Friday, January 9, 2026
14 changes · saas-18.4
Resolved issues and error corrections
This fix prevents invoices from being confirmed when their accounting lines still reference accounts from another company after the invoice company is changed. It helps avoid incorrect cross-company postings and keeps financial records aligned with the selected company and journal.
Original PR description
This issue was already fixed in this PR: https://github.com/odoo/odoo/pull/234357 But that was revert because there was a bug with company branches ### Steps to reproduce: - Create Company A and Company B - Create an invoice on Company A with one line having an account in Company A - On the same invoice, change the company to Company B and change the journal to a journal of Company B - Save, then confirm the invoice. ### Issue: The invoice, now belonging to Company B, still has the same account from company A, and we are able to post it on the journal from company B opw-5167958 Forward-Port-Of: odoo/odoo#242708 Forward-Port-Of: odoo/odoo#242239
Account balances now include transactions from child branches when viewed from a parent company. This gives businesses using branch hierarchies a more accurate consolidated view and prevents balances from appearing lower than expected.
Original PR description
Description of the issue/feature this PR addresses: This PR updates the company filtering logic in account balance computations to support Odoo's branch hierarchy. In multi-branch environments, a…
Description of the issue/feature this PR addresses:
This PR updates the company filtering logic in account balance computations to support Odoo's branch hierarchy. In multi-branch environments, a parent company should be able to see the aggregated balances of its child branches. Currently, the strict equality operator prevents this consolidation, creating a discrepancy between the expected "Global" view and the displayed balance.
Current behavior before PR:
The _compute_current_balance method in account_account.py uses the = operator for the company_id domain: domain=[('account_id', 'in', self.ids), ..., ('company_id', '=', self.env.company.id)]
This restricts the balance calculation exclusively to the current active company, excluding any transactions made in its branches (child companies), even when the user is positioned at the parent level.
Desired behavior after PR is merged:
The operator is changed to child_of. When a user is in a parent company/branch, the current_balance of the account will include the sum of all journal entries from that company and all its descendants in the hierarchy. This ensures consistency with how other parts of Odoo (like https://github.com/odoo/enterprise/blob/e29aadef1a81c662d9a4d33879b440dbe4390c0b/account_followup/models/res_partner.py#L230) handle company-related domains.
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#242576Company-paid expenses now keep their accounting entries balanced when an analytic account is changed. This avoids incorrect debit amounts and unwanted automatic balancing lines, helping expense reports stay accurate without manual correction.
Original PR description
Changing the analytic account on the journal entry generated by a company-paid expense creates an unwanted auto-balancing line. ## Steps to reproduce 1. Create an expense paid by the company. 2.…
Changing the analytic account on the journal entry generated by a company-paid expense creates an unwanted auto-balancing line. ## Steps to reproduce 1. Create an expense paid by the company. 2. Confirm and generate the expense report. 3. Reset the expense’s journal entry to draft and add an analytic account on the first line. → An auto-balancing line is added to the entry, and the remaining lines are incorrectly debited. ## Cause For company-paid expenses, the generated journal entry represents a *payment* rather than an *invoice*. In `_prepare_product_base_line_for_taxes_computation`, this causes the method to use `product_line_amount_currency` as the price unit, which excludes taxes. However, in `hr_expense`, the same method always defines `special_mode['total_included'] = False`. This combination leads `_get_tax_details` to call `_eval_tax_amount_price_included` instead of `_eval_tax_amount_price_excluded`, reapplying the tax on the lines. As a result, the move becomes unbalanced and Odoo generates an auto-balancing line to compensate. ## Solution Keep the special mode as *total excluded* for payments generated by company-paid expenses, since their tax and product lines are already handled separately in the corresponding `account.move`. **opw-5166707** --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#241545 Forward-Port-Of: odoo/odoo#233841
Cancelling a remaining manufacturing backorder no longer cancels warehouse transfers tied to quantities that were already produced. This prevents completed production flows from being disrupted and keeps stock movements accurate in multi-step manufacturing routes.
Original PR description
Issue ----- For multi step routes, cancelling the backorder MO also cancels the (post -> stock) picking for the produced quantity. Steps to reproduce ----- - Activate routes - Go to the main warehouse and activate 3 step production - Creation of a MO for 100 units - Validate the pre production picking - Produce 40 units and create a backorder for remaining quantity - Cancel the backorder > The "post -> stock" picking is cancelled as well Cause ----- The picking is in "ready" state, so it gets cancelled by https://github.com/odoo/odoo/blob/083d53c688a0d18a1f4594b9fcbbfa738aa5e86d/addons/mrp/models/mrp_production.py#L1743-L1744 Desired behaviour ----- > Only cancel related MO pickings (pre prod/post prod) if no MO (or MOs) done yet. Don't cancel related MO pickings if any MO validated. ----- Ticket: opw-5405024 Forward-Port-Of: odoo/odoo#239865
Peruvian purchase invoices and credit notes now keep the displayed document number aligned with the stored invoice reference after automatic formatting. This prevents mismatched vendor invoice numbers in records and reports, reducing confusion during accounting checks.
Original PR description
When creating or editing Peruvian purchase invoices/credit notes, the l10n_latam_document_number field is formatted with zfill(8) (e.g., "F01-100" becomes "F01-00000100"), but the name field was not…
When creating or editing Peruvian purchase invoices/credit notes, the l10n_latam_document_number field is formatted with zfill(8) (e.g., "F01-100" becomes "F01-00000100"), but the name field was not synchronized, causing data inconsistencies between these fields. Steps to reproduce: 1. Create a purchase invoice for a Peruvian company 2. Select a document type (Factura, Boleta, or Credit/Debit Note) 3. Enter a document number like "F01-100" 4. Save the record 5. Observe that l10n_latam_document_number shows "F01-00000100" but name field may show a different format This fix ensures that after formatting the document number, the name field is synchronized with the correctly formatted value, preventing inconsistencies in vendor invoices and reports. 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#241948
This fix ensures flexible work calendars only use working time that falls within the requested scheduling window. It prevents shop floor work orders from failing with a validation error when started later in the day, improving reliability for manufacturing scheduling.
Original PR description
**Steps to reproduce** On a local DB, with demo data: - Change your machine's time to a late part of the day (e.g. 6pm) - Install `mrp_workorder` - Set the "Standard 40 hours/week" (used by a…
**Steps to reproduce** On a local DB, with demo data: - Change your machine's time to a late part of the day (e.g. 6pm) - Install `mrp_workorder` - Set the "Standard 40 hours/week" (used by a workcenter) as flexible. - From the Shop Floor, start the "WH/MO/00003 - Manual Assembly" workorder. "Validation Error: The start date of the time off must be earlier than the end date." **Cause** `_calculate_date_finished` in mrp is calling `plan_hours` and under certain conditions with a flexible resource, it is possible for `plan_hours` to return a datetime before the `day_dt` parameter. This happens because for flexible resources, `_attendance_intervals_batch` can return attendance intervals with start or end datetimes outside of the start_dt -> end_dt window. For example, a flexible calendar with 8h/day will return the 8:00->16:00 interval, even if start_dt is later than 8:00. **Change** Don't return attendance intervals outside of the [start_dt, end_dt] interval by shifting them if necessary. opw-5123230 Forward-Port-Of: odoo/odoo#233169
The Manufacturing delayed productions filter has been updated so users can search manufacturing orders without warnings or crashes. This keeps the filter working as expected and prevents disruption when reviewing late production work.
Original PR description
Issue before this commit: ========================= Searching for Delayed Productions in the MRP list view triggered: - A deprecation warning in saas-18.4 → 19.0: `warnings.warn("Since 19.0, use…
Issue before this commit:
=========================
Searching for Delayed Productions in the MRP list view triggered:
- A deprecation warning in saas-18.4 → 19.0:
`warnings.warn("Since 19.0, use Domain.custom(to_sql=lambda model, alias, query: SQL(...))", DeprecationWarning)`
- A traceback in master:
`Failed to cast TableSQL('mrp_production', -, None).date_finished into a datetime`
Steps to Reproduce:
=========================
- Install mrp module.
- Open the Manufacturing Orders list view.
- Filter by Delayed Productions.
- Observe the warning (saas-18.4 → 19.0) or traceback (master).
Cause of the issue:
=========================
Recent ORM changes in [PR](https://github.com/odoo/odoo/commit/f811af2c52df798b6ba0fc18e3f45944abdb7a12) disallow using raw SQL expressions as values inside normal domains.
Only Domain.custom() is permitted for injecting custom SQL.
The previous _search_is_delayed implementation used a deprecated pattern,
which caused the warning in current versions and a crash in the master version.
With This Commit:
=========================
- Rewrite the delayed production filter using Domain.custom() to safely generate the SQL.
- Preserve functional behaviour: the filter still returns delayed productions correctly.
- Avoid deprecation warnings and prevent traceback.
TaskID:- 5404547Peppol invoice exports with cash rounding now avoid adding an invalid tax breakdown line. This helps Belgian invoices with rounding pass electronic invoicing validation and be sent successfully.
Original PR description
Issue: A TaxSubtotal node was blocking the XML validation for peppol invoices with Cash Rounding Step to reproduce: 1. Select BE Company CoA 2. Enable Cash Rounding in the settings 3. Create a cash…
Issue: A TaxSubtotal node was blocking the XML validation for peppol invoices with Cash Rounding Step to reproduce: 1. Select BE Company CoA 2. Enable Cash Rounding in the settings 3. Create a cash rounding method (in the settings where cash rounding can be enabled): - precision `1.00` - strategy: Add a rounding line - profit / loss account: any 4. Create an invoice - Set a Belgian partner (e.g. "BE Company CoA" is okay) - Set the cash rounding method from step 2 - Single Line with price=70.00€ and a 21% tax 5. The total should be 85.00 € (84.70 € w/o the rounding) In the journal items there should be the following non-payment term items: - 70.00€ base - 14.70€ tax - 0.30€ rounding 6. Confirm & Send (with PEPPOL) Current Behavior: Look at the UBL BIS 3 XML in the `Invoice` element - `TaxTotal/TaxAmount`: 14.70€ - `TaxTotal/TaxSubtotal/TaxableAmount`: 70.00€ - `TaxTotal/TaxSubtotal/TaxAmount`: 14.70€ - `TaxTotal/TaxSubtotal/TaxableAmount`: 0.30€ - `TaxTotal/TaxSubtotal/TaxAmount`: 00.00€ - `TaxTotal/TaxSubtotal/TaxCategory/TaxExemptionReason`: "Exempt from tax" - `LegalMonetaryTotal/TaxExclusiveAmount`: 70.00€ - `LegalMonetaryTotal/TaxInclusiveAmount`: 84.70€ - `LegalMonetaryTotal/PayableRoundingAmount`: 00.30€ - `LegalMonetaryTotal/PayableAmount`: 85.00€ This fails validation `BR-E-08`: "In a VAT breakdown (BG-23) where the VAT category code (BT-118) is "Exempt from VAT" the VAT category taxable amount BT-116 [is equal to: `BT-116 = sum(BT-131) - sum(BT-92) + sum(BT-99)` i.e. `VAT category taxable amount = Invoice net - allowance + charge`] where all the VAT category codes (BT-151, BT-95, BT-102) are "Exempt from VAT"" Expected behavior: Look at the UBL BIS 3 XML in the `Invoice` element - `TaxTotal/TaxAmount`: 14.70€ - `TaxTotal/TaxSubtotal/TaxableAmount`: 70.00€ - `TaxTotal/TaxSubtotal/TaxAmount`: 14.70€ - `LegalMonetaryTotal/TaxExclusiveAmount`: 70.00€ - `LegalMonetaryTotal/TaxInclusiveAmount`: 84.70€ - `LegalMonetaryTotal/PayableRoundingAmount`: 00.30€ - `LegalMonetaryTotal/PayableAmount`: 85.00€ Solution: Per the calculation of the VAT category taxable amount (BT-116). There should have a TaxSubtotal for tax Category having invoice lines. https://docs.peppol.eu/poacc/billing/3.0/bis/#_calculation_of_totals As invoice lines should contain their item name. Rounding line won't have one. https://docs.peppol.eu/poacc/billing/3.0/rules/ubl-tc434/BR-25/ As rounding appear in the LegalMonetaryTotal, removing the related TaxSubtotal doesn't remove information. https://docs.peppol.eu/poacc/billing/3.0/bis/#_element_for_rounding_amount_the_payableroundingamount Rounding base_lines are removed from `vals['base_lines']` as they need to have a product label. https://github.com/odoo/odoo/blob/366d7122ee30e16c157d026363b731c066a564c5/addons/account_edi_ubl_cii/models/account_edi_xml_ubl_bis3.py#L305-L310 As `_ubl_add_values_payable_rounding_amount` needs rounding lines within base_lines and `_ubl_add_values_tax_totals` shouldn't have them, this commit exchanges their processing order. This commit also: - fix the test file `test_invoice_cash_rounding_add_invoice_line.xml` as it failed the XML validation (BR-E-08). opw-5434335 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#241717
The employee timeline now saves pending payroll contract changes before a new employee version is created. This prevents contracts from being incorrectly created for future employee versions after a contract end date has been entered.
Original PR description
To reproduce: install hr_payroll open an employee form view > payroll make sure the employee_version you are on doesn't have a contract end date set the end date to X and without saving create a new employee version from the plus sign with date greater than X The Bug: when following the above flow a contract will be created for both employee versions it shouldn't be the case for the second version as version date is greater than contract end date opw-5427769 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Point of Sale device actions now keep their own response tracking when multiple requests are sent at the same time. This prevents one request from overwriting another, so users receive all expected confirmations from connected devices.
Original PR description
Instead of passing `session_id` in the device class parameters, we provide it directly in the response dictionary, in order to allow concurrent actions on the device. Before this commit: - send an action from a PoS: `session_id` is set to `1`, - before the end of the execution, send a second action from the same PoS on the same device (e.g. on another browser): `session_id` is updated to `2`, - you get only one confirmation in the PoS. After this commit: we get both confirmations.
Purchase orders created by a child company from a purchase agreement now correctly include applicable purchase taxes defined on the parent company. This prevents missing tax amounts on RFQs and purchase orders, improving tax accuracy for multi-company purchasing flows.
Original PR description
### Issue: In a child company, adding a product from a Purchase Agreement to a Purchase Order does not apply the associated parent company's purchase taxes ### Cause: In the onchange, taxes were filtered by company: ```python taxes_ids = fpos.map_tax(line.product_id.supplier_taxes_id.filtered(lambda tax: tax.company_id == requisition.company_id)).ids ``` This filter fails for taxes belonging to the parent company, so they were not applied on the child company purchase order ### Steps to reproduce: - Create a company branch and switch to it - Enable `Purchase Agreements` in Settings - Create a product with a Purchase Taxes (ex. 15%) - Create a Purchase Agreement for any vendor with this product - Create a RFQ for the vendor and add the agreement - Observe that the tax is not applied opw-5121243 Forward-Port-Of: odoo/odoo#242909 Forward-Port-Of: odoo/odoo#237114
Fixes a rounding issue where fully discounted sales orders could still show a small remaining VAT amount, such as $0.01. This ensures orders with a 100% discount correctly total to zero, improving invoice and order accuracy for customers using global tax rounding.
Original PR description
Versions -------- - 18.0+ Steps ----- 1. Set tax rounding to "Round Globally"; 2. create a 19.99% tax; 3. create a new sales order; 4. add a line with a $19.99 unit price & 19.99% tax; 5. add a second line with identical values; 6. apply a 100% global discount (-$38.98 subtotal, -$47.97 total). Issue ----- The order total is $0.01 due to VAT. Cause ----- The `_round_tax_details_tax_amounts` method distributes the "tax delta" across the tax details, but currently it only does this if there's a non-zero target tax amount. In our scenario, we have a $0.01 tax delta, but because our tax total is $0.00 due to the 100% discount, the delta doesn't get distributed, leading to the $0.01 difference not getting corrected. Solution -------- When deciding whether to distribute a tax delta, check the tax delta value instead of the target tax amount. opw-5345538 opw-5097907 Forward-Port-Of: odoo/odoo#242939 Forward-Port-Of: odoo/odoo#240633
This update resolves a problem where scanning barcodes on picking orders with kit product variants would cause errors. The fix ensures that packaging information is correctly captured during barcode scans, allowing for accurate tracking of kit components. This improves the reliability of the barcode scanning process for inventory management.
Original PR description
In the barcode application, scanning a picking order containing a kit product variant with packaging will raise a Traceback. ### Steps to reproduce: 1. Enable packagings on inventory configuration.…
In the barcode application, scanning a picking order containing a kit product variant with packaging will raise a Traceback. ### Steps to reproduce: 1. Enable packagings on inventory configuration. 2. Create a product, that as a least 2 variants. 3. Add a packaging to one of the variants. 4. Create a BoM for created product (kit type). 5. Create a picking order for the variant with packaging. 6. Print the picking operation to scan the code through barcode. 7. Go to barcode and try to scan it, this will trigger the traceback. ### Cause of the issue: Scaning a barcode will call get_barcode_data during this call it will retrieve the information about the picking order and call _get_stock_barcode_data: https://github.com/odoo/enterprise/blob/f2dd6326c2084ed467c3e4c3e9d931f41309ad79/stock_barcode/controllers/stock_barcode.py#L91 _get_stock_barcode_data will obtain the packaging methode for the products. https://github.com/odoo/enterprise/blob/f2dd6326c2084ed467c3e4c3e9d931f41309ad79/stock_barcode_mrp/models/stock_picking.py#L13-L16 since in our use case the product has variant the packaging information is not inside product_tmpl_id.packaging_ids and thereof it will not retrieve the packaging information. ### Fix: We don't need to use product_tmpl_id.packaging_ids because of its compute and set methods (and the fact that the product_variant_ids field is required), the product_tmpl_id.packaging_ids will always be included in the product_tmpl_id.product_variant_ids.packaging_ids: https://github.com/odoo/odoo/blob/eb88370e2fc1887e8c88dfd8dbeadce23bb7abe5/addons/product/models/product_template.py#L430-L441 our fix will allow for packaging in the variant to be considered when there is more than only one variant. opw-4852875 Forward-Port-Of: odoo/enterprise#103155 Forward-Port-Of: odoo/enterprise#87867
This update resolves a problem preventing connections to IAP Codaclean, which is a key integration for Belgian accounting. The issue was caused by a missing parameter in the system, now corrected to ensure seamless data exchange and proper functionality.
Original PR description
Connections to IAP Codaclean are failing because of missing `enterprise_number` param. no-task-id Forward-Port-Of: odoo/enterprise#103724