Daily updates from Odoo
Wednesday, May 13, 2026
15 changes · saas-18.3
Resolved issues and error corrections
This update corrects a display issue where certain quality point types were incorrectly shown regardless of the selected operations. The fix ensures these types are only visible when a manufacturing operation is selected and a work order operation is defined, improving data accuracy and usability.
Original PR description
**Steps to reproduce:** - Install `quality_control` and `mrp` modules with demo data - Go to Quality → Quality Points → Create(New) - In the `Type` field, observe that options such as 'Print Label',…
**Steps to reproduce:**
- Install `quality_control` and `mrp` modules with demo data
- Go to Quality → Quality Points → Create(New)
- In the `Type` field, observe that options such as
'Print Label', 'Register Production', etc. appear
regardless of the selected `Operations`
**Issue**:
Types like `print_label`, `register_production`,
`register_byproducts`, and `register_consumed_materials`
are displayed even when the Operations is not
Manufacturing and when no work order operation is defined.
**Expected behavior**:
These `types` should only be available when:
- `Operations` Type = Manufacturing
- `work order operation` is set
**Cause**:
The custom search logic for the `allow_registration` boolean field
relied on receiving a direct `True` or `False` value.
https://github.com/odoo/enterprise/blob/de3682c7f50b68c19d3a3429fa3768c447074f50/mrp_workorder/models/quality.py#L104
Before `saas-18.3`, the `value` passed to the domain search method was
a plain boolean(True/False).
https://github.com/odoo/enterprise/blob/de3682c7f50b68c19d3a3429fa3768c447074f50/mrp_workorder/models/quality.py#L21-L24
Starting from `saas-18.3`, the value is passed as
`OrderedSet([True])`. while the operator received is `in`
or `not in`.
Because the value always arrives `OrderedSet([True])`,
the condition checking the `value` is always
evaluated as truthy. As a result, the code never reaches the
else branch of the logic, which causes the incorrect domain
behavior.
The issue is caused by how Odoo optimizes boolean domains.
When we pass:
('allow_registration', '=', False)
the value correctly reaches the base domain logic as
`allow_registration = False`.
But during domain processing at:
https://github.com/odoo/odoo/blob/347c46f8ecff7ae97c2a686bf5750374b6c3e2d3/odoo/orm/domains.py#L967
it optimize it to:
('allow_registration', 'in', [False])
Then `_optimize()` is called, which again calls
`_optimize_step()`:
https://github.com/odoo/odoo/blob/347c46f8ecff7ae97c2a686bf5750374b6c3e2d3/odoo/orm/domains.py#L459
Inside `_optimize_step()` at:
https://github.com/odoo/odoo/blob/347c46f8ecff7ae97c2a686bf5750374b6c3e2d3/odoo/orm/domains.py#L971
it is further simplified to:n ('allow_registration', 'not in', [True])
Similarly, when we pass: ('allow_registration', '=', True)
it becomes: ('allow_registration', 'in', [True])
This is expected behavior.
The custom search method for `allow_registration`
was not handling these optimized forms correctly,
which caused Issue.
**FIX:**
- Use the domain `operator (in / not in)` to determine the intended
boolean condition instead of relying on the received value(OrderedSet([True])).
- This is correct because Odoo normalizes boolean domains to only two
forms during optimization: in [True] and not in [True]. Therefore,
the operator reliably indicates whether the condition expects
True or False, allowing the search method to handle the domain
correctly.
---
opw-5915197This update fixes an issue where portal messages were incorrectly restricted, preventing certain message types from being visible to users. The change expands the visibility of non-internal messages while still hiding internal notes as intended. This ensures all users can access relevant portal communications.
Original PR description
*: test_mail_full Since #138233, portal messages were strictly filtered by the `mt_comment` subtype. This was intended to hide internal notes, but it incorrectly excluded other non-internal message subtypes. Basically we want the share domain (`_get_search_domain_share()`) to apply to all users in the portal. This change ensures internal notes remain hidden while allowing all other non-internal non-comment subtypes to be visible. opw-6031571 Forward-Port-Of: odoo/odoo#263914 Forward-Port-Of: odoo/odoo#263052
This update corrects a previous oversight by adding the 'l10n_pl_bank_verification' module to the Weblate translation files. This ensures accurate translations are available for the new bank verification feature in the Odoo system, improving the user experience for Polish customers.
Original PR description
[FIX] Add l10n_pl_bank_verification to weblate.json In a previous PR, we added the new module 'l10n_pl_bank_verification' but didn't added it in weblate.json. This PR fix it See odoo/odoo#262518 Forward-Port-Of: odoo/odoo#263758
This update resolves an issue where users were receiving an error message when exporting payroll data to SDWorx for freelance employees. The change removes a previous check that incorrectly flagged freelancers, ensuring accurate data transfer. This improves the user experience for our Belgian customers using the SDWorx integration.
Original PR description
Steps to reproduce: ------------------------------- 1. Install `l10n_be_hr_payroll_sd_worx` module 2. Switch the active company to a Belgian company 3. Go to Employees and create a new employee. Set…
Steps to reproduce: ------------------------------- 1. Install `l10n_be_hr_payroll_sd_worx` module 2. Switch the active company to a Belgian company 3. Go to Employees and create a new employee. Set the Employee Type to Freelancer from HR Settings page. 4. Navigate to Payroll > Reporting > Export Work Entries to SDWorx Observation: ------------------------------- A user error is raised stating: ``` There is no SDWorx code defined for the following employees ``` Issue: ------------------------------- In https://github.com/odoo/enterprise/pull/106065/changes/c19009c776349c3f5d8aebf99aff8efe987b54db The Check for Freelance Employee type was removed, which was earlier added in the fix https://github.com/odoo/enterprise/pull/102211/changes/96724c3cc55725e87e618443b96069921b8f3bda Solution: ------------------------------- Add a condition to the employee filter to exclude freelance employees from the SDWorx code validation. opw-5387342 Forward-Port-Of: odoo/enterprise#114411
This update resolves an issue where test emails sent through the Email Marketing app would leave a related attachment visible in the chatter of contact records. The fix ensures that test messages are properly removed from the Chatter after sending, preventing clutter and improving the user experience. This change was backported from a previous fix.
Original PR description
**Steps to reproduce:** - Go to Email Marketing app - Create a mailing campaign - Set its recipients to Contact - Upload a file in Settings > Attach a file - Click on the test button to send a test mail to any mail - Go to the first contact record - Related attachment appears in the chatter **Issue:** Before 18.2, messages created for testing were ignored by the Chatter as they were empty (and not unlinked). But if an attachment was provided, it was linked to the test message and not deleted afterwards (which means it shows up in the record chatter). **Fix:** Ensure the related messages are unlinked at the same time as the test mail in `send_mail_test` by setting `is_notification` to False to trigger the `unlink` logic and remove the related attachments at the same time. backport of: https://github.com/odoo/odoo/commit/526b3d73886558315f2435714b2ed82fec313e78 opw-6168632 Forward-Port-Of: odoo/odoo#262152
This update resolves a technical issue that prevented invoices with Early Payment Discounts (EPD) and 0% tax from passing schematron validation, a requirement for Peppol compliance. The fix ensures accurate VAT breakdowns are generated, addressing a previous error where duplicate tax categories were created and a hardcoded tax code was used, ultimately improving invoice accuracy and compliance.
Original PR description
Before this commit, creating an invoice with an Early Payment Discount (EPD) as a payment term could cause the schematron validation of the generated invoice to fail when an invoice line had a 0% tax. The issue was caused by generating two TaxSubtotal nodes for the same TaxCategory (0%, exemption code 'E'): - one for the 0% VAT - one for the EPD discount applied to the total amount However, Peppol requires a single VAT breakdown (TaxSubtotal) per VAT category (in this case: E) Additionally, when VAT was set to 0%, the allowance charge TaxSubtotal incorrectly used 'S' as a hardcoded tax category code. This commit fixes both issues. task-5900496 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#263501 Forward-Port-Of: odoo/odoo#254199
This update fixes a problem in our sale stock testing process. A test was incorrectly running due to outdated cached data, allowing it to pass even when it shouldn't. This change ensures tests accurately reflect the system's behavior and improves overall reliability.
Original PR description
When running the test, `button_validate()` was called twice in succession. - Once explicitly - Once through `process_cancel_backorder()` The first time it is called though, it's not through the restricted user that we want to test, allowing some access rights checks to run smoothly. The second time it's called with the restricted user, the cache still contains some data that should be no longer accessible, allowing the test to run even though it shouldn't. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264057
This update resolves an issue where regular users were encountering access errors when viewing sales orders, specifically when checking if the customer was another company. This prevented them from properly processing deliveries, regardless of whether the order was inter-company or not. The fix ensures all users can access relevant sales order information.
Original PR description
When running `button_validate`, a regular stock user won't be able to access the related SO to check whether the partner is another company or not. This will raise access errors for all regular SO deliveries, regardless of being inter-company or not. Forward-Port-Of: odoo/enterprise#117047
This update resolves an issue where users with planning manager permissions couldn't copy planning slots to employees with flexible calendars due to access restrictions. Now, users with planning manager rights can successfully copy and move slots, improving usability and workflow efficiency for planning managers.
Original PR description
**Purpose**: A user with planning manager rights but no access to employee and contract records should be able to copy and movea planning slot to an employee with a flexible resource_calendar without…
**Purpose**: A user with planning manager rights but no access to employee and contract records should be able to copy and movea planning slot to an employee with a flexible resource_calendar without getting an access rights error. **Before this commit:** When copying a planning slot, the system tries to compute the working hours over the period of the slot. This will raise an access rights error if the user doesn't have access to employee and contract records when the slot is moved to a flexible resource_calendar. **After this commit:** The user can copy a planning slot without access rights error with only planning manager rights, even if the slot is moved to a flexible resource_calendar. **Steps to reproduce:** 1.Install Planning and Planning Contract modules. 2.Create a user with only planning manager rights and no access to employee and contract records. 3.Copy a planning slot to an employee with a flexible resource_calendar. opw-6166557 Forward-Port-Of: odoo/enterprise#115953
This update fixes an issue where returned subcontracted products were incorrectly routed to the subcontractor's location instead of the user's stock. When returning products 'for exchange', the system now correctly directs returned items to the subcontractor's location and new deliveries to the user's stock, ensuring accurate inventory tracking. This improves the efficiency of subcontracting operations.
Original PR description
## Issue When making a request for quotation for a subcontracted product and returning the delivery "for exchange", the new incoming delivery does not have the correct destination. Instead of having…
## Issue
When making a request for quotation for a subcontracted product and returning the delivery "for exchange", the new incoming delivery does not have the correct destination. Instead of having the stock of the user, the destination of the new incoming delivery is the same as its source: the subcontracting location.
<img width="1254" height="257" alt="5479900" src="https://github.com/user-attachments/assets/c7e6d392-8328-4a03-a71e-466e768f448b" />
## Steps to reproduce
1. Install MRP Subcontracting (`mrp_subcontracting`) and Purchase (`purchase`)
2. In Settings, enable *Subcontracting*
3. Create a Product P and a subcontracting BoM with Subcontractor S
4. Create a Request for Quotation
- Vendor: Subcontractor S
- Product: Product P (any quantity > 0)
5. Confirm the RFQ, receive the PO, validate the picking
6. On the validated picking, click *Return*, set the quantity of products to return, and click *Return for Exchange*
- This creates two new pickings, one to return the product(s) we received, and one to receive new products
7. Validate the two new pickings
8. **In Inventory > Reporting > Moves History, the very last `stock.move.line` has the same location in the *From* (`location_id`) and the *To* (`location_dest_id`) columns**
## Cause
The `location_dest_id` of the new `stock.move` is updated in `StockReturnPickingLine._prepare_move_default_values`.
https://github.com/odoo/odoo/blob/fb534f1eadcb8ef74e2ee6fd5b68872dddb978e3/addons/mrp_subcontracting/wizard/stock_picking_return.py#L20-L25
The condition added by https://github.com/odoo/odoo/commit/5404b426aac9 sets the destination of all returned subcontracted moves to the subcontractor location. This is incorrect when using "return for exchange", as in this case, the return move is directed towards the user's stock. In fact, when using "return for exchange", the following pickings are created:
| id | name | return_id | |
|:--:|--------------|:---------:|---|
| 1 | WH/IN/00001 | | Initial RFQ delivery |
| 2 | WH/OUT/00001 | 1 | Return of the initial RFQ delivery |
| 3 | WH/IN/00002 | 2 | New products delivery to replace the initial delivery. The stock.move.line of this stock.picking has a wrong `location_dest_id` |
## Fix
In the context of return for exchanges, the returned item must be directed to the *Subcontracting Location* while the new item must be directed to the *Stock*. In the `_prepare_move_default_values`, we should only set the `location_dest_it` to the subcontractor location for outgoing pickings.
opw-5479900This update resolves an issue where users accessing bank reconciliation within a child company were encountering access errors. The fix involves using 'sudo' to ensure the correct currency ID is retrieved, allowing proper bank reconciliation functionality within the child company environment. This improves usability for users working with multiple company structures.
Original PR description
The bug is easy to reproduce, but niche. 1. Have a company set up with a child company 2. Have a non admin user with administration rights for accounting 3. Create a bank statement in a journal with no set currency_id and fully reconcile it 4. While only in the child company, try to access the bank reconciliation widget -> access error The error occurs because of how journal_currency_id is computed on the bank rec widget. The fallback value for the currency is derived from the journal_id.company_id.currency_id which is inaccessible from the child company. To circumvent this, we just add sudo() to the call. Forward-Port-Of: odoo/enterprise#117005
This update ensures Odoo's audit trail feature in India (l10n_in) remains active, complying with Ministry of Corporate Affairs regulations. Previously, the audit trail could be disabled, but this change permanently enforces its maintenance to meet legal requirements. This ensures data integrity and reduces potential compliance risks.
Original PR description
After the refactor introduced in https://github.com/odoo/odoo/commit/f280f762b6417fa1a0b09649ffbdecafcc7e7579, The audit trail feature was split into two modes: a lightweight general-purpose mode and a force-restricted mode for specific localizations (e.g., Germany), where deactivation is not allowed once enabled. In India, as per the requirements of the Ministry of Corporate Affairs, the audit trail must be maintained and cannot be disabled once activated. This commit extends the force-restricted audit trail mode to the Indian localization (l10n_in) to ensure compliance with statutory requirements. task-6182002
This update fixes an issue where tax calculations were incorrect after removing a tax line on a sales order or invoice. The fix ensures that dependent taxes (those affected by the base amount) are properly recalculated, preventing inaccurate tax amounts. This improves the reliability of financial reporting.
Original PR description
**Steps to reproduce:** * Install the *Accounting* module with French localization (*l10n_fr_account*). * Create a *Sales Tax* with: * A new tax group (e.g., 'Codifab'). * Enable *Affect Base of…
**Steps to reproduce:** * Install the *Accounting* module with French localization (*l10n_fr_account*). * Create a *Sales Tax* with: * A new tax group (e.g., 'Codifab'). * Enable *Affect Base of Subsequent Taxes*. * Create a *Sales Order*: * Add the first tax (with *Affect Base of Subsequent Taxes*). * Then add the second tax (eg VAT tax). * Confirm the *Sales Order*. * Create a *Down Payment Invoice* (percentage-based). * Open the generated invoice and: * Remove the first tax (the one affecting the base). **Observed behavior:** * The amount of the second tax group does not update after removing the first tax, leading to incorrect tax computation. **Cause:** * In `_import_base_line_extra_tax_data`, the condition: `all(str(tax.id) in extra_tax_data['manual_tax_amounts'] for tax in sorted_taxes)` only ensured partial matching of taxes. * This allowed reuse of stale `manual_tax_amounts` when taxes were removed or modified, causing incorrect base values for dependent taxes (e.g., *Affect Base of Subsequent Taxes*). **Fix:** * Update the condition to enforce an exact match between current taxes and cached `manual_tax_amounts` by checking both size and membership. * Prevent reuse of outdated tax data when taxes change, ensuring proper recomputation of dependent taxes. * Align Python logic with the JS implementation for consistency between `account_tax.py` and `account_tax.js`. opw-6063970
This update resolves an issue that prevented the final invoice from being correctly sent to ZATCA when down payments had been reversed. The fix ensures that the system properly handles both reversed and non-reversed down payment invoices, preventing a critical error. This improves the reliability of ZATCA invoice generation for SA companies.
Original PR description
Sending the final invoice of a sale order to ZATCA crashed with `ValueError: Expected singleton: account.move(a, b)` when the sale order had multiple down-payment references. Steps to reproduce: 1.…
Sending the final invoice of a sale order to ZATCA crashed with `ValueError: Expected singleton: account.move(a, b)` when the sale order had multiple down-payment references. Steps to reproduce: 1. Configure a SA company and setup ZATCA 2. Create a sale order and confirm it 3. Deliver the product line. 3. From the sale order, create a down-payment invoice (fixed amount, e.g. 115) and post it (DP1). 4. On DP1, click "Credit Note" and choose "Full refund and new draft invoice"; validate. DP1 becomes `reversed` and a new draft down-payment DP2 is created. Post DP2. 5. From the sale order, create the final regular invoice and post it. 6. Send the final invoice to ZATCA (or generate its XML) -> `ValueError: Expected singleton: account.move(a, b)`. Root cause: _l10n_sa_get_line_prepayment_vals looks up the related down-payment move through the down-payment sale order line shared with the product line. The filter matched any out_invoice with _is_downpayment() == True, so the reversed DP1 and the active DP2 both ended up in the recordset, and reading .name raised the singleton error. Prefer non-reversed down-payment moves when available, but fall back to reversed ones if no alternative exists (e.g. when generating a credit note of the final invoice after the original down-payment was itself reversed). opw-6116265 Forward-Port-Of: odoo/odoo#260980 Forward-Port-Of: odoo/odoo#259384
This update fixes an issue where CodaBox statements were sometimes incorrectly routed to the wrong bank journal due to currency differences. The system now prioritizes journals with specified currencies, ensuring statements are accurately assigned to the correct currency account. This improves the reliability of financial data imported from CodaBox.
Original PR description
When several journals share the same IBAN but use different currencies, a CODA could land on the wrong journal instead of the currency-specific one. Split the lookup in two passes: first a journal with an explicit currency_id matching the CODA, then fall back to the no-currency journal (qualified by the company currency). Steps to reproduce: - Create 2 bank journals sharing the same IBAN; one without currency and one with USD. - Setup CodaBox connection and retrieve USD statements. - Before this fix: may land on the EUR journal. opw-6048931 Forward-Port-Of: odoo/enterprise#116228 Forward-Port-Of: odoo/enterprise#114590