Daily updates from Odoo
Monday, June 22, 2026
52 changes · saas-19.1
Security fixes and vulnerability patches
This update strengthens Odoo's security by ensuring users only have read access to data, preventing potential issues and maintaining data integrity. The change focuses on the core Odoo database structure, addressing a vulnerability that could lead to unexpected behavior. This update is a standard security fix.
Original PR description
Ensure that the user has read access to prevent any unexpected behavior. Task-6226863 Forward-Port-Of: odoo/odoo#267709
New functionality added to Odoo
This update adds support for several popular food delivery services – including Talabna, Mandoob, and DiDi Food – expanding Odoo's reach to new markets and catering to a wider range of customer preferences. The update also backports existing delivery provider integrations, ensuring continued functionality.
Original PR description
In this commit: - We are introducing new delivery providers like Talabna, Mandoob, Snoonu, DiDi Food and Zyada for different countries and backporting Radyes, ToYou, The Chefz, InstaShop and Smiles. Task-6263289,6263272,6263203,6263165,6310690 Forward-Port-Of: odoo/enterprise#119537
Enhancements to existing features
This update clarifies the process for adding handwritten signatures within the HTML editor. The wording has been changed from 'Insert your signature from Sign' to 'Insert your handwritten signature' for better user understanding and a more natural workflow. This improves the overall user experience.
Original PR description
Purpose of this PR: - Replace 'Insert your signature from Sign' with 'Insert your handwritten signature'. task-6217718 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update enhances the timesheet assistant by providing clearer guidance when the Odoo Timesheet Assistant (AW) isn't properly set up, offering helpful warnings if the extension is missing, and displaying more relevant suggestions for time tracking. It also improves the accuracy of time entries by resolving record names and prioritizing recent timesheeted projects.
This update improves the payment process by adding debtor and creditor information to the data sent to Odoofin, which is required for using Powens and Saltedge payment gateways. This change ensures smoother and more complete payment initiation workflows.
Original PR description
In order to be able to initiate payments using Powens and Saltedge, we need to include debtor information in the payload sent to Odoofin. This commit adds the necessary fields and updates the tests accordingly. Task ID: 5977148, 6095729 Forward-Port-Of: odoo/enterprise#119843
Resolved issues and error corrections
This update resolves an issue where loading demo data for the `l10n_in` module failed when installed without pre-existing demo data. The fix ensures that company IDs are correctly converted into the required format, allowing users to successfully load demo data from the Settings menu. This improves the user experience and ensures consistent demo data setup.
Original PR description
## Description When loading demo data from **Settings** after installing `l10n_in` without demo data, the `_install_demo` method receives company IDs instead of a `res.company` recordset. As a…
## Description When loading demo data from **Settings** after installing `l10n_in` without demo data, the `_install_demo` method receives company IDs instead of a `res.company` recordset. As a result, the following line crashes: ```python companies.filtered(...) ``` with: ```text AttributeError: 'int' object has no attribute 'filtered' ``` This PR ensures that the received company IDs are converted into a `res.company` recordset before being processed, allowing demo data to be loaded successfully from the Settings menu. ## Steps to Reproduce 1. Install `l10n_in` **without demo data**. 2. Navigate to **Settings**. 3. Click **Load Demo Data**. ## Current Behavior Demo data installation fails with: ```text AttributeError: 'int' object has no attribute 'filtered' ``` ## Expected Behavior Demo data should be installed successfully without raising any exception. ## Solution Convert the received company IDs into a `res.company` recordset when the argument passed to `_install_demo` is not already a recordset.
This update resolves an issue where mass email campaigns were inadvertently using users' personal email servers, causing delays and errors. The changes now ensure that personal servers are excluded from the selection process for mass mailings, preventing campaigns from getting stuck and improving reliability. This ensures consistent email sending functionality.
Original PR description
A personal outgoing mail server is an `ir.mail_server` that belongs to one user. The system only lets that user send through it. Mass mailings do not always respect this, which can cause a few…
A personal outgoing mail server is an `ir.mail_server` that belongs to one user. The system only lets that user send through it. Mass mailings do not always respect this, which can cause a few problems: 1. Admins cannot duplicate a personal server. The copy keeps the same owner, and the rule that says one user can own only one server stops the save. 2. In *Email Marketing > Settings*, the "Dedicated Server" picker offers every server, even personal ones. If an admin picks a personal one, all campaigns get stuck. The cron job runs as Odoobot, the personal server rejects it, and the mailing stays in the queue. 3. When no dedicated server is set, the fallback selection can still land on a personal server (for example because its `from_filter` matches the sender). The cron sends through it and gets rejected. One commit per problem: 1. **mail**: duplicating a personal server now produces a copy with no owner. 2. **mass_mailing**: the picker in the settings hides personal servers. Setting an owner on a server that is already used for mass mailing now raises a clear error that names the campaign blocking the change. 3. **mass_mailing**: personal servers are skipped when the fallback selection runs, so only shared servers are considered. opw-6086077 Forward-Port-Of: odoo/odoo#261537
This update significantly speeds up appointment scheduling, particularly when managing multiple resources like tables in a restaurant. The change streamlines the process of checking resource availability, reducing load times by up to 70% for complex scenarios. This results in a faster and more responsive user experience.
Original PR description
In the current code, for each slot, and for each "available" resource, we check if the resource is available on the slot, based on availability values. Then, we check the remaining capacity of that…
In the current code, for each slot, and for each "available" resource, we check if the resource is available on the slot, based on availability values. Then, we check the remaining capacity of that resource. Also, linked resources information is added when computing the original resource remaining capacity. If many linked resources exist, this will be done several times and is not useful. This commit makes that loop disappear. We now check all resources at once in terms of availability, and linked resources that could be selected (in the appointment resources, in the slot resources (if any restricted resource)) at the same time. Then, the total capacity is the sum of the resource remaining capacity and the ones of available linked resources. Therefore, _slot_availability_is_resource_available is renamed to _slot_available_resources, as it now takes more than one resource and returns all resources among 'resources' that are valid on the slot, based on the availability_values, slot restrictions and booking lines. A noticeable difference is mainly seen when using many resources (and linked resources). For instance, a restaurant with a lot of small tables will have their slot availability check much shorter. BENCHMARK, LOCAL (time only, as number of requests does not change) Only appointment installed For a restaurant with - 10 tables of 2 - 5 tables of 2 linked, 2 times - 10 tables of 4 - 2 table of 2 - time then auto assign On loading /appointment/id: ~ 3.1s -> ~ 1.6s On selecting any number of people (1 to 10): [2s, 2.5s] -> [0.6s, 0.8s] Task-4144524 Forward-Port-Of: odoo/enterprise#107711
This update resolves an issue where appointment invitations weren't always sent correctly. The change ensures invitations are only sent when an appointment is in the 'booked' or 'request' status, preventing unnecessary emails and improving efficiency. This was originally identified and addressed in a related enterprise PR.
Original PR description
This PR adapts the code to fix the invitations at the appointments' update. See the enterprise PR to get more information about the issues. Enterprise PR: https://github.com/odoo/enterprise/pull/114304 Task-6139036 Forward-Port-Of: odoo/odoo#260073
This update ensures appointment invitations are only sent when an appointment is actually booked or requested, resolving previous issues where invitations were incorrectly triggered. It now correctly sends invitations to new attendees of booked appointments and ensures the correct status changes are logged, improving the reliability of appointment scheduling notifications.
Original PR description
This PR fix three issues related to the sending of the appointment invitations. Each one has its own commit: - Commit 1 sends invitations only if the event either "booked" or "request". Previously they were sent even if the appointment was cancelled. - Commit 2 prevents the sending of regular invitations and always sends appointment invitation to new attendees of existing booked appointments. - Commit 3 sent appointment invitations if the status of an existing event is set "request". It also add the status change in the log as it would have been if it was done at the creation. Community PR: https://github.com/odoo/odoo/pull/260073 Task-6139036 Forward-Port-Of: odoo/enterprise#114304
This update resolves an error that prevented users from sorting tasks by their planned dates within the project management portal. The fix ensures that the system correctly retrieves sort order information, preventing a 'KeyError' and improving the user experience. This change ensures reliable task sorting functionality.
Original PR description
Currently, an error occurs when a user sorts tasks by Planned Date. **Steps to reproduce:** - Install the `project_enterprise` module with demo data. - Go to Projects in the portal (`/my/projects`),…
Currently, an error occurs when a user sorts tasks by Planned Date. **Steps to reproduce:** - Install the `project_enterprise` module with demo data. - Go to Projects in the portal (`/my/projects`), open any `project`, and sort the tasks by `Planned Date`. KeyError: 'order' After a [recent change], the sort order is retrieved from searchbar sortings. When sorting by Planned Date, it attempts to access the order key from the corresponding sorting configuration [1]. However, the planned_date_begin entry does not define an order key [2], which raises error when it tries to access order. This commit ensures that the order key is added with its value for planned_date_begin in searchbar sorting. [recent change]: https://github.com/odoo/odoo/commit/8be5dacf9fbfe8c23b04c876994bea2ce7cbb89a [1]: https://github.com/odoo/odoo/blob/2ae9b57b86cd0bc4816ff8ec207564631baa8ad6/addons/project/controllers/portal.py#L424 [2]- https://github.com/odoo/enterprise/blob/9dd3a9b2c09a6d23a3f71d3e531edd6d78b30277/project_enterprise/controllers/portal.py#L8-L11 sentry-7556050938
This update resolves an error that occurred when users attempted to send SMS messages to website visitors. The fix updated the system to correctly access visitor phone numbers, ensuring the SMS functionality works as intended. This prevents a disruption in lead generation and communication.
Original PR description
Currently, an error occurs when a user tries to send an sms to a visitor. **Steps to Reproduce:** - Install `website_crm_sms` without demo data. - Go to `Website` > `Edit`, drag and drop another…
Currently, an error occurs when a user tries to send an sms to a visitor. **Steps to Reproduce:** - Install `website_crm_sms` without demo data. - Go to `Website` > `Edit`, drag and drop another `Form` block. - Configure the form action to `Create an Opportunity` and `save`. - Fill in the required fields, including phone number and `Submit` the form. - Go to `Website` > `Reporting` > `Visitors` and click the `SMS` button on the visitor record. `AttributeError: 'website.visitor' object has no attribute 'phone'` After [this commit], which removed the mobile field from res.partner along with all related views, then it was updated to access the phone number from the website visitor. When a user creates an opportunity through the website and then tries to send an sms from the corresponding visitor record, it raises an error [1] because it attempts to access the phone field on website.visitor. when an anonymous (non-logged-in) user creates an opportunity, clicking the sms button on the corresponding visitor record triggers error here [2]. This commit ensures that the correct mobile field is accessed from the website visitor. [this commit]: https://github.com/odoo/odoo/commit/6b820eb6fc6f782ba6a83d605d87b4a1dd2a87be [1]- https://github.com/odoo/odoo/blob/6a0e6443951053f8361e97f42e5e45c32bb73656/addons/website_crm_sms/models/website_visitor.py#L13 [2]- https://github.com/odoo/odoo/blob/6a0e6443951053f8361e97f42e5e45c32bb73656/addons/website_crm_sms/models/website_visitor.py#L20 sentry-7550340909 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270118
This update corrects a technical issue where the UBL BIS3 format for Debit Notes was not fully compliant with the BIS3 standard. Specifically, the system was incorrectly using 'LegalMonetaryTotal' instead of the required 'RequestedMonetaryTotal' node. This change ensures accurate UBL BIS3 generation for Debit Notes, improving data consistency and compliance.
Original PR description
Problem --------- Debit note should have the node `RequestedMonetaryTotal` instead of `LegalMonetaryTotal`. Solution --------- Add a conditional depending on the document type. opw-6295897 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270238
This update resolves an issue where milestone deadline dates would disappear from task views after navigating back or refreshing. The fix ensures that milestone deadlines are consistently displayed in task kanban views and task form views, regardless of user navigation.
Original PR description
Steps to reproduce: 1. Open the Project application and open any project. 2. Filter the tasks by milestone (milestone deadlines appear as expected in the kanban view). 3. Open any task form view. 4.…
Steps to reproduce: 1. Open the Project application and open any project. 2. Filter the tasks by milestone (milestone deadlines appear as expected in the kanban view). 3. Open any task form view. 4. Click the browser's back button (or simply refresh the page while on the task kanban view). Issue: Milestone deadline dates disappear from the task Kanban cards and headers after navigating back or reloading. Why this happens: When hitting the browser back button or refreshing, the web client's router state recovery workflow executes (`loadRouterState` -> `loadState` -> `doAction` -> `_executeActWindowAction`). During this flow, `_getActionParams` checks if it can reuse the cached `lastAction`. However, due to a safety condition introduced in commit ab26f95893 to prevent embedded action showing across different projects, the router falls back to generating a fresh action request via `state.action`. This forces `_loadAction` to fetch the action definition from the database. Because the original base action window `act_project_project_2_project_task_all` lacks the `display_milestone_deadline` key inside its default context dictionary, the reloaded view is rendered without the flags required by the frontend to display milestone deadlines. opw-6283514 Forward-Port-Of: odoo/odoo#269781
This update corrects a visual issue in the Data Recycle app where grouping records resulted in incorrect record counts and truncated group names. The fix removes the unnecessary display of summed record IDs, improving the clarity and accuracy of grouped lists.
Original PR description
## Issue In the *Data Recycle* app, when grouping records, the record IDs are summed up and appear right next to the name of each group, which: 1. truncates the name and count of the groups 2. does…
## Issue
In the *Data Recycle* app, when grouping records, the record IDs are summed up and appear right next to the name of each group, which:
1. truncates the name and count of the groups
2. does not make sense (summing up IDs is pointless)
<img width="720" height="281" alt="115492" src="https://github.com/user-attachments/assets/567902af-b356-4a0a-8b1e-2ed101a2eba3" />
## Steps to reproduce
1. Install *Data Recycle* (`data_recycle`)
2. In Data Cleaning > Configuration > Recycle Records, create a new rule:
- Any name
- Model: *Contact*
- Filter: *Name contains G* (or anything else that matches some records)
4. Click the *Run Now* button in the upper left corner
5. In Data Cleaning > Recyle Records, group the records by any field (e.g., *Model*)
6. **The name of the group (Contact) is truncated, making it and the record count unreadable. This is due to the sum of Record ID being displayed in the same row, even though that information is irrelevant.**
## Cause
Similarly to related enterprise PR https://github.com/odoo/enterprise/pull/115492, the *Record ID* field of the `data_recycle.record` model uses the default `sum` aggregator.
https://github.com/odoo/odoo/blob/6de867f1c92bacedc0574b63e9e6a2a57fe805dd/addons/data_recycle/models/data_recycle_record.py#L17
related: https://github.com/odoo/enterprise/pull/115492
opw-6219824
Forward-Port-Of: odoo/odoo#265163This update resolves an issue in the Data Cleaning app where grouping records resulted in the display of summed record IDs alongside group names, causing truncation and inaccurate counts. The fix removes the default 'sum' aggregator applied to integer fields, preventing this misleading display and ensuring accurate group counts.
Original PR description
## Issue In the *Data Cleaning* app, when grouping records, the record IDs are summed up and appear right next to the name of each group, which: 1. truncates the name and count of the groups 2. does…
## Issue
In the *Data Cleaning* app, when grouping records, the record IDs are summed up and appear right next to the name of each group, which:
1. truncates the name and count of the groups
2. does not make sense (summing up IDs is pointless)
<img width="709" height="374" alt="6166623-before" src="https://github.com/user-attachments/assets/9d80b1ec-49c0-4b7f-8c6e-53846f9e433e" />
## Steps to reproduce
1. Install *Data Cleaning* (`data_cleaning`)
2. In Data Cleaning > Configuration > Field Cleaning, create a new rule (or edit an existing one):
- Any name
- Model: *Contact*
- Rule:
- Field to Clean: *Name (Contact)*
- Action: *Set Type Case* - Case: *All Uppercase*
4. Click the *Clean* button in the upper left corner
5. In Data Cleaning > Field Cleaning, group the records by any field (e.g., *Field*)
6. **The name of the group (_Name (Contact)_) is truncated, making it and the record count unreadable. This is due to the sum of _Record ID_ being displayed in the same row, even though that information is irrelevant.**
## Cause
The *Record ID* (`res_id`) field is an Integer field defined [here](https://github.com/odoo/enterprise/blob/3603afdd5c0d19c9276f3855156be4040ab5717d/data_cleaning/models/data_cleaning_record.py#L20). By default, Integer fields have the `sum` aggregator:
https://github.com/odoo/odoo/blob/681610c002a310f1c73fc2e5bec8d3dae27bc4a7/odoo/orm/fields_numeric.py#L17-L23
This causes the IDs to be summed up and appear in the group headers.
## After
<img width="740" height="370" alt="6166623-after" src="https://github.com/user-attachments/assets/a42d8f58-06dc-4308-8b6f-1ab09e8034f8" />
related: https://github.com/odoo/odoo/pull/265163
opw-6166623
Forward-Port-Of: odoo/enterprise#115492This update fixes an issue where product costs weren't correctly converted to the POS currency. Previously, product costs were stored in separate currencies, leading to potential inaccuracies in pricing. This change ensures all product costs are accurately converted, improving the reliability of sales data in the Point of Sale system.
Original PR description
When loading products in the POS, both the sale price and the cost were converted to the POS currency using `currency_id`. However a product stores its sale price and its cost in two potentially different currencies: `currency_id` (company currency, falling back to the main company) and `cost_currency_id` (company currency, falling back to the current company). opw-6297452 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269829
This update prevents a traceback error that occurred when clicking the 'envelope' icon in the chatter, specifically during event registrations or follower additions. The issue stemmed from a missing `res_partner_id` field, which caused a conflict in notification filtering. This fix ensures the notification popover functions correctly regardless of whether a partner ID is present.
Original PR description
# How to reproduce - Create an Event registration - Add a follower - Click on the enveloppe icon next to the sender's name in the chatter # The problem A traceback appears # Cause of the issue When…
# How to reproduce - Create an Event registration - Add a follower - Click on the enveloppe icon next to the sender's name in the chatter # The problem A traceback appears # Cause of the issue When clicking on the enveloppe, we display the `message_notification_popover` that calls `isFollowerNotification` to filter follower notifications from other ones. This function compares the ids of the followers of the notification to it's res_partner_id : https://github.com/odoo/odoo/blob/ee12a62407fa1c2dbca00d77dc6d5bd16eac1e43/addons/mail/static/src/core/common/notification_model.js#L101-L105 But in our case res_partner_id is undefined because it is not a required field and it will not be set in the case of mass_mailing : https://github.com/odoo/odoo/blob/ee12a62407fa1c2dbca00d77dc6d5bd16eac1e43/addons/mail/models/mail_notification.py#L23-L27 opw-6178443 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265263
This update corrects a recent change that was incorrectly returning all active documents during searches. The fix ensures that searches for user root documents only return valid results, excluding those marked as 'trash'. This improves search accuracy and data integrity.
Original PR description
We went a bit too fast with df353d76 and transformed search `'in', '[]'` from Domain.FALSE to all active documents. All active documents should only be returned when searching for all valid user roots (i.e., not TRASH). We're here partially reverting referenced commit and applying the closest code minimizing diff for foward ports. Task-5893183
This update fixes an issue where the Luxembourg eCDF XML export incorrectly reported financial year data. The change removes a problematic account mapping, ensuring the data aligns with the Odoo Profit & Loss view. This ensures accurate reporting for Luxembourg tax compliance.
Original PR description
Issue: Users reported that the financial year result in the XML export for the Luxembourg eCDF platform is incorrect, despite being correct in the Odoo Profit and Loss visualization. The exported XML populated incorrect amounts in cell 0161 under certain circumstances (namely, in the case of an explicit entry from account 999999 to account 142000). Solution: * Removed account 142 entirely from both the `ACCOUNTS_2019` and `ACCOUNTS_2020` dictionaries so it no longer auto-populates cells 0161/0162 (up to 2019 included) and 2955/2956 (from 2020 onward). * Removed the 2019 threshold condition in the loop bypass for account 142. * Removed the hard-coded manual pop for cell 2955 since it has been removed from the mapping. * Deleted the redundant reassignment of `net142` in the loss calculation block. Ticket [link](https://www.odoo.com/odoo/project.task/6059571) opw-6059571 Forward-Port-Of: odoo/enterprise#121010
This update resolves a problem where the PDP identifier field in the company registration process was left blank when using non-0225 PEPPOL EAS. A new error message is now displayed to guide users to enter a valid identifier, preventing silent failures and ensuring accurate registration. This improves the reliability of the PDP proxy setup.
Original PR description
Currently when the company partner uses non 0225 peppol EAS the `pdp_identifier` field is `False`. Thus the (related) identifier field on the registration wizard is left empty. Also add a UserError when writing an invalid identifier to the `pdp_identifier` field instead of just silently failing. That way an error ill pop up in the registration wizard when trying to register with an invalid identifier. task-6307489 Forward-Port-Of: odoo/odoo#270915 Forward-Port-Of: odoo/odoo#270330
This update ensures that attachments related to incoming invoices from EDI imports (specifically for Italian businesses) are correctly handled. Previously, detaching these attachments caused issues with bulk XML exports. Now, attachments for Italian invoices are preserved to ensure accurate data transfer and compliance with tax regulations.
Original PR description
The feature introduced in odoo/enterprise#78429 allows users to detach attachments from moves, primarily to facilitate the regeneration and re-sending of outgoing XMLs (e.g., sales invoices) without needing to delete the original attachment. However, detaching should not apply to incoming XML attachments on bills that originate from EDI import, as these attachments are the received source document and are never regenerated by the system. Detaching them inadvertently prevents their inclusion in bulk XML exports. An exception exists for Italy: businesses need to send Tax Integration XMLs back to the SdI. In this specific case, detaching the Tax Integration XML is appropriate and ensures the bulk export finds the latest, correct attachment. Ticket [link](https://www.odoo.com/odoo/project.task/5062132) opw-5062132 Forward-Port-Of: odoo/odoo#267892 Forward-Port-Of: odoo/odoo#239701
This update corrects a requirement in the Danish Nemhandel invoicing format, specifically within the AllowanceCharge node. The change adds a necessary TaxCategory node to ensure compliance with UBL standards, resolving a previously identified issue. This ensures accurate invoice processing for Nemhandel customers.
Original PR description
Add the TaxCategory node in AllowanceCharge node as it's a requirement for some UBL format. It has been spoted with Nemhandel, as it requires a single tax category in the AllowanceCharge. no-task Forward-Port-Of: odoo/odoo#270351
This update prevents errors in e-Waybill requests when the dispatch and delivery locations share the same pin code. Previously, the system couldn't automatically calculate the distance in these cases, leading to incomplete requests. Now, a distance must be provided, ensuring accurate e-Waybill generation and avoiding server issues.
Original PR description
Prevent sending incomplete e-Waybill requests to the GSP server when the dispatch and delivery pincodes are identical. In such cases, the distance cannot be automatically determined and must be provided explicitly. This commit adds a validation to ensure a distance is set before generating the e-Waybill, avoiding incomplete requests and subsequent server-side errors. task-6234343 Forward-Port-Of: odoo/odoo#270495 Forward-Port-Of: odoo/odoo#268497
This update fixes a potential issue where the standard price for products could be incorrectly calculated due to how user access restrictions were handled. The change ensures that standard price updates account for all available inventory, regardless of user permissions, preventing inaccurate pricing. This improves the reliability of product valuation.
Original PR description
`qty_available` is by default not computed with sudo, while the `total_value` is. This means that in `_update_standard_price`, the customer configuration can have a negative impact on the…
`qty_available` is by default not computed with sudo, while the `total_value` is. This means that in `_update_standard_price`, the customer configuration can have a negative impact on the standard_price compute.
For example, if a user create a custom rule so that specific users have access to specific warehouses only, compute `total_value / qty_available` can actually mean `global_total_value / partial_qty_available`, which creates an aberrant standard price.
To fix this issue, the _update_standard_price must be done in sudo.
OPW-6243363
---
## Test result without fix
```
2026-06-17 12:24:50,810 47572 ERROR oes_test_19 odoo.addons.stock_account.tests.test_stockvaluation: FAIL: TestStockValuation.test_update_standard_price_with_limited_access_users
Traceback (most recent call last):
File "/home/odoo/Odoo/src/19.0/odoo/addons/stock_account/tests/test_stockvaluation.py", line 3624, in test_update_standard_price_with_limited_access_users
self.assertEqual(product.standard_price, 1.0)
AssertionError: 12.11111111111111 != 1.0
```
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#270559This update resolves an error that occurred when syncing AvaTax exemption codes. The issue stemmed from a mismatch in how AvaTax represented 'all countries' values, causing a crash during synchronization. This fix ensures correct data handling and successful exemption code synchronization.
Original PR description
Steps to reproduce: - Create a US company - Go to Accounting > Configuration > Settings - Activate `Avatax` > Set Credentials - Try to "Sync Parameters" Traceback: ```py File…
Steps to reproduce:
- Create a US company
- Go to Accounting > Configuration > Settings
- Activate `Avatax` > Set Credentials
- Try to "Sync Parameters"
Traceback:
```py
File "/home/odoo/src/enterprise/saas-19.2/account_avatax/models/res_company.py", line 113, in avatax_sync_company_params
'valid_country_ids': [(6, 0, get_countries(vals['validCountries']).ids)],
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/enterprise/saas-19.2/account_avatax/models/res_company.py", line 90, in get_countries
return self.env['res.country'].browse([country_cache[code] for code in code_list])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.2/odoo/orm/models.py", line 5208, in browse
assert all(ids) or all(isinstance(x, NewId) or x for x in ids), "Invalid falsy real id"
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: Invalid falsy real id
```
The issue occurs because AvaTax return `*` in the `validCountries` field to indicate that an exemption code is valid for all countries. The synchronization logic stores this value in the country cache as `False` and later passes it to `res.country.browse()`. Since `browse()` does not accept a mix of valid IDs and falsy values, the operation crashes during the synchronization process.
This commit filter out falsy country IDs when resolving country codes to prevent crashes and allow exemption codes to be synchronized successfully.
opw-6298189The Odoo team has partially reverted a recent code update due to unexpected changes introduced by Weblate. This ensures the translation updates made during the Weblate integration are preserved while correcting the unwanted code modifications. This resolves a technical issue impacting multiple modules.
Original PR description
For some reason Weblate reverted some code changes apart from the translations updates it did. We partially revert the commit here to fix the code, but keep the translation updates. This partially reverts commit 06c83da5410fd3869af0d9c3edddf9cc1a7d7c55.
This update fixes an issue where DIAN XML invoices were being rejected due to incorrect calculations of prepaid payments. The fix combines payment amounts into a single tag, ensuring accurate totals and preventing the creation of negative payment lines, which were causing API errors.
Original PR description
**Steps to reproduce:** To test this, you will need an official DIAN setup, because this error comes from the response to our API call to the DIAN. - Setup the DIAN in a colombian company - Open the…
**Steps to reproduce:** To test this, you will need an official DIAN setup, because this error comes from the response to our API call to the DIAN. - Setup the DIAN in a colombian company - Open the PoS - Order a product - Before paying, make the amount we are paying bigger than the amount due - We get an error response from the API, the error is saying that the total due does not match what we paid **Why the fix:** Currently, the xml is rejected because the sum of the **PaidAmount** in the **PrepaidPayment** tag is not equal to what we are trying to pay for. This is happening because to avoid the fact that we can not send a line with negative amount, we used the **abs()** function on the line amount to make it positive. The negative line comes from the fact that when we have a total due that is below the amount paid, we create a new payment line with a negative amount to balance it out. But as we can't send lines with negative amount, we needed to make it positive. This does not work, as the sum of the lines' amount will then be too much compared to what we are paying for, because instead of substracting it we will be adding it. To avoid this, we now group the amount in one single tag and send it this way. This ensures that the sent amount is correct and equals the amount due, and does not send a negative line. opw-6232575 Forward-Port-Of: odoo/enterprise#121075 Forward-Port-Of: odoo/enterprise#119255
This update resolves an issue where invoices with reverse charge tax in Poland (fa3) were generating incorrect XML files for ksef transmission. Specifically, the XML lacked the necessary information to accurately reflect the reverse charge amount and total sale value. This fix ensures proper tax reporting and compliance.
Original PR description
**STEP TO REPRODUCE** 1. Create an invoice with a tax with reverse charge (0% EU G for example). 2. Send the invoice to ksef. 3. Open the generated xml, and notice field P_18 is 2 while it should be 1 (because there is reverse charge). Also, there is not P13_10 indicated the total value of sale to which the reverse charge applies. opw-6041836 Forward-Port-Of: odoo/odoo#263764
This update resolves an issue where users couldn't link bank statement lines to child contacts when using the 'Set Partner' button. The fix aligns the system's logic to correctly recognize and select child contacts, ensuring accurate bank statement reconciliation. This improves the usability of the bank reconciliation process.
Original PR description
When creating a bank statement line, we can not set an individual contact that is a children of a company contact. However, when clicking on the 'Set Partner' button, all contacts are shown in the modal list view. This commit aligns the domain coming from the 'Set Partner' button with the domain from the 'partner_id' field of the auto reconcile wizard Steps: - Have a contact X, with a child contact Y - Create and confirm an invoice for contact Y, amount 1000 - Create a bank statement line for 1000 -> You can not select Y, only X - Click 'Add & Close' - Click on 'Set Partner' button -> Y is displayed opw-6205154 Forward-Port-Of: odoo/enterprise#118036
This update resolves an issue where sign templates with auto-filled fields would incorrectly display placeholders instead of the actual values, or fail to generate documents. The fix ensures falsy values from auto-fields are properly handled, preventing errors and guaranteeing accurate sign document generation.
Original PR description
Version: - 19.0 Steps to reproduce: - Create a sign template with a readonly sign item linked to an auto field. - Use a reference record where the linked field value is empty or False. - Send the…
Version: - 19.0 Steps to reproduce: - Create a sign template with a readonly sign item linked to an auto field. - Use a reference record where the linked field value is empty or False. - Send the document for signing. - Complete the signing flow. Issue: - Readonly sign items linked to auto-filled values could not properly handle falsy values. Empty values could trigger the error "Some required items are not filled" and completed sign requests displayed the sign item placeholder instead of the actual auto-filled value. - completed document generation could fail when rendering falsy values for textarea sign items. Cause: - Falsy auto-filled values were ignored during constant item population and replaced by the sign item placeholder. Additionally, readonly constant items were included in required field validation and completed sign requests continued to display placeholders when the stored value was empty. - document rendering assumed sign item values were always strings for textarea sign items but when auto field is empty it value can be False. Fix: - Preserve falsy values when populating readonly constant items, exclude constant items from signer validation, and hide placeholders for empty auto-filled constant items when displaying completed sign requests. - Normalize falsy values to prevent crashes and allow completed documents to be generated correctly. Forward-Port-Of: odoo/enterprise#121009
This update fixes a potential instability issue with dynamic website content snippets. The change ensures callbacks are properly protected during re-renders, preventing unexpected behavior and test failures. This improves the reliability of the website experience.
Original PR description
Commit dcb070244dbcef59cae1e3b1e87ce9030608ce0d changed the registration of callback for re-render of dynamic snippet on window resize. But did not ensure the callback is "protected", like it was implicitely done with `t-on-` in `dynamicContent`. This commit uses `protectSyncAfterAsync` to register the callback, so that is it protected when called again. This lack of "protection" is suspected to cause a non-deterministic failure in `test_shop_editor_no_alternative_products_visibility` where mutations of dom are observed at unexpected times. runbot-939193 Forward-Port-Of: odoo/odoo#271011
This update fixes an issue where the withholding tax return incorrectly combined balances with the regular tax return. The change ensures the withholding tax return accurately calculates the independent balance due, resolving a discrepancy in Italian tax reporting. This improves the accuracy of financial reporting for Italian businesses.
Original PR description
Steps to reproduce: - setup an Italian company - make an invoice (for example in May) with a withholding tax and make a transaction to pay it - generate tax returns (opening date in June so that it generates from May) - validate regular tax return for May - validate withholding tax return for May -> The withholding tax return shows an amount to pay with a balance that is a combination of both the regular tax return and the withholding one, while it should be independent of the regular one. task-6116304 Forward-Port-Of: odoo/enterprise#119375
This update corrects a bug where custom styling of text input fields within Odoo wasn't working correctly. The previous version ignored styling instructions passed from the user. Now, styling options are properly applied, ensuring consistent and customizable text input appearances.
Original PR description
BuilderTextInput's template hardcoded `inputClasses` to 'o-hb-input-text', dropping any `inputClasses` prop passed by callers. As a result, options trying to style their text input had no effect. Introduced in 0aba7f383c86dec00e9fc6d324a5bfdec7a19707. Concatenate caller-supplied `inputClasses` with the default `o-hb-input-text`. Forward-Port-Of: odoo/odoo#265156
This update fixes a bug in the Preparation Time report for Point of Sale, ensuring that preparation durations are displayed correctly based on the user's current timezone. Previously, the report always used the timezone of the OdooBot, leading to inaccurate data. This change improves reporting accuracy and provides a more reliable view of preparation times.
Original PR description
In POS, the Preparation Time report groups average preparation durations by hour. Those hour buckets were always computed with the timezone of the user who ran the module upgrade (OdooBot /…
In POS, the Preparation Time report groups average preparation durations by hour. Those hour buckets were always computed with the timezone of the user who ran the module upgrade (OdooBot / superuser), not the timezone of the user viewing the report. Changing the user, company, or browser timezone had no effect on the graph until the module was upgraded again. Steps to reproduce: ------------------- * Configure a Preparation Display and create POS orders with measured preparation times. * Open Point of Sale → Reporting → Preparation Time. * Note the hour bucket used for the orders. * Change your user timezone in Preferences and reload the report. > Observation: The hour buckets stay the same. Before the fix, they only changed after upgrading `pos_enterprise`, because the timezone was embedded in the SQL view created during `init()` as superuser. Why the fix: ------------ Replace the static PostgreSQL view with a dynamic `_table_query` so `order_hour` is computed with the current user's timezone on each report read. `init()` now only drops the legacy view instead of recreating it with a frozen timezone. opw-6220248 Forward-Port-Of: odoo/enterprise#118365
This fix resolves an issue where extra prices were incorrectly added to combos when using 'always' attribute types. The update ensures that extra prices are now set on the combo creation page, aligning with the intended behavior for product variants. This improves the accuracy of point-of-sale pricing.
Original PR description
## Steps to reproduce - Create an attribute A, of type always, with 2 values, one should have an extra price - Create an attribute B, of type never, with 2 values - Create a product that has both…
## Steps to reproduce - Create an attribute A, of type always, with 2 values, one should have an extra price - Create an attribute B, of type never, with 2 values - Create a product that has both those attributes - Create a combo with that product with both values for A - Go to the PoS and order that combo with the value that has an extra price for A - The extra price is added ## Why the fix: For variants of type always, a product is created, meaning we can chose which products of this variants to have in our combo. As we can chose this, it means that we can and should chose the extra price on the combo creation page, not on the attribute page. It does not make sense to take the attribute extra price into account, as we do not take the unit price of combo items into account, so this extra price should be set on the combo page and we should ignore the attribute's extra price if the type is "always". The variants are then considered as different products, as they should in this case. If the type of the attribute is never, we can't chose which one gets an extra price on the combo page, so we should still take the attribute's extra price in this situation, as we have no other way to set it. We need to have both an always and a never attribute in order to reproduce this bug because if we only have "always" values, the configuration of the combo item is bypassed and is undefined, so **attribute_value_ids** will be undefined in this code and we won't get any value for the extra price in this code: https://github.com/odoo/odoo/blob/c09e8b2fc24ee75495fc947924e29cf5c601506f/addons/point_of_sale/static/src/app/models/utils/compute_combo_items.js#L44-L49 We now ignore the attribute's extra price if it's type is always, otherwise, it the behavior stays the same. opw-6262431 Forward-Port-Of: odoo/odoo#270625 Forward-Port-Of: odoo/odoo#268567
This update resolves an issue where the system incorrectly forecasted expiring perishable products, leading to unnecessary purchase orders. The fix ensures that forecasts accurately reflect product availability and prevents the scheduler from continuously generating purchase orders for items nearing expiration. This improves inventory accuracy and reduces operational waste.
Original PR description
Currently when the user receives a perishable product that expires in future, it is considered for reordering regardless if the user has maximum quantity or not. ## Steps to produce: - Install…
Currently when the user receives a perishable product that expires in future, it is considered for reordering regardless if the user has maximum quantity or not. ## Steps to produce: - Install Inventory - Go to settings > Enable 'Lots and Serial Numbers' and 'Expiration Dates' - Create a product 'Vegetable Oil' that is tracked by lots. - Enable Expiration date in the 'Inventory' Section and set Removal date to 2. - Create a receipt for 'Vegetable oil' with Demand 10 and mark it as todo - Details > Set 'Expiration Date' into the future > Set a Lot Number and Save - Validate the receipt - Open Product Form for Vegetable oil > Reordering Rules. - Create a new Reordering rule with Min 5 and Max 10 and save. ## Observed Behavior: The forecasted quantity is calculated as zero, resulting in a quantity to order of 10, even though no replenishment is actually required. The product already satisfies the maximum quantity defined on the reordering rule, and there is no existing demand, as there are no delivery orders or sales order reservations for the product. **Why this is an issue:** When the user navigates from the product form to the On Hand Quantity view to verify the stock situation, the forecasted quantity is shown as 10. This is inconsistent with the value displayed on the reordering rule, creating confusion and making it difficult to understand the actual inventory status. In addition, if the product is configured with a Buy route, running the `Procurement: Run Scheduler` action repeatedly generates new purchase orders for the perishable product. Even if the generated purchase orders are cancelled or completed, since newly purchased stock will also have an expiration date. As a result, the same incorrect forecast calculation occurs again, causing the scheduler to continuously create new purchase orders and leading to an endless replenishment cycle if they expire within horizon days. ## Root cause: When an orderpoint is created or updated, `_compute_qty_to_order` [1] is triggered. This method calls `_compute_qty_to_order_computed` [2] which accesses the forecasted quantity, causing its compute method to called. The forecast computation retrieves context from `_get_product_context` as seen in [3], where the lead horizon date (route lead time + horizon days configured in settings) is passed as `to_date` at [4]. It then reads the product's `virtual_available` quantity using the orderpoint context at [5]. This ultimately invokes `_compute_quantities`, which delegates the calculation of `virtual_available` to `_compute_quantities_dict`, as shown in [6]. As a result, `max_date` is set to the lead horizon date at [7] (for example, one year in the future). Since the product expires before that date, it is included in `expired_unreserved_quant_res`, causing `virtual_available` to be reduced to zero at [8]. Consequently, the forecasted quantity also becomes zero at [9]. Because the forecasted quantity falls below the orderpoint's minimum quantity, a replenishment is incorrectly triggered. **Why did this issue not occur in previous versions?** This behavior was introduced by [commit](https://github.com/odoo/odoo/commit/8ba2c1e38b636c567511139c5e19b7189430a182 ), which fixed the calculation of fresh(unexpired) quantity displayed in the stock availability widget on sales order lines. Which expects that `scheduled_date` (typically the committed delivery date or expected delivery date, including leadtime) is passed to `read_qties` at [10] , which stores it in the context using the `to_date` key. However, the same `to_date` key is also used by the orderpoint horizon-days logic. This overlap causes the expiration-aware quantity computation to use the horizon date instead of the intended `with_expiration` date , leading to incorrect forecast calculations and the unexpected replenishment behavior described above. [1]- https://github.com/odoo/odoo/blob/9ae1df190cf5ee6a5775eddb32be7b13f5ed92c9/addons/stock/models/stock_orderpoint.py#L394-L396 [2]-https://github.com/odoo/odoo/blob/96b7eed9153eab60288d1624252df6f90ea9505e/addons/stock/models/stock_orderpoint.py#L417-L427 [3]- https://github.com/odoo/odoo/blob/96b7eed9153eab60288d1624252df6f90ea9505e/addons/stock/models/stock_orderpoint.py#L374-L381 [4]- https://github.com/odoo/odoo/blob/9ae1df190cf5ee6a5775eddb32be7b13f5ed92c9/addons/stock/models/stock_orderpoint.py#L484-L491 [5]- https://github.com/odoo/odoo/blob/96b7eed9153eab60288d1624252df6f90ea9505e/addons/stock/models/stock_orderpoint.py#L386 [6]- https://github.com/odoo/odoo/blob/9ae1df190cf5ee6a5775eddb32be7b13f5ed92c9/addons/stock/models/product.py#L152-L154 [7]- https://github.com/odoo/odoo/blob/9ae1df190cf5ee6a5775eddb32be7b13f5ed92c9/addons/stock/models/product.py#L215-L218 [8]- https://github.com/odoo/odoo/blob/9ae1df190cf5ee6a5775eddb32be7b13f5ed92c9/addons/stock/models/product.py#L260-L262 [9]- https://github.com/odoo/odoo/blob/9ae1df190cf5ee6a5775eddb32be7b13f5ed92c9/addons/stock/models/stock_orderpoint.py#L391 [10]- https://github.com/odoo/odoo/blob/afa2b6b7b47d6420146ceb6dad897405aa92c682/addons/sale_stock/models/sale_order_line.py#L129 ## Solution It does not make sense to trigger replenishment for perishable products solely because they are expected to expire before the horizon date. Even when the available quantity already satisfies the maximum quantity defined on the reordering rule, the current logic forecasts those products as unavailable in advance of their expiration. Instead, products should only be excluded from the forecast once they have actually expired, or when they must be removed according to the original expiration-handling logic. To achieve this, an additional context key can be introduced to distinguish calls originating from the forecast availability widget from SO line. When the computation is performed for the forecast widget, the existing `to_date` context key should continue to be used so that availability is evaluated at the requested future date. For all other flows, including orderpoint calculations, the system should rely on the `with_expiration` context key instead. This preserves the original behavior, where only already-expired quantities (or quantities that must be removed due to expiration rules) are excluded from availability calculations, preventing incorrect replenishment recommendations for perishable products. opw-6200644 Forward-Port-Of: odoo/odoo#268223
This update fixes an issue where the number of comments on course slides wasn't accurately displayed. Previously, the system incorrectly counted messages due to changes in how the portal chatter system works. This change ensures the comment counts now reflect the actual number of active comments, improving the user experience.
Original PR description
Steps to reproduce: - Open a slide of a course in non fullscreen mode (website). - Go to the comments tab and add a comment in the chatter. - The comments count does not change in the tab. - The same thing happens when a comment is deleted. - Another way to see the incorrect counter is to add a note in the slide form view (backend). Before this change, `website_slides` used `website_message_ids` to calculate the comments. Since #138233 the old portal chatter has been replaced with the mail chatter and the way messages are displayed on the portal has changed. For example notes are no longer considered portal messages and also deleted messages should not be displayed or counted as such. This change ensures that comments calculations are based on a domain that considers those changes meaning that comments will be synced with the actual number of available comments. Forward-Port-Of: odoo/odoo#270800 Forward-Port-Of: odoo/odoo#260376
This update simplifies the process of applying Early Payment Discounts (EPD) to refund transactions. Previously, a technical issue prevented correct mapping of tax repartition lines, now fixed by ensuring the system correctly identifies invoice and refund types. This enhancement improves the reliability of EPD calculations for refunds.
Original PR description
This commit does not bring native support for EPD on credit notes, only makes custom support a little easier and cleaner. It is quite easy to support EPD (early payment discounts) on refunds by…
This commit does not bring native support for EPD on credit notes, only makes custom support a little easier and cleaner. It is quite easy to support EPD (early payment discounts) on refunds by extending - `_early_payment_discount_move_types` - `_is_eligible_for_early_payment_discount` However, this approach breaks when it reaches `inverse_tax_rep` in `_get_invoice_counterpart_amls_for_early_payment_discount_per_payment_term_line`, which assumes tax repartition lines with `document_type == 'invoice'` and raises when called on `tax_rep` lines of 'refund' type instead. This commit fixes that by selecting source and target repartition lines according to the `tax_rep`'s document type, which ensures: - the `.index()` no longer raises a `ValueError`, as `tax_rep` is now looked up in the matching set (`refund_` for refunds, `invoice_` otherwise) - `inverse_tax_rep` returns the corresponding line in the opposite set, preserving the original invoice->refund mapping while adding the refund->invoice one Since `inverse_tax_rep` is a closure, downstream modules cannot patch it without copying the whole ~170-line method. Making it symmetric here lets custom EPD-on-refund support work without that duplication. task-[6265601](https://www.odoo.com/odoo/all-tasks/6265601) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#271102
This update resolves a bug that previously caused errors when address fields were missing in payment authorization requests. Now, missing address fields are automatically set to empty strings, ensuring the system functions correctly and avoids disruptions to payment processing. This improves the reliability of the payment authorization module.
Original PR description
Fix bug introduced by commit https://github.com/odoo/odoo/pull/267592/changes/c4556637e8eeef07ce6e3cc3b3b4cf28fa10e468 that caused an error if an address field was not set, due to trying to cut a False field. Now, unset fields are set to empty strings. Forward-Port-Of: odoo/odoo#270295
This update fixes a bug in the stock valuation calculation that was incorrectly displaying product values. The fix ensures that values are accurately converted to the main company's currency (USD) when multiple companies and currencies are involved, resulting in correct stock valuation reports. This improves the accuracy of financial reporting across all company setups.
Original PR description
**Steps to reproduce:** - make sure your main company (company 1) has dollars as its main currency - create second company (company 2) and a warehouse in this second company - set euro has the main…
**Steps to reproduce:** - make sure your main company (company 1) has dollars as its main currency - create second company (company 2) and a warehouse in this second company - set euro has the main currency in the company 2 From company 1: - set an exchange rate of 1$ = 0.5 eur on the euro currency - create a storable product with a cost of 10$ and an on-hand quantity of 1 From company 2: - set the cost to 10 eur and set an on-hand quantity of 1 with both company selected and company 1 as the main company selected: - open the stock view and look for your product **Current behavior:** the total value is 20$ **Expected behavior:** with conversion rate, it should be 30$ **Cause of the issue:** when computing the total value we do not apply a conversion rate from the value of the company to the main company selected https://github.com/odoo/odoo/blob/8759429547e42e9f63b15a7c80475be46ef437e2/addons/stock_account/models/product.py#L273 opw-6280108 Forward-Port-Of: odoo/odoo#270575
This update fixes an issue where the table of contents would obscure headings when the status bar was sticky. The change ensures headings remain visible by intelligently accounting for sticky elements during scrolling within the table of contents, improving usability.
Original PR description
Since [1] when the `o_form_statusbar` status bar was made `sticky` the table of content scrolls to a given heading without taking it into account. Because of this, when scrolling upwards the heading ends up behind the status bar. This commit fixes this by finding top-aligned sticky elements within the closest scrollable element impacted by the table of content. Steps to reproduce: - Go to a To do note - Define some headings - Have sufficient content so that reaching a heading requires scrolling - Define a table of content with `/toc` - Click on a heading => The heading ended up behind the status bar. [1]: https://github.com/odoo/odoo/commit/a3c63413825cf3492a10ade77a2c571c4eeb33a6 task-6302762 Forward-Port-Of: odoo/odoo#270043
This update fixes an issue where the sandwich rule incorrectly excluded public holidays from leave calculations. Now, when 'Include Public Holidays as Working Day' is enabled, the system accurately determines leave duration, including weekend days that fall on holidays. A new test case ensures this fix functions as expected.
Original PR description
Problem: When a time off type is configured with "Include Public Holidays as Working Day", the sandwich rule was still treating public holidays as non-working days. This caused the sandwiched weekend days to not be included in the leave duration. Example: Employee applies leave from May 15 (Friday, Public Holiday) to May 18 (Monday). Expected duration is 4 days since May 15 is a working day and May 16-17 (weekend) should be sandwiched. Instead, only 1 day was calculated. Fix: Now when "Include Public Holidays as Working Day" is enabled, the correct number of days are calculated in the sandwich rule. Also added a test case to verify that public holidays are correctly treated as working days during sandwich rule evaluation. Task-4570118 Forward-Port-Of: odoo/odoo#270254 Forward-Port-Of: odoo/odoo#266624
This update resolves an issue related to how Odoo handles direct debit mandates for SEPA accounts. The change adds a constraint to ensure that direct debits are only processed through the correct partner bank, improving data accuracy and reducing potential errors. This enhances the reliability of our SEPA direct debit functionality.
Original PR description
Forward-Port-Of: odoo/enterprise#121023 Forward-Port-Of: odoo/enterprise#120901
This update resolves a bug where overtime was incorrectly generated when using Timing type rules with employer tolerances. The fix ensures that attendance limits are accurately considered during overtime calculations, preventing unnecessary overtime charges. This improves the accuracy of employee time tracking.
Original PR description
**Version:** - 19.0 **Steps to reproduce:** - Create a rule of Timing type. - Add a tolerance for the employer. - Set the ruleset on the employee. - Add an attendance of less than the tolerance. **Issue:** - When using a Timing type rule with employer tolerance, overtime is still created even if the attendance is below the tolerance limit. **Cause:** - The timing rule calculation was missing the tolerance check that exists in the quantity rule calculation. **Fix:** - Added the missing tolerance check in the timing rule calculation. - Removed employee tolerance from view for timing rules. **Task-6064081** Forward-Port-Of: odoo/odoo#257079
This update significantly reduces the memory used when loading large General Ledgers, primarily by optimizing how display names are retrieved. Previously, the system loaded excessive data, leading to slow performance. Now, a single fetch call ensures only the necessary display name information is loaded, resulting in a substantial performance boost.
Original PR description
### Issue Loading a large General Ledger (e.g., during an "Unfold All" action) and retrieving display names for thousands of journal lines (`account.move.line`) causes excessive memory and…
### Issue Loading a large General Ledger (e.g., during an "Unfold All" action) and retrieving display names for thousands of journal lines (`account.move.line`) causes excessive memory and performance overhead. Profiling with `memray` showed that one of the main memory hotspots was located in `custom_label_builder`. **Previous behavior:** Accessing `record.display_name` in a loop without an explicit `fetch()` call triggered lazy computation of the field via `_compute_display_name()`. When the compute method accessed stored dependency fields (such as `name`, `ref`, `move_id`), each cache miss went through `_fetch_field()`, which greedily loaded **all fields sharing the same prefetch group** on the model, far beyond the dependencies of `display_name` alone. This caused the ORM cache to be filled with many unnecessary stored fields for every record in the prefetch set. --- ### Dataset Volume The performance metrics were captured using a dataset consisting of: * **455,694** Journal Items (`account.move.line`) * **19,947** Journal Entries (`account.move`) --- ### Solution Add a single `fetch(['display_name'])` call on the browsed recordset. By calling `fetch(['display_name'])` upfront, the ORM goes through `_determine_fields_to_fetch(['display_name'])`, which walks only the declared `field_depends` of `display_name` and fetches **only those specific stored fields**. nothing more. --- ### Impact & Results | Metric | Before Optimization | After Optimization | Change / Note | | :--- | :--- | :--- | :--- | | **Peak Memory** | ~856 MB | ~223 MB | ~74% reduction | | **Execution Time** | 2.48s | 2.13s | About the same time with multiple tries | OPW-6275158 Forward-Port-Of: odoo/enterprise#121020
This update fixes an issue where invoices for returned dropshipped products incorrectly displayed both lots (lot1 and lot2) instead of just the returned lot (lot2). The fix ensures that the invoice accurately reflects the returned quantity, resolving a potential discrepancy in inventory tracking and reporting.
Original PR description
**Issue** Printing an invoice for a returned dropshipped tracked product could display the wrong lot/serial number on the invoice report. **Steps to reproduce** - Activate "Display Lots & Serial…
**Issue**
Printing an invoice for a returned dropshipped tracked product could display the wrong lot/serial number on the invoice report.
**Steps to reproduce**
- Activate "Display Lots & Serial Numbers on Invoices"
- Create a product tracked by serial/lot and enable the dropship route
- Create two lots: "lot1" and "lot2"
- Create and confirm a SO for quantity 2
- Confirm the PO and validate the dropship for both lots
- Create and post an invoice
- Return "lot2" from the dropship picking
- Create and post a credit note for quantity 1
- Click on print on the invoice
-> The generated PDF displays "lot1 & lot2" instead of "lot1"
**Cause**
While rendering `account.report_invoice_with_payments`, the report calls `_get_invoiced_lot_values` to determine which lot/serial numbers should be displayed:
https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L31-L32 `invoiced_qties = 2` since the invoice is on a quantity of 2 https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L44 Three stock move lines are retrieved from the SO:
- the two original dropship deliveries,
- the return move for `lot2`. https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L63 However, none of them are considered as `is_stock_return` because the dropship locations use `supplier` instead of `internal`: https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L72-L76 As a consequence:
- The two original delivery move lines each keep quantity `1`: https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L69 they never pass through the return handling logic (as they should be): https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L77-L80
- for the last one, `is_stock_return = False` while it should not, thus the quantity is 1 instead of 0. Furthermore, it does not pass by this code:
https://github.com/odoo/odoo/blob/8759429547e42e9f63b15a7c80475be46ef437e2/addons/sale_stock/models/account_move.py#L79 which would make the quantity for lot2 equalled to 0 (1-1) The quantities are therefore accumulated as:
https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L92
resulting in:
`qties_per_lot = {lot1: 1, lot2: 2}`
instead of:
`qties_per_lot = {lot1: 1, lot2: 0}`
The report selects both lots since it starts with lot1 (qty of 1): https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/sale_stock/models/account_move.py#L94-L99
opw-6236855
Forward-Port-Of: odoo/odoo#270599This update prevents users from changing the status of checks when they lack the necessary permissions. Previously, users without access to the main company of a tax unit would encounter errors. Now, the status change button is disabled, ensuring data integrity and preventing incorrect status updates.
Original PR description
Before this commit: Only main company of tax unit have write access on check, so when main company is not selected and user tries to change status of check, access error is thrown. After this commit: Disable check status button if user don't have write access on check. task-5951364 ENT PR: https://github.com/odoo/enterprise/pull/121353
A recent issue prevented users from creating WhatsApp event templates, resulting in an 'access denied' error. This fix restricts the creation of new WhatsApp templates, ensuring users can only manage existing ones. This resolves a bug impacting event communication workflows.
Original PR description
Issue: 1) User goes to Event.event Form -> communication tab -> add line 2) Select whatsapp -> type something -> create and edit -> create new template with any model event.registration -> save ( all the way including the event form) 3) reload page -> whatsapp event.mail displays "User does not have access to this record". Fix: add "'no_create_edit': True" to the associated field in the xml to block creation of new mail.templates opw-6037488 Forward-Port-Of: odoo/odoo#268641 Forward-Port-Of: odoo/odoo#259683
This update fixes an issue where the spreadsheet filter dropdown remained open even when the selected filter value didn't change. The change ensures the dropdown automatically closes after a filter selection, providing a more consistent and user-friendly experience. This improves usability and reduces confusion for users.
Original PR description
Current behavior before PR: - In b4d5d1f, added early return when filter value is unchanged. - However, the dropdown was not closed in this case, leaving it open after clicking the filter button, resulting in inconsistent and unexpected UX. Desired behavior after PR is merged: - Ensure the dropdown is closed even when the filter value remains unchanged, restoring consistent and expected behavior. Task: [6304213](https://www.odoo.com/odoo/project/2328/tasks/6304213) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270225
This update fixes an issue where product pricing in the Point of Sale (PoS) system was incorrectly calculating VAT and total prices. The fix ensures that prices accurately reflect the applied pricelist and fiscal position mappings, resulting in correct tax calculations and total amounts.
Original PR description
Steps to reproduce: ------------------- 1. Create a product with a tax (e.g. 15%). 2. Create a pricelist that changes the price (e.g. 100 to 200). 3. Create a fiscal position mapping the tax (e.g.…
Steps to reproduce: ------------------- 1. Create a product with a tax (e.g. 15%). 2. Create a pricelist that changes the price (e.g. 100 to 200). 3. Create a fiscal position mapping the tax (e.g. 15% to 30%). 4. Add the pricelist and the fiscal position in PoS. 5. Add the product to the cart, and select the tax and the pricelist created in the previous steps. 6. Long press on the product to see its info. The price should be 200 now after selecting the pricelist. Also the tax should be 30% bc of the FP mapping, i.e. total price should be 200 + 30% = 260. However, we observe that VAT shows 15 (15%) instead of 60 (30%), and Price incl. Tax shows 230 instead of 260. What's happening: ----------------- On the frontend, `getTaxDetails()` is called with no options, so it uses the product `list_price` (100) and `taxes_id` (15%), giving VAT = 15. Alos, on the backned, `self.taxes_id` is used directly to compute the taxes, even though the pricelist price is correct (200), fiscal position is ignored, hence 200 + 15% = 230 instead of 200 + 30% = 260. The fix: -------- On frontend, we pass the pricelist and fiscal position to `getTaxDetails`, and compute the tax name from the mapped taxes. On the backend, we read the `fiscal_position_id` from the context and apply the tax mapping, so the correct taxes are used. opw-6200632 Forward-Port-Of: odoo/odoo#266012
Documentation and clarification updates
This pull request formally records Adrien Didot's (Adridot) signature on the Odoo Individual Contributor License Agreement. Adding the associated documentation ensures compliance with Odoo's licensing terms. This update supports Adrien Didot's contribution to the Odoo project.
Original PR description
Individual Contributor License Agreement signature. Adds `doc/cla/individual/adridot.md` per the CLA signing instructions. Related contribution: #270196 Forward-Port-Of: odoo/odoo#270411 Forward-Port-Of: odoo/odoo#270197