Tuesday, January 27, 2026
21 changes · saas-18.3
Resolved issues and error corrections
This update fixes an issue where dialog boxes were hidden behind chat windows, making them difficult to use. Now, dialogs appear above all chat windows except the AI chat window, ensuring a clearer and more intuitive user experience.
Original PR description
**Description of the issue this PR addresses:** ------------------------------------------------ Dialogs were rendered behind chat windows, making them difficult to see and interact with. **Current behavior before PR:** --------------------------------- - The dialog appears behind the chat window **Desired behavior after PR is merged:** ----------------------------------------- - Dialogs are displayed above all chat windows except AI - The AI chat window remains intentionally above dialogs **Task:** 5367135
This update corrects a technical issue that was causing an error message to appear on the TFN dashboard, specifically related to employee TFN status reporting. The fix ensures accurate warning calculations for employees applying for TFNs, improving payroll reporting reliability. This resolves a potential data discrepancy.
Original PR description
Steps to reproduce: ------------------- 1. Install l10n_au_hr_payroll. 2. Enable multi-company and switch to an AU company. 3. Change an existing employee’s company to the AU company ([employee…
Steps to reproduce:
-------------------
1. Install l10n_au_hr_payroll.
2. Enable multi-company and switch to an AU company.
3. Change an existing employee’s company to the AU company
([employee created more than 28 days ago](https://github.com/odoo/enterprise/blob/7adab8bfdccf5f0e97eb2894e065b63ea8200d20/l10n_au_hr_payroll/data/hr_payroll_dashboard_warning_data.xml#L31)).
4. Under the payroll tab, set the TFN Status to:
"Employee applied for TFN but didn't receive it yet, less than 28 days ago".
5. Open Payroll.
Issue:
--------
A traceback occurred:
```
Error: NameError("name 'invalid_employees' is not defined")
```
Cause:
------
The evaluation code computes `warning_count` using
an undefined `invalid_employees` variable.
Solution:
---------
Define `invalid_employees` before using it to compute
`warning_count` and `warning_records`.
**NOTE:**
The [upgrade script](https://github.com/odoo/upgrade/blob/ed5bc3fd99ef6fba4bc7162934df36396ae9fc3f/migrations/l10n_au_hr_payroll/saas~18.4.1.0/end-migrate.py#L30) is already available from version 18 to 19.
opw-5459998
Forward-Port-Of: odoo/enterprise#103777This update resolves an issue preventing portal users from filtering job listings by department. The fix corrects a permissions error that restricted access, ensuring all users can utilize the department filter on the Jobs page. This improves the user experience for job seekers.
Original PR description
## Issue: Filtering by Department on the Jobs page as a Portal user raised a Forbidden Error ## Cause: Portal users lacked access rights on hr.department, even though public users have it ## Steps to reproduce: You need a portal user and a published job position in a department (you can use demo data) - Open the Website > Jobs page as Admin - Edit > Customize > Enable Department filter > Save - Login with Portal User - Access the jobs page and set a Department filter opw-4948838
This update resolves an issue in Odoo Studio where incorrectly configured related fields could cause warnings and errors. The change ensures that Studio only creates relational fields with searchable data types, preventing these technical problems and improving stability for business users. This resolves a previous operational issue.
Original PR description
Before this commit studio allowed to make a related field with a non-searchable field (ie standard computed fields) in the the chain. This triggered a warning at creation (at fields.py:resolve_depends) and errors when using in a business setting. After this commit, the filter to build the relational field is modified to take into account this. opw-5436158
This update addresses a limitation in the account online synchronization process where access tokens expire quickly. We've implemented a new consent token system – a unique, secure identifier linked to the user – to ensure reliable consent management and continued synchronization functionality. This change improves the user experience and maintains data consistency.
Original PR description
In this commit:bf5b7d0 we introduce a message on the account_online_link to be able to manage the consent. (one needed fix in this commit:https://github.com/odoo/enterprise/commit/1c84804fd3f0c0d1d23916b9f6a388616f66ac7e) This commit will change the way we manage the consent since the access token is in fact available only for 30 min, so the link in the chatter would not work. We decided to have a consent token which is a uuid4 encoded in base64 (url safe) and link it to the odoofin user. task-5187621 Forward-Port-Of: odoo/enterprise#105392 Forward-Port-Of: odoo/enterprise#105202
This update fixes an access error that prevented users with standard inventory permissions from generating serial numbers for tracked products. The issue stemmed from a specific write operation within the system's serial number generation process. The fix ensures that users can correctly generate serial numbers without encountering access restrictions.
Original PR description
**Behavior:** Behavior: When logged in as a user with group_user access (member), trying to generate the next few serial numbers for a tracked product from receipts will cause an access error. This…
**Behavior:** Behavior: When logged in as a user with group_user access (member), trying to generate the next few serial numbers for a tracked product from receipts will cause an access error. This happens because there is a write operation on the ir.sequence linked to the serial number at the end of the process that happens only when the 'New' button was previously pressed. And since access rights to ir.sequence are dependant on the base group of the user, changing the user Inventory rights to admin will not resolve the issue. A test has been created to ensure no access error is created when generating sequence numbers as a lower access user, this test would pass without the fix since it is focused on the python function. **Steps to reproduce:** - Create a product that is tracked by serial number - Log in as a user with group_user access (member role) - Go to Inventory -> Operations -> Receipts - Create a new picking and add the product - After clicking on Mark as Todo you'll see Details pop up in the product line - After clicking Details, select Generate Serial/Lots - Click New, then Generate, and you'll get an access error for ir.Sequence opw-5368553
This update fixes a bug where users could successfully pay invoices with expired Sales Orders. Now, the system automatically prevents payment attempts when the Sales Order's expiry date has passed, ensuring accurate financial records and preventing incorrect payments. This improves the reliability of our payment processing.
Original PR description
## Issue: Payment link should expire if payment is expired. #### Steps to reproduce: 1- Create a new quotation. 2- Set the expiry date in the past. 3- Open the action menu and generate a payment link. 4- Open the payment link and pay. Expected result: The payment should fail if the so is expired. opw-5478691 Forward-Port-Of: odoo/odoo#245601 Forward-Port-Of: odoo/odoo#244061
This update corrects a bug that prevented companies using the Euro as their main currency from syncing exchange rates correctly. The BNB now provides rates in EUR, and this change ensures the system recognizes and utilizes the updated data. Companies with BGN as their currency will also experience this error.
Original PR description
The `_parse_bnb_data` method assumed that the Bulgarian National Bank (BNB) provides exchange rates against BGN (Bulgarian Lev). However, since Bulgaria joined the Eurozone on January 1, 2026, the…
The `_parse_bnb_data` method assumed that the Bulgarian National Bank (BNB) provides exchange rates against BGN (Bulgarian Lev). However, since Bulgaria joined the Eurozone on January 1, 2026, the BNB now provides rates against EUR. This caused the error "Your main currency (EUR) is not supported by this exchange rate provider" when Bulgarian companies with EUR as their main currency tried to sync exchange rates. refs: We can compare the data here from 31 December using the WayBackMachine: https://web.archive.org/web/20251231193558/https://www.bnb.bg/Statistics/StExternalSector/StExchangeRates/StERForeignCurrencies/index.htm Compared to today: https://www.bnb.bg/Statistics/StExternalSector/StExchangeRates/StERForeignCurrencies/index.htm And see the comparison used to be to BGN but is now for EUR Steps To Reproduce: 1. Create a company for Bulgaria with EUR as the main currency. 2. Go to Accounting Settings -> Automatic Currency Rates. 3. Select "[BG] Bulgaria National Bank" as the service provider. 4. Click the sync button. 5. Error appears: "Your main currency (EUR) is not supported by this exchange rate provider. Please choose another one." The fix updates the base currency from BGN to EUR, matching the current BNB XML format which now provides rates against EUR. Note: Companies with BGN as main currency will now get the same error, which is expected since the BNB no longer provides BGN-based rates. This behavior was discussed and confirmed with the PO. Ticket [link](https://www.odoo.com/odoo/project.task/5483771) opw-5483771 Forward-Port-Of: odoo/enterprise#105074
This update resolves errors in the SAF-T export process for Romanian companies when partner information (country or name) is missing. The fix ensures accurate invoice generation and SAF-T file creation by correctly handling missing partner details, specifically the RegistrationNumber format.
Original PR description
Fix SAF-T export errors when partners have no country or name. For Romanian companies, the RegistrationNumber should be generated as “04 + partner ID” for customers not subject to VAT and with unknown CNP, without including the country code. Steps to reproduce country issue: - Configure a Romanian company with l10n_ro_saft installed - Create a contact without a country - Create and validate an invoice for this contact - Export the SAF-T file from the General Ledger report You you will get a TypeError because you cant concatenate Bool and String. Steps to reproduce name issue: - Create a main contact - Add a child contact without a name - Change the child type to “Company” - Create and validate an invoice - Export the SAF-T file from the General Ledger report This prevents KeyError when printing the first 70 characters of the partner name in the report. opw-5499918 Forward-Port-Of: odoo/enterprise#105406 Forward-Port-Of: odoo/enterprise#105020
This update resolves an issue in Odoo's Web Studio where it could incorrectly link fields, leading to warnings and errors during setup. The change ensures that related fields are only created when linked to searchable fields, improving stability and preventing potential problems in business workflows. This resolves a technical issue impacting Studio's reliability.
Original PR description
Before this commit studio allowed to make a related field with a non-searchable field (ie standard computed fields) in the the chain. This triggered a warning at creation (at fields.py:resolve_depends) and errors when using in a business setting. After this commit, the filter to build the relational field is modified to take into account this. opw-5436158
This update resolves an issue where the quantity of products transferred during the MRP process was sometimes incorrectly calculated. The fix adds extra steps to ensure the filtering and quantity updates are synchronized, leading to more accurate product transfers and a smoother user experience. This improves the reliability of the MRP workflow.
Original PR description
Error message ----- ``` FAIL: TestTourMrpOrder.test_mrp_multi_step_product_catalog_component_transfer Traceback (most recent call last): File "/data/build/odoo/addons/mrp/tests/test_order.py", line…
Error message
-----
```
FAIL: TestTourMrpOrder.test_mrp_multi_step_product_catalog_component_transfer
Traceback (most recent call last):
File "/data/build/odoo/addons/mrp/tests/test_order.py", line 5433, in test_mrp_multi_step_product_catalog_component_transfer
self.assertEqual(component_transfer.product_uom_qty, 2)
AssertionError: 1.0 != 2
```
Cause
-----
It looks like somehow one of the 2 clicks on the product is either not registered, or the update of the POL's quantity isn't triggered / doesn't happen fast enough, so the tour ends with a quantity of 1 for the product. I see 2 possible causes for this:
1. The product is visible in the initial view. So when the view updates (because of the filtering step), the next step - clicking on the product - the clicks can already be triggered, which might lead to an inconsistent state.
2. There is some synchronicity issue with the quantity update's debounce
https://github.com/odoo/odoo/blob/11292070870ef22663364eda5a4b243dea68856a/addons/product/static/src/product_catalog/kanban_record.js#L16-L18
Solution
-----
Add extra steps to wait for filtering to be applied. Also add extra steps to ensure correct update of the POL's quantity.
-----
Runbot error 237956This update resolves a bug that caused the follow-up report to crash when users unfolded partner lines while prefix groups were enabled. The fix ensures the report handles complex data structures correctly, improving stability and reliability for users generating these reports.
Original PR description
When prefix groups were enabled, and a prefix group line had been unfolded, the report crashed when trying to unfold the partner. This happened because res_ids_map is computed for each of the unfolded lines, including the prefix groups one, which then had no 'res.partner' key, causing a key error. Forward-Port-Of: odoo/enterprise#105525
This update fixes an issue where the quantity delivered on sale orders wasn't accurately updated after a partial refund with a 'Ship Later' option. Previously, the system incorrectly reported zero delivered quantities. The fix ensures that delivered quantities are correctly calculated, including those associated with refunded orders, to provide accurate inventory tracking.
Original PR description
The qty_delivered on sale.order.line was not correctly computed when the original order was refunded with a ship later. Steps to reproduce: ------------------- * Create a sale order for 5 quantities of any product * Confirm the sale order * Settle the order in the PoS * At this point the qty_delivered on the sale order line is 5 * Now go back to the PoS and refund partially the order for 3 quantities and use the "Ship Later" option > Observation: The qty_delivered is 0 instead of 2 Why the fix: ------------ We group the pos.order.line by procurement group and then check if all pickings related to these lines are done before adding the qty to the qty_delivered. We also make sure to include the refund lines in the computation opw-5059560 Forward-Port-Of: odoo/odoo#244008 Forward-Port-Of: odoo/odoo#240945
This update resolves a bug in the website editor that occurred when users manipulated the page, leading to incorrect selection offsets. Specifically, clicking on blank spaces could cause errors. The fix ensures that selection offsets are validated, preventing these errors and improving the stability of the website editor, particularly in Chrome.
Original PR description
**Description of the problem** In the website editor, the user can manipulate the page in such a way to generate a problematic `SelectionPlugin.activeSelection`, which still points to an existing…
**Description of the problem** In the website editor, the user can manipulate the page in such a way to generate a problematic `SelectionPlugin.activeSelection`, which still points to an existing `anchorElement`, but has an invalid `offset`. **How to reproduce** This seems to be reproducible only on Chrome. 1. Enter in the website edit mode 2. Drop the `s_newsletter` snippet 3. Drop the `s_popup` snippet 4. Click on the popup, and delete it 5. Click on the blank space inside the `s_newsletter` snippet 6. Delete the `s_newsletter` snippet 7. The error occurs Notes: 1. Snippet different than `s_newsletter` can be used to reproduce the problem, as long as they contain a blank space. 2. It is important to make sure that the movement of the mouse pointer does not trigger any preview when going from step 5 to step 6. **Why the problem happens** On Chrome, clicking on a blank area can cause `document.getSelection()` to return a selection with a null `anchorNode.` When this happens, `SelectionPlugin.getSelectionData()` will use the already existing `activeSelection` if `activeSelection.anchorNode` is still connected. Before this commit, this method only checked that `anchorNode` was connected, without validating offsets. This leads to the following edge case: 1. The user removes the `s_popup` 2. At this point, `document.getSelection()` would point to the `s_newsletter` snippet, so if the user just deletes the snippet nothing bad would happen. But instead, if: 3. The user clicks on a blank area in `s_newsletter`, `document.getSelection()` will now return a null `anchorNode` 4. The user delete the `s_newsletter` snippet, and `SelectionPlugin.getSelectionData()` is called by an handler after the deletion 5. At this point: `document.getSelection()` has a null `anchorNode`, so the method will check if `activeSelection.anchorNode` is still connected, WITHOUT validating the offsets. 6. Since `anchorNode` is still connected, this selection will be used, and an error will be triggered shortly after, because the offset is too high (pointing to `s_popup` which does not exist anymore). **Fix** After this commit, when `SelectionPlugin.getSelectionData()` checks that `activeSelection.anchorNode` is still connected it also checks that the offsets are valid (meaning that they are smaller than the number of nodes). task-5430500 Forward-Port-Of: odoo/odoo#244331
This update fixes a rounding error in the calculation of withholding taxes for Argentine businesses. Specifically, the withholding amount was slightly off, resulting in a discrepancy. The change ensures accurate tax calculations for purchase withholdings, improving financial reporting accuracy.
Original PR description
Steps to reproduce: - Set company to (AR) Responsable Inscripto - In Accounting > Settings, choose Round per Tax as the rounding method. - Go to Accounting > Taxes, duplicate IIBB WTH CABA 0%, and set Amount to 4.5%. - Open partner ADHOC SA, in the accounting tab add the new tax in Purchase Withholding - Create a new vendor Bill to vendor ADHOC SA with unit price 156,087.00 - Confirm and open Payment wizard Issue: Withholding amount is 7023.91, but it should be 7023.92 It occurs that the computed amount is 7023.915. Then when the tax repartition values are computed, the value is rounded and rounding difference are redistributed in the tax lines, so it seems the value has been rounded down. opw-5154585 Forward-Port-Of: odoo/odoo#241633
This update fixes an issue where dialog windows were hidden behind the AI chat window, making them difficult to use. Now, dialogs are consistently displayed above all chat windows except the AI chat window, ensuring a clearer and more intuitive user experience.
Original PR description
**Description of the issue this PR addresses:** ------------------------------------------------ Dialogs were rendered behind chat windows, making them difficult to see and interact with. **Current behavior before PR:** --------------------------------- - The dialog appears behind the chat window **Desired behavior after PR is merged:** ----------------------------------------- - Dialogs are displayed above all chat windows except AI - The AI chat window remains intentionally above dialogs **Task:** 5367135
This update resolves an issue where users without administrative privileges could encounter errors when generating global invoices in the Mexican CFDI module. The fix addresses a caching problem and incorrect access control within the invoice generation process, ensuring reliable global invoice creation for all users.
Original PR description
**PROBLEM** 1. When generating a global invoice with a user without super user access, a access error may occur on the ir.sequence model. 2. There is an issue with the cache of the field…
**PROBLEM** 1. When generating a global invoice with a user without super user access, a access error may occur on the ir.sequence model. 2. There is an issue with the cache of the field `l10n_mx_edi_global_invoice_sequence_id`. (this is why problem can sometimes resolves itself on restarting the odoo instance). **STEP TO REPRODUCE** 1. Create 1 invoice with CFDI to public checked. 2. Goes to the list view for invoices, select the invoice, and apply the action "create global invoice" to it. 4. A access error may appear (depending on cache value). **CAUSE** 1. In `_get_global_invoice_cfdi_sequence()`, we get or create the ir.sequence used for global invoices. We are creating it with sudo(), so a user without sudo privilege can write to it. But, when we are retrieving a ir.sequence record that already exist, when don't use sudo(), this causes an access error for user without sudo privilege. 2. In `_get_global_invoice_cfdi_sequence()`, we try to get the computed field `l10n_mx_edi_global_invoice_sequence_id`. If it doesn't exist, we create a ir.sequence, but we forget to assign it to the field. Because we already trigger the compute method of the field by trying to access it, there is a None value in cache for it. This means we will always create a ir.sequence, despite one already existing for the company until the cache expires or the compute method is re-triggered. opw-5472552 Forward-Port-Of: odoo/enterprise#104181
This update fixes an issue preventing Latin American electronic invoices from printing correctly in PDF format. The change ensures the invoice header and footer are accurately displayed, regardless of whether a chart template is set up in the database, addressing a problem with older systems. This ensures accurate invoice generation for businesses in Argentina, Chile, Brazil, and other Latin American countries.
Original PR description
This commit fixes a bug introduced here https://github.com/odoo/odoo/commit/3f7d79731fd5e5a751f7f1aeae63379c6211de5c because some old databases do not have set the chart template so it is needed to render the header and footer of the report template layouts taking in consideration the account fiscal country code instead of the chart template. Replicate printing the pdf of a customer electronic invoice on an argentinen company without chart template. Ticket Adhoc side: 105739 Task latam: 1373 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#244102 Forward-Port-Of: odoo/odoo#238033
This update resolves an issue where customer invoices sent via Peppol were generating duplicate attachments, causing clutter in the system. The fix ensures that attachments are updated instead of created again, streamlining the invoice process and improving the user experience. This prevents confusion and ensures consistent attachment management.
Original PR description
When sending a customer invoice via Peppol, the system creates duplicate attachments (4 instead of 2 expected), cluttering the chatter and the attachment sidebar. This commit: - Implements a search-and-update logic for attachments to ensure idempotency (updates existing instead of creating duplicates). task-5438951 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#245370 Forward-Port-Of: odoo/odoo#241130
A previous issue prevented users from adding attachments when sending emails to large contact lists (501+ contacts). This update corrects a technical error related to how the system handles large contact selections, ensuring attachments can now be successfully added during mass email campaigns. This improves the reliability of the email sending process.
Original PR description
Steps to reproduce: 1. Install 'contact' 2. Create 501+ contacts (e.g. by duplicating existing one) 3. Select all contacts in list view and click Send Email (from Action menu) 4. Try to add an attachment Issue: - A traceback is raised in the mail composer: `SyntaxError: Unexpected end of JSON input` Cause: `res_ids` is not set on the composer when more than 500 records are selected. This is expected, as the compute method `_compute_res_ids()` does not write `res_ids` when the number of active_ids exceeds 500 (to avoid storing large payloads on the field). Because of this, the code trying to JSON.parse(res_ids) fails. see: https://github.com/odoo/odoo/blob/abc8417413faf598fb83106de4328571d71888aa/addons/mail/wizard/mail_compose_message.py#L400 Solution: - Fallback to context.active_ids when res_ids is not available opw-5351374 Forward-Port-Of: odoo/odoo#238311
This update enhances the security and reliability of our Peppol integration by safely handling server deregistration when a client leaves. The system now allows for a controlled reset of configurations, enabling users to re-register without disruption. This change was prompted by a previous incident and improves the overall stability of the Peppol connection.
Original PR description
Reintroduce server-initiated deregistration on `client_gone`, but only for implementations that explicitly handle it. The base proxy client now just raises the error. Peppol opts in by soft-resetting its configuration so users can re-register. See the IAP postmortem for the rationale and incident history. https://github.com/odoo/iap-apps/pull/1317 no-task Forward-Port-Of: odoo/odoo#245567 Forward-Port-Of: odoo/odoo#239254