Daily updates from Odoo
Saturday, August 8, 2026
50 changes
8 changes
Resolved issues and error corrections
Payroll warning information is now consistently visible in payslip and pay run list views instead of appearing as an unnamed optional column. This improves clarity for payroll users and prevents confusing empty entries in the column selection menu.
Original PR description
Currently, in the payslip and payrun view, we can see empty label in optional dropdown. Having empty label isn't UX friendly. This empty label is refered to payslip warnings. In this PR expected to change visibility of warning fields, The visibility must be always visible and the field is no longer optional. This condition applies to PayRun and Paylist ListViews. task-6424657 Forward-Port-Of: odoo/enterprise#127224 Forward-Port-Of: odoo/enterprise#125860
The exchange rate update link for the Romanian National Bank has been changed to the new official domain. This prevents future disruption to automatic currency rate updates after the old address stops serving XML files.
Original PR description
As of 6 August 2026, the XML files used by software applications to retrieve daily exchange rates will no longer be available directly through addresses on the www.bnr.ro domain and will be accessible exclusively via the curs.bnr.ro subdomain. The XML file names will remain unchanged; only the access domain will be modified. no-task Forward-Port-Of: odoo/enterprise#127177
This update fixes a Swiss payroll transmission issue where a required value was not being recorded in the payroll logs. This helps payroll teams keep more complete records for compliance checks and troubleshooting.
Original PR description
Forward-Port-Of: odoo/enterprise#127241
`_selection_target_model()` searched all records of ir_model and due to some prefetch issues, multiple queries ran depending on the number of models in db. By using search_fetch we eliminate this. Partial backport of odoo/odoo#281215 Forward-Port-Of: odoo/odoo#281229
Original PR description
`_selection_target_model()` searched all records of ir_model and due to some prefetch issues, multiple queries ran depending on the number of models in db. By using search_fetch we eliminate this. Partial backport of odoo/odoo#281215 Forward-Port-Of: odoo/odoo#281229
Before this commit, the unread badge of the Chat action could stay empty after a click on "Mark as Unread" in the meeting view: FAILED: [17/24] Tour discuss.meeting_view_public_tour Step .o-mail-Meeting [title='Chat']:has(.badge:contains(1)) This happens because a mark as read and a mark as unread write the same fields of the channel member in two requests, and the server applies them in the order it receives them, not the order they are sent. Under CI load, a mark as read sent be
Original PR description
Before this commit, the unread badge of the Chat action could stay empty after a click on "Mark as Unread" in the meeting view:
FAILED: [17/24] Tour discuss.meeting_view_public_tour
Step .o-mail-Meeting [title='Chat']:has(.badge:contains(1))
This happens because a mark as read and a mark as unread write the same fields of the channel member in two requests, and the server applies them in the order it receives them, not the order they are sent. Under CI load, a mark as read sent before the click reached the server after the mark as unread, marking the member read again and hiding the badge through its bus push.
This commit requests the mark as unread through the queue of the mark
as read, which sends one request at a time.
This also drops the check the mark as read made against a mark as unread requested in between, as the queue keeps only the last request and replaces the waiting one.
https://runbot.odoo.com/odoo/error/944432
Forward-Port-Of: odoo/odoo#280946Steps to reproduce ------------------ 1. Install `l10n_pe_pos`. 2. Create a contact with the identification type DNI and a number. 3. Sell a product to this contact and print the receipt. -> the receipt shows "RUC" in front of the number, even though the number is a DNI and not a RUC. Why it's happening ------------------ Since `aeaca097ae39` the number of the contact is printed with a label in front of it, before there was no label at all. This label is the `vat_label` of the country,
Original PR description
Steps to reproduce ------------------ 1. Install `l10n_pe_pos`. 2. Create a contact with the identification type DNI and a number. 3. Sell a product to this contact and print the receipt. -> the…
Steps to reproduce ------------------ 1. Install `l10n_pe_pos`. 2. Create a contact with the identification type DNI and a number. 3. Sell a product to this contact and print the receipt. -> the receipt shows "RUC" in front of the number, even though the number is a DNI and not a RUC. Why it's happening ------------------ Since `aeaca097ae39` the number of the contact is printed with a label in front of it, before there was no label at all. This label is the `vat_label` of the country, so "RUC" for Peru. But in Peru each contact can have a different identifier, and the type is on the contact in `l10n_latam_identification_type_id`. The fix ------- In `l10n_pe_pos` we set `partner_vat_label` with the name of the identification type of the contact. If the contact has no identification type we keep the number alone. Before vs After for a customer identified with DNI ------------------------------------------------- <img width="465" height="203" alt="Capture d’écran 2026-07-30 à 14 45 17" src="https://github.com/user-attachments/assets/85c921df-c1fd-430b-b4e6-341bc183bd61" /> <img width="467" height="253" alt="Capture d’écran 2026-07-30 à 14 49 36" src="https://github.com/user-attachments/assets/3ac243c6-04fe-47a4-a662-c59b88276db7" /> opw-6422619 Forward-Port-Of: odoo/odoo#279409
Otherwise using the "Update Apps List" wizard (`base.action_view_base_module_update`) and then trying to `_get` the new module may not work because `_get_id` is `ormcache`ed. To reproduce: 1. Install `account_peppol` and `l10n_fr` 2. Delete the `l10n_fr_pdp` module from the apps 3. Go to the settings and click "Activate Electronic Invoicing" 4. Make sure "France FRCTC Electronic Address" is selected 5. Click on "Activate Peppol (Demo)" 6. Click on "Update App List" in the warning 7. Cl
Original PR description
Otherwise using the "Update Apps List" wizard (`base.action_view_base_module_update`) and then trying to `_get` the new module may not work because `_get_id` is `ormcache`ed. To reproduce: 1. Install `account_peppol` and `l10n_fr` 2. Delete the `l10n_fr_pdp` module from the apps 3. Go to the settings and click "Activate Electronic Invoicing" 4. Make sure "France FRCTC Electronic Address" is selected 5. Click on "Activate Peppol (Demo)" 6. Click on "Update App List" in the warning 7. Click on "Update" 8. Start over at step 3. and the same warning appears again, but the module can be found in the "Apps" already. Everything works fine after a server restart. task-None Forward-Port-Of: odoo/odoo#281299 Forward-Port-Of: odoo/odoo#280938
### Issue before this commit: When generating ZUGFeRD or Factur-X electronic invoices, including an HTML hyperlink (such as an email or website) in the document layout caused the final PDF to fail PDF/A validation. Portals would reject the file with the error: "An annotation dictionary does not contain the key F". ### Steps to reproduce the issue: 1. Download Accounting and l10n_de 2. Go to Contacts > set Tax ID for company Bloem GmbH and also for DE company 3. Activate ZUGFeRD from setti
Original PR description
### Issue before this commit: When generating ZUGFeRD or Factur-X electronic invoices, including an HTML hyperlink (such as an email or website) in the document layout caused the final PDF to fail…
### Issue before this commit: When generating ZUGFeRD or Factur-X electronic invoices, including an HTML hyperlink (such as an email or website) in the document layout caused the final PDF to fail PDF/A validation. Portals would reject the file with the error: "An annotation dictionary does not contain the key F". ### Steps to reproduce the issue: 1. Download Accounting and l10n_de 2. Go to Contacts > set Tax ID for company Bloem GmbH and also for DE company 3. Activate ZUGFeRD from settings 4. Go to settings and click on Configure Document Layout and insert something like <a href="mailto:info@company.de_skr03example.com"> info@company.de_skr03example.com</a> into the footer 5. Create an invoice to Bloem GmbH and send it through ZUGFeRD 6. Download PDF and upload it on https://www.portinvoice.com/ 7. See error: An annotation dictionary does not contain the key F. With the exception of annotation dictionaries whose subtype value is Popup, all annotation dictionaries must contain the key F. ### Cause of the issue: The underlying PDF generation engine creates hyperlinks as PDF annotations but omits the /F (Flags) key. During Odoo's PDF/A conversion process, these annotations were left unmodified. This violates the strict PDF/A specification, which mandates that all non-Popup annotations must explicitly define the /F key. ### Reason to introduce the fix: This fix ensures full PDF/A compliance by iterating through all page annotations and injecting the missing /F key for any annotation that is not a Popup. This allows users to safely include clickable links in their invoice templates without breaking electronic document validation. opw-6388212 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#281275 Forward-Port-Of: odoo/odoo#279024
6 changes
Resolved issues and error corrections
The Romanian National Bank exchange rate feed now uses the new official domain required from August 2026. This keeps automatic currency rate updates working without interruption for companies relying on Romanian exchange rates.
Original PR description
As of 6 August 2026, the XML files used by software applications to retrieve daily exchange rates will no longer be available directly through addresses on the www.bnr.ro domain and will be accessible exclusively via the curs.bnr.ro subdomain. The XML file names will remain unchanged; only the access domain will be modified. no-task Forward-Port-Of: odoo/enterprise#127177
`_selection_target_model()` searched all records of ir_model and due to some prefetch issues, multiple queries ran depending on the number of models in db. By using search_fetch we eliminate this. Partial backport of odoo/odoo#281215 Forward-Port-Of: odoo/odoo#281229
Original PR description
`_selection_target_model()` searched all records of ir_model and due to some prefetch issues, multiple queries ran depending on the number of models in db. By using search_fetch we eliminate this. Partial backport of odoo/odoo#281215 Forward-Port-Of: odoo/odoo#281229
Before this commit, the unread badge of the Chat action could stay empty after a click on "Mark as Unread" in the meeting view: FAILED: [17/24] Tour discuss.meeting_view_public_tour Step .o-mail-Meeting [title='Chat']:has(.badge:contains(1)) This happens because a mark as read and a mark as unread write the same fields of the channel member in two requests, and the server applies them in the order it receives them, not the order they are sent. Under CI load, a mark as read sent be
Original PR description
Before this commit, the unread badge of the Chat action could stay empty after a click on "Mark as Unread" in the meeting view:
FAILED: [17/24] Tour discuss.meeting_view_public_tour
Step .o-mail-Meeting [title='Chat']:has(.badge:contains(1))
This happens because a mark as read and a mark as unread write the same fields of the channel member in two requests, and the server applies them in the order it receives them, not the order they are sent. Under CI load, a mark as read sent before the click reached the server after the mark as unread, marking the member read again and hiding the badge through its bus push.
This commit requests the mark as unread through the queue of the mark
as read, which sends one request at a time.
This also drops the check the mark as read made against a mark as unread requested in between, as the queue keeps only the last request and replaces the waiting one.
https://runbot.odoo.com/odoo/error/944432
Forward-Port-Of: odoo/odoo#280946Steps to reproduce ------------------ 1. Install `l10n_pe_pos`. 2. Create a contact with the identification type DNI and a number. 3. Sell a product to this contact and print the receipt. -> the receipt shows "RUC" in front of the number, even though the number is a DNI and not a RUC. Why it's happening ------------------ Since `aeaca097ae39` the number of the contact is printed with a label in front of it, before there was no label at all. This label is the `vat_label` of the country,
Original PR description
Steps to reproduce ------------------ 1. Install `l10n_pe_pos`. 2. Create a contact with the identification type DNI and a number. 3. Sell a product to this contact and print the receipt. -> the…
Steps to reproduce ------------------ 1. Install `l10n_pe_pos`. 2. Create a contact with the identification type DNI and a number. 3. Sell a product to this contact and print the receipt. -> the receipt shows "RUC" in front of the number, even though the number is a DNI and not a RUC. Why it's happening ------------------ Since `aeaca097ae39` the number of the contact is printed with a label in front of it, before there was no label at all. This label is the `vat_label` of the country, so "RUC" for Peru. But in Peru each contact can have a different identifier, and the type is on the contact in `l10n_latam_identification_type_id`. The fix ------- In `l10n_pe_pos` we set `partner_vat_label` with the name of the identification type of the contact. If the contact has no identification type we keep the number alone. Before vs After for a customer identified with DNI ------------------------------------------------- <img width="465" height="203" alt="Capture d’écran 2026-07-30 à 14 45 17" src="https://github.com/user-attachments/assets/85c921df-c1fd-430b-b4e6-341bc183bd61" /> <img width="467" height="253" alt="Capture d’écran 2026-07-30 à 14 49 36" src="https://github.com/user-attachments/assets/3ac243c6-04fe-47a4-a662-c59b88276db7" /> opw-6422619 Forward-Port-Of: odoo/odoo#279409
Otherwise using the "Update Apps List" wizard (`base.action_view_base_module_update`) and then trying to `_get` the new module may not work because `_get_id` is `ormcache`ed. To reproduce: 1. Install `account_peppol` and `l10n_fr` 2. Delete the `l10n_fr_pdp` module from the apps 3. Go to the settings and click "Activate Electronic Invoicing" 4. Make sure "France FRCTC Electronic Address" is selected 5. Click on "Activate Peppol (Demo)" 6. Click on "Update App List" in the warning 7. Cl
Original PR description
Otherwise using the "Update Apps List" wizard (`base.action_view_base_module_update`) and then trying to `_get` the new module may not work because `_get_id` is `ormcache`ed. To reproduce: 1. Install `account_peppol` and `l10n_fr` 2. Delete the `l10n_fr_pdp` module from the apps 3. Go to the settings and click "Activate Electronic Invoicing" 4. Make sure "France FRCTC Electronic Address" is selected 5. Click on "Activate Peppol (Demo)" 6. Click on "Update App List" in the warning 7. Click on "Update" 8. Start over at step 3. and the same warning appears again, but the module can be found in the "Apps" already. Everything works fine after a server restart. task-None Forward-Port-Of: odoo/odoo#281299 Forward-Port-Of: odoo/odoo#280938
You'll need two users : - Internal User A that can create projects - User B with a granted portal access Optionnal third user to compare the flows : - Internal User B that can create tasks in a porject - With User A, create a new project with atleast a single stage - Go to the project settings - Make sure that Visibility is set to : "All internal users and invited portal users" - Click on Share Project - Add User B as a new Collaborator with the Edit acess mode - Confirm by clic
Original PR description
You'll need two users : - Internal User A that can create projects - User B with a granted portal access Optionnal third user to compare the flows : - Internal User B that can create tasks in a…
You'll need two users : - Internal User A that can create projects - User B with a granted portal access Optionnal third user to compare the flows : - Internal User B that can create tasks in a porject - With User A, create a new project with atleast a single stage - Go to the project settings - Make sure that Visibility is set to : "All internal users and invited portal users" - Click on Share Project - Add User B as a new Collaborator with the Edit acess mode - Confirm by clicking on Share Project - Still in the project settings, click on the blue user icon in the top right to edit the Followers : - Make sure you are following the project - Click on the edit button and make sure Task Created is checked Optionnal for easiness of testing : - Go to the User A settings and in Preferences > Notifications : In Odoo - Log in with User B (in a new incognito tab on the side is best) - Go to Projects > The project that has been shared - Create a new task No notification is sent to User A. If the same flow is done using User C, then a notification is correctly sent. The fields that determine to which users the notifications are sent to is `message_follower_ids`. In our case, the value of that field does not contain User A, so no notifcation is sent to them. The method responsible for assigning values to that field is `_message_auto_subscribe()` which adds follower using subtypes parent relationship. The parent subtype of tasks are projects. So, essentially, we look for followers of the parent project, and see if we can add them to our task. Before proceeding with the assignation, we check that the parent subtype's field was actually edited : https://github.com/odoo/odoo/blob/ea18f34a48d61350f80c79894bef66bf02840bfc/addons/mail/models/mail_thread.py#L4778-L4781 So we look that `updated_values` contains "project_id". `updated_values` is created by the the `mail_thread` create method by joining the values in `vals_list` and the context default variables. In our case, this should be enough since `default_project_id` is provided when creating a task : https://github.com/odoo/odoo/blob/ea18f34a48d61350f80c79894bef66bf02840bfc/addons/mail/models/mail_thread.py#L340-L344 But, a bit before this, the task create method edits the context to replace 'default_project_id' by 'default_create_in_project_id' : https://github.com/odoo/odoo/blob/ea18f34a48d61350f80c79894bef66bf02840bfc/addons/project/models/project_task.py#L1102-L1109 So we do not detect that `project_id` has been changed and don't actually add the followers. We remove the custom 'default_create_in_project_id` context opw-6026932 Forward-Port-Of: odoo/odoo#278824 Forward-Port-Of: odoo/odoo#278353
11 changes
Enhancements to existing features
Receipt printer selection now uses the same broader matching rules as preparation printers. This helps point-of-sale setups find compatible IoT printers more consistently and reduces configuration friction.
Original PR description
In odoo/enterprise#124306, we removed the subtype from the printer domain, but only for preparation printers. We also update it for receipt printers. Forward-Port-Of: odoo/enterprise#127142 Forward-Port-Of: odoo/enterprise#125648
Resolved issues and error corrections
This fix ensures the Swiss payroll ELM transmission process correctly records the minimum income value in payroll logs. This helps payroll teams and administrators review transmissions more reliably and reduces confusion during checks or audits.
Original PR description
Forward-Port-Of: odoo/enterprise#127241
The live currency rate update has been adjusted to use the Romanian National Bank's new required web address. This helps ensure daily exchange rates continue to update automatically after the old address stops working in August 2026.
Original PR description
As of 6 August 2026, the XML files used by software applications to retrieve daily exchange rates will no longer be available directly through addresses on the www.bnr.ro domain and will be accessible exclusively via the curs.bnr.ro subdomain. The XML file names will remain unchanged; only the access domain will be modified. no-task Forward-Port-Of: odoo/enterprise#127177
The test `editing s_popup, then closing it, then undo show it again` had a few fails in CI: the `fa-eye` was not set as expected. This commit adds a `waitSidebarUpdated` call just before to ensure owl has no pending rendering when checking the eye. runbot-242292 Forward-Port-Of: odoo/odoo#263490
Original PR description
The test `editing s_popup, then closing it, then undo show it again` had a few fails in CI: the `fa-eye` was not set as expected. This commit adds a `waitSidebarUpdated` call just before to ensure owl has no pending rendering when checking the eye. runbot-242292 Forward-Port-Of: odoo/odoo#263490
Currently, people can get infinite loop in the cron that fetches messages from the ppf, as we don't catch the exception that may happen. At least catch them, so we can send an ack opw-6440955 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#281170
Original PR description
Currently, people can get infinite loop in the cron that fetches messages from the ppf, as we don't catch the exception that may happen. At least catch them, so we can send an ack opw-6440955 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#281170
### Issue before this commit: When generating ZUGFeRD or Factur-X electronic invoices, including an HTML hyperlink (such as an email or website) in the document layout caused the final PDF to fail PDF/A validation. Portals would reject the file with the error: "An annotation dictionary does not contain the key F". ### Steps to reproduce the issue: 1. Download Accounting and l10n_de 2. Go to Contacts > set Tax ID for company Bloem GmbH and also for DE company 3. Activate ZUGFeRD from setti
Original PR description
### Issue before this commit: When generating ZUGFeRD or Factur-X electronic invoices, including an HTML hyperlink (such as an email or website) in the document layout caused the final PDF to fail…
### Issue before this commit: When generating ZUGFeRD or Factur-X electronic invoices, including an HTML hyperlink (such as an email or website) in the document layout caused the final PDF to fail PDF/A validation. Portals would reject the file with the error: "An annotation dictionary does not contain the key F". ### Steps to reproduce the issue: 1. Download Accounting and l10n_de 2. Go to Contacts > set Tax ID for company Bloem GmbH and also for DE company 3. Activate ZUGFeRD from settings 4. Go to settings and click on Configure Document Layout and insert something like <a href="mailto:info@company.de_skr03example.com"> info@company.de_skr03example.com</a> into the footer 5. Create an invoice to Bloem GmbH and send it through ZUGFeRD 6. Download PDF and upload it on https://www.portinvoice.com/ 7. See error: An annotation dictionary does not contain the key F. With the exception of annotation dictionaries whose subtype value is Popup, all annotation dictionaries must contain the key F. ### Cause of the issue: The underlying PDF generation engine creates hyperlinks as PDF annotations but omits the /F (Flags) key. During Odoo's PDF/A conversion process, these annotations were left unmodified. This violates the strict PDF/A specification, which mandates that all non-Popup annotations must explicitly define the /F key. ### Reason to introduce the fix: This fix ensures full PDF/A compliance by iterating through all page annotations and injecting the missing /F key for any annotation that is not a Popup. This allows users to safely include clickable links in their invoice templates without breaking electronic document validation. opw-6388212 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#279024
Sometimes the default_state remains in the context from a past action and when the subcontractor fills its components consumptions it will directly modify the quant's quantity. This trigger the automatic rules and generate an unwanted picking opw-6109661 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of:
Original PR description
Sometimes the default_state remains in the context from a past action and when the subcontractor fills its components consumptions it will directly modify the quant's quantity. This trigger the automatic rules and generate an unwanted picking opw-6109661 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280930 Forward-Port-Of: odoo/odoo#280733
**Steps to reproduce:** 1. Install Accounting and l10n_be and switch to the Belgian company 2. In the settings, set the discount account (`708000`) on Customer Invoices under "Default Accounts" and enable analytic accounting 3. Go to [Accounting -> Configuration -> Analytic Accounts] and create 4 new accounts with "Project" plan (i.e 1,2,3,4) 4. Create a new invoice with two lines, each having 2 of the analytic accounts with 50% each. 5. Set the price to 1000 and a 10% discount for each lin
Original PR description
**Steps to reproduce:** 1. Install Accounting and l10n_be and switch to the Belgian company 2. In the settings, set the discount account (`708000`) on Customer Invoices under "Default Accounts" and…
**Steps to reproduce:** 1. Install Accounting and l10n_be and switch to the Belgian company 2. In the settings, set the discount account (`708000`) on Customer Invoices under "Default Accounts" and enable analytic accounting 3. Go to [Accounting -> Configuration -> Analytic Accounts] and create 4 new accounts with "Project" plan (i.e 1,2,3,4) 4. Create a new invoice with two lines, each having 2 of the analytic accounts with 50% each. 5. Set the price to 1000 and a 10% discount for each line then save. 6. Edit the second line and set the discount to 20%. 7. Open the Journal Items tab **Issue:** - When an invoice contains multiple lines with analytic distributions, changing the discount percentage on any line other than the first fails to correctly update the analytic distribution percentages on the corresponding discount journal items. - The analytic account distribution splits the percentage evenly across both accounts event if they are not split 50/50 **Why this happens:** - This occurred because `_compute_discount_allocation_needed` iterated over `self` to populate target changes. When only one line was modified, `self` contains that line only which is correctly updated with the new analytic distribution. Later in the execution in `_sync_dynamic_line`, particularly in https://github.com/odoo/odoo/blob/5a14360705a55f4d91edf39c936d7a5d8573044b/addons/account/models/account_move.py#L2263-L2274 The first line in `computed_needed` is what gets set in res, and subsequent lines only modify the field if it's monetary. So if the second invoice line is the one updated, it will never override the `analytic_distribution` with the updated values, leaving stale values in that field. - The code iterated directly over `line.analytic_distribution` dictionary keys (the account IDs) rather than its `.items()`. This caused it to ignore the individual percentage value splits (e.g. 60/40), accumulating the un-weighted full discount amount to each account ID. https://github.com/odoo/odoo/blob/5a14360705a55f4d91edf39c936d7a5d8573044b/addons/account/models/account_move_line.py#L1044-L1052 **Fix:** - Change the processing loop inside `_compute_discount_allocation_needed` from `self` to `self.move_id.line_ids` to calculate the correct `analytic_distribution` across all records. - Applying the factored weight ratio (`amount * (percentage / 100.0)`) to `distribution_totals` opw-6362084 Forward-Port-Of: odoo/odoo#280302 Forward-Port-Of: odoo/odoo#275070
In _validate_amount(), setting a "Percentage of balance" line to 0 raises "Statement line percentage can't be 0", and setting a "Percentage of statement line" to 0 raises "Balance percentage can't be 0". Align each error message with the amount type being validated. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280399 Forward-Port-Of: odoo/odoo#269393
Original PR description
In _validate_amount(), setting a "Percentage of balance" line to 0 raises "Statement line percentage can't be 0", and setting a "Percentage of statement line" to 0 raises "Balance percentage can't be 0". Align each error message with the amount type being validated. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280399 Forward-Port-Of: odoo/odoo#269393
Otherwise using the "Update Apps List" wizard (`base.action_view_base_module_update`) and then trying to `_get` the new module may not work because `_get_id` is `ormcache`ed. To reproduce: 1. Install `account_peppol` and `l10n_fr` 2. Delete the `l10n_fr_pdp` module from the apps 3. Go to the settings and click "Activate Electronic Invoicing" 4. Make sure "France FRCTC Electronic Address" is selected 5. Click on "Activate Peppol (Demo)" 6. Click on "Update App List" in the warning 7. Cl
Original PR description
Otherwise using the "Update Apps List" wizard (`base.action_view_base_module_update`) and then trying to `_get` the new module may not work because `_get_id` is `ormcache`ed. To reproduce: 1. Install `account_peppol` and `l10n_fr` 2. Delete the `l10n_fr_pdp` module from the apps 3. Go to the settings and click "Activate Electronic Invoicing" 4. Make sure "France FRCTC Electronic Address" is selected 5. Click on "Activate Peppol (Demo)" 6. Click on "Update App List" in the warning 7. Click on "Update" 8. Start over at step 3. and the same warning appears again, but the module can be found in the "Apps" already. Everything works fine after a server restart. task-None Forward-Port-Of: odoo/odoo#281299 Forward-Port-Of: odoo/odoo#280938
Features or functions removed from Odoo
An outdated automated test for structured payment references was removed because the related behavior was intentionally changed in an earlier update. This keeps the accounting test suite aligned with the current, simpler reconciliation setup based on easier matching rules for users.
Original PR description
After merging pr #117256 the behavior for creating auto reconcile models for structured reference is no longer working so the test for checking that behavior should be removed. This was an FP request to use contains instead of regex in auto reconcile model creation because it was too complicated for users. no task id Forward-Port-Of: odoo/enterprise#126635
2 changes
Resolved issues and error corrections
The live currency rate connection for Romania has been updated to use the central bank's new required web address. This helps ensure daily exchange rates continue to update automatically after the old address stops serving these files.
Original PR description
As of 6 August 2026, the XML files used by software applications to retrieve daily exchange rates will no longer be available directly through addresses on the www.bnr.ro domain and will be accessible exclusively via the curs.bnr.ro subdomain. The XML file names will remain unchanged; only the access domain will be modified. no-task Forward-Port-Of: odoo/enterprise#127177
Otherwise using the "Update Apps List" wizard (`base.action_view_base_module_update`) and then trying to `_get` the new module may not work because `_get_id` is `ormcache`ed. To reproduce: 1. Install `account_peppol` and `l10n_fr` 2. Delete the `l10n_fr_pdp` module from the apps 3. Go to the settings and click "Activate Electronic Invoicing" 4. Make sure "France FRCTC Electronic Address" is selected 5. Click on "Activate Peppol (Demo)" 6. Click on "Update App List" in the warning 7. Cl
Original PR description
Otherwise using the "Update Apps List" wizard (`base.action_view_base_module_update`) and then trying to `_get` the new module may not work because `_get_id` is `ormcache`ed. To reproduce: 1. Install `account_peppol` and `l10n_fr` 2. Delete the `l10n_fr_pdp` module from the apps 3. Go to the settings and click "Activate Electronic Invoicing" 4. Make sure "France FRCTC Electronic Address" is selected 5. Click on "Activate Peppol (Demo)" 6. Click on "Update App List" in the warning 7. Click on "Update" 8. Start over at step 3. and the same warning appears again, but the module can be found in the "Apps" already. Everything works fine after a server restart. task-None Forward-Port-Of: odoo/odoo#281299 Forward-Port-Of: odoo/odoo#280938
1 change
Resolved issues and error corrections
The Romanian National Bank exchange rate feed used for automatic currency updates now points to its new official web address. This prevents future update failures when the old address stops serving the files in August 2026.
Original PR description
As of 6 August 2026, the XML files used by software applications to retrieve daily exchange rates will no longer be available directly through addresses on the www.bnr.ro domain and will be accessible exclusively via the curs.bnr.ro subdomain. The XML file names will remain unchanged; only the access domain will be modified. no-task Forward-Port-Of: odoo/enterprise#127177
2 changes
Resolved issues and error corrections
The live currency rate update service now uses the Romanian National Bank's new curs.bnr.ro domain. This keeps automated exchange rate updates working after the old www.bnr.ro access path is retired in August 2026.
Original PR description
As of 6 August 2026, the XML files used by software applications to retrieve daily exchange rates will no longer be available directly through addresses on the www.bnr.ro domain and will be accessible exclusively via the curs.bnr.ro subdomain. The XML file names will remain unchanged; only the access domain will be modified. no-task Forward-Port-Of: odoo/enterprise#127177
On python 3.10.12 `test_export_translatable_resources` fails. This is fixed in this commit build-944659 I only tested it on 17.0 since we do not seem to have the build error on higher versions. But the minimum python version is 3.10 until [excluding saas-19.1](https://github.com/odoo/odoo/blob/11ee42b4bf70a1008b06d13a48263e42c381aeed/odoo/release.py#L39) Forward-Port-Of: odoo/odoo#281294 Forward-Port-Of: odoo/odoo#280927
Original PR description
On python 3.10.12 `test_export_translatable_resources` fails. This is fixed in this commit build-944659 I only tested it on 17.0 since we do not seem to have the build error on higher versions. But the minimum python version is 3.10 until [excluding saas-19.1](https://github.com/odoo/odoo/blob/11ee42b4bf70a1008b06d13a48263e42c381aeed/odoo/release.py#L39) Forward-Port-Of: odoo/odoo#281294 Forward-Port-Of: odoo/odoo#280927
12 changes
Enhancements to existing features
The recurring donation product now includes a default placeholder image in the website shop. This gives donation pages a more complete and consistent appearance when no custom product image is set.
Original PR description
Added placeholder image for the recurring donation product. task-6361612 Forward-Port-Of: odoo/enterprise#126209
Resolved issues and error corrections
This change prevents the Website Sale Subscription app from failing to install if the default monthly subscription plan was previously deleted. It skips linking optional donation pricing data to that missing plan, allowing setup to continue normally.
Original PR description
Currently, an error occurs when user tries to install `website_sale_subscription` after deleting the monthly subscription plan. Steps to replicate: - Install `sale_subscription`. - Open Subscription…
Currently, an error occurs when user tries to install `website_sale_subscription` after deleting the monthly subscription plan.
Steps to replicate:
- Install `sale_subscription`.
- Open Subscription > Configuration > Recurring Plans.
- Delete the plan named `monthly`.
- Install `website_sale_subscription`.
Error:
```
ValueError: External ID not found in the system: sale_subscription.subscription_plan_month
odoo.tools.convert.ParseError: while parsing /home/odoo/odoo19/enterprise/website_sale_subscription/data/donation_data.xml:16, somewhere inside
<record id="product_recurring_donation_pricing_monthly" model="product.pricelist.item">
<field name="plan_id" ref="sale_subscription.subscription_plan_month"/>
<field name="product_tmpl_id" ref="product_recurring_donation"/>
<field name="fixed_price">1.0</field>
<field name="pricelist_id" eval="False"/>
</record>
```
Cause:
- Error is raised when assigning the `Monthly` subscription plan in the `website_sale_subscription` master data because the user has deleted the `Monthly` subscription plan.
Solution:
- As the `plan_id` is not a required field, we can skip assigning the `plan_id` if it the record is not found.
sentry-7441124574
Forward-Port-Of: odoo/enterprise#125649Users can now revoke a Belgian CodaBox connection using either the fidu password or a valid IAP token. This fixes a mismatch between the server and client behavior, making account disconnection smoother when a token is available.
Original PR description
The user should be able to revoke the CodaBox connection by either entering the fidu password or by using a valid iap_token. This was implemented in the iap server but not in the client side, after this commit the user should be able to either revoke by using the fidu password or by using the iap_token. task-6348433 Forward-Port-Of: odoo/enterprise#126698
This fix restores missing styling for spreadsheet side panels in the backend. Users should see the affected panels display correctly again after a previous CSS reorganization accidentally omitted the shared styling.
Original PR description
During the reorganisation of the css in #114180, the generic sidepanel.css file was removed from every assets. It belongs to the bundle assets at is impacts sidepanels that are only available in the backend (i.e. not in public spreadsheets) Task-6448906 Forward-Port-Of: odoo/enterprise#126850
Fixed an issue that could cause event badge printing to fail when a badge template included an image. This helps event staff print attendee badges reliably without interruptions.
Original PR description
Before this commit, some faulty logic in the `load_image` function caused a traceback when the ESC/LABEL badge template tried to use an image field. This bug only surfaced recently due to changes in how binary fields are accessed. After this commit, the logic is fixed and the traceback no longer occurs. task-6452486 Forward-Port-Of: odoo/enterprise#127017
The Sign portal now counts only documents that still need action from the signed-in user. This prevents completed signature requests from continuing to appear in the user’s to-sign total, making the portal status clearer and more accurate.
Original PR description
Version: 18.0 Steps to reproduce: - Create a sign request with two signers. - Assign the first signature to a portal user. - Log in as the portal user and sign the document. Issue: After signing, the to-sign count in the portal does not decrease. This is because the query only checks the overall sign request state instead of the individual signer's item state, so the count remains unchanged Fix: Added an item level state check to the count query so it only counts items that are still pending for that specific user. Task ID: 6412976 Forward-Port-Of: odoo/enterprise#126962 Forward-Port-Of: odoo/enterprise#125632
Google Reserve availability responses now avoid reporting more open spots than the total available spots. This prevents rare configuration mistakes from sending confusing or invalid availability information to Google.
Original PR description
This commit makes sure that we never send more "spots_open" than there are "spots_total" when Google Reserve asks for availabilities. This could happen in very rare case when customers create configurations that do not make sense (for example a table of 6 but no management of capacities and configuring 125 spots per resource). Task-6449615 Forward-Port-Of: odoo/enterprise#126855
Payslip reports now correctly hide note sections that contain only empty formatting rather than real content. This prevents blank note areas from appearing on payroll documents, keeping reports cleaner and more professional.
Original PR description
The condition was only checking if the note field was truthy. Actually, this can be a problem if the field is with only empty tags. Instead, we should use is_html_empty. Forward-Port-Of: odoo/enterprise#127052 Forward-Port-Of: odoo/enterprise#127008
This fixes payroll worked-day calculations so they can correctly consider inactive related records when generating payslips. It helps avoid incorrect payroll results in edge cases where archived records still affect employee pay history or contract data.
Original PR description
Forward-Port-Of: odoo/enterprise#114877
Fixed an issue in the Barcode app where selecting products from mixed packaged and unpackaged delivery lines could leave two lines selected at once. This makes warehouse picking clearer and helps prevent operator confusion during deliveries that include both package types.
Original PR description
**Steps to reproduce:** - Enable "Move Entire Packages" setting on deliveries - Make a product A, that has a package P1, on hand qty of 1 - Make product B that don't have a package, but on hand qty…
**Steps to reproduce:** - Enable "Move Entire Packages" setting on deliveries - Make a product A, that has a package P1, on hand qty of 1 - Make product B that don't have a package, but on hand qty of 1 - Make a delivery that has both of those products, requested qty of 1 for both - Mark it as todo - Go to the barcode app, select the delivery - Select the line with product B - Select the line with product A --> The line with product B is not unselected **Why the fix:** When we have a mix of packaged products and products without a package on the same operation, they are handled separately. The products without a package are handled in https://github.com/odoo/enterprise/blob/98c79af3fb6cb354f46fd2f58e642a72a9271443/stock_barcode/static/src/models/barcode_model.js#L388-L392 that calls https://github.com/odoo/enterprise/blob/98c79af3fb6cb354f46fd2f58e642a72a9271443/stock_barcode/static/src/models/barcode_model.js#L1277-L1284 But as you can see, there are no mention of the selected package line, which is stored in **this.lastScanned.packageId**. As we do not touch this variable, the selected package line stays selected. The same is true for the other way around, when we select a package line we call https://github.com/odoo/enterprise/blob/98c79af3fb6cb354f46fd2f58e642a72a9271443/stock_barcode/static/src/models/barcode_model.js#L394-L398 This function does not care for the **selectedLineVirtualId** which represents the selected line without a package. To avoid this and make it so that only one line is selected even if they have different package, we now set the corresponding value to false to unselect the other line in all situation. This is basically how it's done in https://github.com/odoo/enterprise/blob/98c79af3fb6cb354f46fd2f58e642a72a9271443/stock_barcode/static/src/models/barcode_model.js#L1202-L1208 to unselect every line regardless of packages. opw-6266203 Forward-Port-Of: odoo/enterprise#126790 Forward-Port-Of: odoo/enterprise#122038
Code cleanup and technical improvements
The live chat customer information panel now handles the Open Tickets section more consistently by removing a redundant check. This reduces the risk of display issues or crashes and adds test coverage to keep the behavior stable.
Original PR description
Enterprise counterpart of "[FIX] crm_livechat, *: prevent crash in the info panel", which explains why the condition of the caller goes away. This commit drops the same condition on the "Open tickets" block, and covers that block with a test. https://github.com/odoo/odoo/pull/280430 Forward-Port-Of: odoo/enterprise#126761 Forward-Port-Of: odoo/enterprise#126715
This update removes an outdated compatibility layer in several Odoo Enterprise screens now that the newer interface reference system is fully in place. It should not change day-to-day behavior for users, but it simplifies the code and reduces the risk of future maintenance issues.
Original PR description
Removes the leftover t-custom-ref migration shims Community: https://github.com/odoo/odoo/pull/280967
3 changes
Resolved issues and error corrections
This fix ensures a Swiss payroll value is properly recorded during ELM transmission processing. It helps payroll teams keep more complete and accurate transmission logs for compliance and troubleshooting.
Original PR description
Forward-Port-Of: odoo/enterprise#127241
This fix ensures Belgian payroll reports the correct mobility budget amount when a remaining balance is paid after the employee's current payroll version no longer includes a mobility budget. It uses the previous quarter's information instead of reporting zero, helping keep DMFA declarations accurate.
Original PR description
When the mobility budget balance is paid on a version that no longer carries a mobility budget, fall back to the previous quarter's version to declare the correct amount instead of 0. Task-6384786
The live currency rate update now uses the new Romanian National Bank subdomain for exchange rate files. This keeps automated exchange rate updates working after the bank retires the old web address in August 2026.
Original PR description
As of 6 August 2026, the XML files used by software applications to retrieve daily exchange rates will no longer be available directly through addresses on the www.bnr.ro domain and will be accessible exclusively via the curs.bnr.ro subdomain. The XML file names will remain unchanged; only the access domain will be modified. no-task Forward-Port-Of: odoo/enterprise#127177
5 changes
Resolved issues and error corrections
This fix ensures Belgian payroll reports the correct mobility budget balance when it is paid after the related contract no longer has an active mobility budget. It uses the previous quarter's contract information so declarations avoid incorrectly showing a zero amount.
Original PR description
When the mobility budget balance is paid on a contract that no longer carries a mobility budget, fall back to the previous quarter's contract to declare the correct amount instead of 0. Task-6384786
Steps to reproduce: - Create a sale order with a down payment term. - Invoice the down payment (down payment invoice A). - Credit that down payment invoice directly (credit note A), without reconciling it with anything else. - Generate the FatturaPA XML for credit note A. - Observe that DatiFattureCollegate lists both down payment invoice A and credit note A itself, instead of only down payment invoice A. On an order with several down payment invoices/credit notes over time, every one of th
Original PR description
Steps to reproduce: - Create a sale order with a down payment term. - Invoice the down payment (down payment invoice A). - Credit that down payment invoice directly (credit note A), without…
Steps to reproduce: - Create a sale order with a down payment term. - Invoice the down payment (down payment invoice A). - Credit that down payment invoice directly (credit note A), without reconciling it with anything else. - Generate the FatturaPA XML for credit note A. - Observe that DatiFattureCollegate lists both down payment invoice A and credit note A itself, instead of only down payment invoice A. On an order with several down payment invoices/credit notes over time, every one of them is listed instead of just the document the current credit note actually reverses. Cause of the issue: _l10n_it_edi_export_data built downpayment_moves from self.invoice_line_ids._get_downpayment_lines().move_id with no filtering. _get_downpayment_lines() (sale override) returns every invoice line ever created against the same down payment sale order line, across the whole life of the order, not just the invoice the current document actually relates to. The template renders DatiFattureCollegate for every one of those moves unconditionally, on top of the already-correct reversed_entry_id/reconciled_moves fallback, including the current document itself. Solution: Restrict downpayment_moves to lines with a negative price_subtotal, mirroring the existing down payment deduction-line detection a few lines above, and explicitly exclude the current document. This limits DatiFattureCollegate's down payment entries to the case they are meant for: a final invoice actually deducting a previously invoiced down payment. opw-6429716
**Steps to Reproduce:** 1. Send a message to Marc demo with Mitchell admin or vice-versa, read the message from reciever's side. 2. Click on seen-by indicator from sender's side, make sure the dialog appears and then Press `'ESC'`. 3. Chat window closes whereas the dialog should have closed. Since #169737, pressing 'esc' on the seen-by dialog closes the chat window instead of the dialog. The chat window's root element has a keydown handler that closes the window on `'escape'`, and cat
Original PR description
**Steps to Reproduce:** 1. Send a message to Marc demo with Mitchell admin or vice-versa, read the message from reciever's side. 2. Click on seen-by indicator from sender's side, make sure the dialog…
**Steps to Reproduce:** 1. Send a message to Marc demo with Mitchell admin or vice-versa, read the message from reciever's side. 2. Click on seen-by indicator from sender's side, make sure the dialog appears and then Press `'ESC'`. 3. Chat window closes whereas the dialog should have closed. Since #169737, pressing 'esc' on the seen-by dialog closes the chat window instead of the dialog. The chat window's root element has a keydown handler that closes the window on `'escape'`, and catches focus by default whenever something non-focusable is clicked inside it (e.g. the seen-by indicator). The seen-by dialog's content had no focusable element, so it never grabbed focus for itself, leaving focus on the chat window. Pressing 'escape' therefore closed the chat window instead of the dialog. This commit fixes the issue by adding tabindex on the template, letting the dialog grab focus like other dialogs/popovers already do, so `'escape'` is handled by the dialog first. task-4895004
On python 3.10.12 `test_export_translatable_resources` fails. This is fixed in this commit build-944659 I only tested it on 17.0 since we do not seem to have the build error on higher versions. But the minimum python version is 3.10 until [excluding saas-19.1](https://github.com/odoo/odoo/blob/11ee42b4bf70a1008b06d13a48263e42c381aeed/odoo/release.py#L39) Forward-Port-Of: odoo/odoo#280927
Original PR description
On python 3.10.12 `test_export_translatable_resources` fails. This is fixed in this commit build-944659 I only tested it on 17.0 since we do not seem to have the build error on higher versions. But the minimum python version is 3.10 until [excluding saas-19.1](https://github.com/odoo/odoo/blob/11ee42b4bf70a1008b06d13a48263e42c381aeed/odoo/release.py#L39) Forward-Port-Of: odoo/odoo#280927
When several xmlids point to the same record, PostgreSQL's UPDATE ... FROM can match multiple source rows to one target and pick an arbitrary value. Aggregate translations per res_id in import order so the later entry wins Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#277818
Original PR description
When several xmlids point to the same record, PostgreSQL's UPDATE ... FROM can match multiple source rows to one target and pick an arbitrary value. Aggregate translations per res_id in import order so the later entry wins Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#277818