Daily updates from Odoo
Monday, May 11, 2026
16 changes · 18.0
Resolved issues and error corrections
This update fixes an issue where the cost of service sale order lines wasn't being calculated correctly. The change ensures that the product's cost is accurately applied when a new sale order line is added to a confirmed order, regardless of whether timesheets are associated or the product has a standard price.
Original PR description
Steps to reproduce: --------------------------------------- 1. Install the `sale_timesheet_margin` module 2. Create a product as follows: * Type: Service * Invoicing Policy: Prepaid/Fixed Price *…
Steps to reproduce:
---------------------------------------
1. Install the `sale_timesheet_margin` module
2. Create a product as follows:
* Type: Service
* Invoicing Policy: Prepaid/Fixed Price
* Create on order: Nothing
* Cost: Add some cost to the product (e.g., 30)
3. Create and Confirm Sale Order with Product (Add Cost field in SOL from the optional field)
4. Now add a new Sales Order Line (SOL) with the same product
Observation:
---------------------------------------
The cost of the recently created Sales Order Line (SOL) is 0.0, which is not correctly calculated based on the product's cost.
Issue:
---------------------------------------
The `_compute_purchase_price` method has a filter (`service_non_timesheet_sols`) that excludes certain sale order lines from the parent's purchase price computation. When a new sale order line is added to an already confirmed sale order (state='sale'), the new line inherits the parent SO's state immediately. That means, the new line matches the filter criteria and gets excluded from parent computation. The `purchase_price` is never calculated from the product's `standard_price`
Solution:
---------------------------------------
The added condition, like EITHER:
1. Has timesheets recorded (`sol.timesheet_ids` is truthy) → Preserve existing cost
2. OR product has NO standard price (`not sol.product_id.standard_price`) → Use timesheet-based costing
Code intentionally skips the computation of `service_non_timesheet_sols` lines to preserve existing values
opw-5351724
Forward-Port-Of: odoo/odoo#253860This update improves the speed of exporting the general ledger to an Excel file. The previous process included unnecessary calculations, causing significant delays. The change optimizes the export process, resulting in a much faster export time – now around 22 seconds instead of over 900 seconds.
Original PR description
**Description:** In version 17, when we export the general ledger to an xls file, we now iterates over accounts fetched with `_get_accounts_with_move_lines` and perform a sum of the related amls balance, credit and debit. Source of this change: [103329](https://github.com/odoo/enterprise/pull/103329) Those sums are calculated through an SQL query built in `_get_query_sum`. However, it's currently inefficient because the query also computes the unaffected earnings of the company on each iteration, even though that information in only meant to be used if the account_type = 'equity_unaffected' in `_query_values`. **Benchmark:** | accounts | amls | before | after | |:---|:---|:---|:---| | 696 | 2819556 | >900s | 22.4s | **Reference:** opw-5904527 Forward-Port-Of: odoo/enterprise#112882
This update fixes an issue where the correct fiscal position (Domestic) wasn't being applied for sales transactions within the EU. The change ensures that VAT is correctly calculated based on the partner's location, regardless of their VAT prefix, improving accuracy for intra-EU business operations. This resolves a discrepancy in how VAT was being processed.
Original PR description
With l10n_nl: - Set the fiscal positions in this order: 1. Domestic 2. EU Intra B2B - Create a contact with: - German address - Dutch delivery address - Dutch VAT - Create a second contact with: - German address - Dutch delivery address - No VAT - Create a Sales Order for each contact: - For the first contact, the applied fiscal position is EU Intra B2B - For the second contact, the applied fiscal position is Domestic The detected fiscal position should be Domestic in both cases In _get_fiscal_position vat_exclusion is computed using the VAT prefix of the partner and our company. But if the prefix of the VAT does not match the country of the partner, it's delivery address will still be overriden. opw-5892138
This update optimizes the import process for Peppol documents, which often contain many lines. By caching frequently accessed tax and product information, the system avoids redundant searches, resulting in faster import times and reduced strain on the system. This enhancement improves the overall efficiency of the account management process.
Original PR description
When retreiving Peppol documents with many lines, the system was performing redundant ORM queries for taxes and products. Each line triggered individual searches even when the same tax or product had already been retrieved. To fix this, a cache dictionary is now passed along the import flow for both taxes and products. Each unique (tax_type, amount) pair and product (default_code, name, barcode, company) is only searched once per document. task-6018392 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves issues preventing Odoo's Norwegian VAT XML reports from passing validation by Skatteetaten. The changes ensure correct decimal formatting, mathematical calculations, and required legal notes are included, guaranteeing accurate VAT returns and avoiding delays.
Original PR description
Before commit: The Norwegian VAT XML export fails Skatteetaten validation due to incorrect decimal formatting, mathematical rounding mismatches between base and tax amounts, missing mandatory legal…
Before commit: The Norwegian VAT XML export fails Skatteetaten validation due to incorrect decimal formatting, mathematical rounding mismatches between base and tax amounts, missing mandatory legal notes, and invalid KID number formats. Fix: To strictly follow Skatteetaten validation rules for the Norway VAT XML, the following changes were implemented: - Ensured standard rates drop the decimal (e.g, `25.0` to `25`), and formatted fractional rates like `11.11` to `11,11` in XML. - Rounded down the `tax_amount` to align precisely with government mathematical expectations. - `base_amount` converted into absolute value to ensuring the calculation (`base * rate = tax`) resolves perfectly. - Add the mandatory `<merknad>` explaining the reverse charge method for codes 81, 83, 86, 88, and 91. - Clean the `company_kid` by safely stripping the 'NO' prefix, and 'MVA' suffix. Expect: The generated XML payload now adheres perfectly to Skatteetaten's strict structural and mathematical rules, allowing the VAT return to pass government validations successfully. Related Community PR: https://github.com/odoo/odoo/pull/258390 Task-6033027 Forward-Port-Of: odoo/enterprise#110792
This update fixes an issue where manufacturing costs were being double-counted in project profitability reports. The change ensures that only the primary manufacturing orders (source MOs) linked to a project are included in the calculations, providing a more accurate view of project costs. This improves the reliability of financial reporting for manufacturing projects.
Original PR description
Steps to reproduce: ==== - Install the project_mrp_account module. - Enable the 'Routes' and 'Replenish on Order' options in Inventory. - Create products with a multilevel MO. - Create a Sale Order…
Steps to reproduce: ==== - Install the project_mrp_account module. - Enable the 'Routes' and 'Replenish on Order' options in Inventory. - Create products with a multilevel MO. - Create a Sale Order that triggers Manufacturing Orders (MO), then validate it. - Go to the Project Dashboard and check the costs in the profitability section. Issue: ==== - Currently, the system sums the amount of all MOs without differentiating between source and child MOs. This results in double-counting of manufacturing costs in the profitability report. Cause: ==== - In 'account.analytic.line', the domain is only based on 'auto_account_id' and 'category'. There is no relation or differentiation between source and child MOs, so costs are aggregated incorrectly. Fix: ==== - We can filter out all the child MO's by checking out all MO's linked with that specific project. Only these source MOs are considered for cost calculation in the project profitability dashboard, avoiding duplication. Only these source MOs are considered for cost calculation in the project profitability dashboard, avoiding duplication. task-4969489
This update fixes an issue where manufacturing costs were being double-counted in project profitability reports. By removing the project association from child Manufacturing Orders, the system now accurately calculates costs, improving the reliability of project financial reporting. This change was implemented to align with a previous update in version 19.0.
Original PR description
**Steps to reproduce:** Install the project_mrp_account module. Enable the "Routes" and "Replenish on Order" options in Inventory. Create products with a multilevel Manufacturing Order (MO) flow. Create and confirm a Sales Order that triggers Manufacturing Orders, then validate it. **Current behavior:** The system sums the cost of all Manufacturing Orders without distinguishing between source and child MOs. As a result, manufacturing costs are double-counted in the project profitability report. **Fix:** Remove the project from child MOs to avoid double-counting in the project dashboard and MRP analytic stat button. In 19.0, the project is also set on child MOs. https://github.com/odoo/odoo/commit/2713876dbc70d3984e584a9037a2206dcda4e84a task-4969489
This update prevents Odoo from incorrectly importing bank account details for sales invoices, which was causing errors related to company mismatches. The fix now restricts bank import to purchase documents (invoices), ensuring data accuracy and preventing disruptions to the accounting process.
Original PR description
# Description of the issue/feature this PR addresses: A recent change introduced by PR [#242365](https://github.com/odoo/odoo/pull/242365) removed a company guard when importing bank information…
# Description of the issue/feature this PR addresses: A recent change introduced by PR [#242365](https://github.com/odoo/odoo/pull/242365) removed a company guard when importing bank information from EDI documents. As a result, during Factur-X and UBL 2.0 imports, Odoo may attempt to create or link a bank account on the wrong partner, leading to company constraint errors when importing credit notes. This issue primarily affects outbound credit notes, where Odoo incorrectly tries to import the company’s own bank account as a partner bank. <img width="1195" height="915" alt="image" src="https://github.com/user-attachments/assets/b93d9ec4-8840-4e06-87ed-8590cfe9149d" /> # Current behavior before PR: During Factur-X and UBL 2.0 imports: - Bank information extracted from the XML is always passed to _import_partner_bank, regardless of the document type. - For sales documents (out_invoice, out_refund), the bank account in the XML belongs to the company itself. - Odoo then attempts to create or assign this bank account to the partner, triggering an error such as: > Incompatible companies on records: Invoice belongs to company A, bank account belongs to another company. - Vendor invoices (in_invoice) work by chance, but the logic is incorrect and fragile. - The behavior is inconsistent with how Factur-X and UBL define PayeePartyCreditorFinancialAccount (always the seller’s bank). # Desired behavior after PR is merged: Bank details are imported only for purchase documents (in_invoice, in_refund), where the seller is the vendor and importing their bank account is correct. - For sales documents (out_invoice, out_refund), the import of bank details is skipped, avoiding: - Incorrect partner bank creation - Company constraint errors - This behavior is implemented consistently for: Factur-X imports, UBL 2.0 imports The fix uses invoice.is_purchase_document() ensuring: - Vendor bank details continue to be imported correctly - No regression for existing Factur-X vendor invoice flows - Credit note imports behave correctly again Odoo-ticket: [5877901](https://www.odoo.com/my/tasks/5877901) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves a bug preventing Odoo invoices with a specific tax category ('O-service out of tax scope') from passing Peppol validation. The fix ensures this category doesn't include VAT IDs, aligning with Peppol requirements. This ensures compliance and proper export of invoices to Peppol networks.
Original PR description
**PROBLEM** In peppol, there is a tax category 'O-service out of tax scope'. This tax category is used when what is invoice can't be tax (out of the tax scope). This is different from tax exemption: when using tax category O, there can't be any vat id on the invoice. This also means you can't use tax category O with other taxes, since other taxes need the vat id. Invoices generated by odoo with tax category O failed peppol validation. **STEP TO REPRODUCE** 1. install account_edi_ubl_cii_tax_extension. 2. Create a tax with tax category O. 3. Create an invoice and try validating using the file validator. 4. You should have error BR-O-02 and BR-O-05. opw-6012669
This update fixes a crash that occurred when creating purchase invoices with vendor bills that only used a description and UoM, without a product assigned. The change ensures purchase matching is more robust and can handle bills identified solely by their description, improving data accuracy and preventing errors during invoice creation.
Original PR description
### Issue before this commit: Opening the Purchase Matching wizard would crash if the vendor bill contained lines with a description and a Unit of Measure (UoM), but no product selected. ### Steps to…
### Issue before this commit: Opening the Purchase Matching wizard would crash if the vendor bill contained lines with a description and a Unit of Measure (UoM), but no product selected. ### Steps to reproduce the issue: 1. Enable Units of Measure in Settings 2. Create and confirm a Vendor Bill setting a description and a UoM, but leave the Product field empty. 3. Click on "Purchase matching" smart button 4. The system throws a traceback with the error: "The unit of measure Unit defined on the order line doesn't belong to the same category as the unit of measure False defined on the product." ### Cause of the issue: In the purchase.bill.line.match model, the field product_uom_qty was computed by calling _compute_quantity using line.product_uom_id. Since product_uom_id is a related field on product_id.uom_id, it returns False when no product is set. The UoM conversion logic cannot handle a False destination category, leading to the crash. ### Reason to introduce the fix: Make purchase matching robust when imported vendor bills contain lines identified only by their description and not by a product. Note that for `purchase.bill.line.match` corresponding to an account.move.line but not related to any product, the `product_uom_qty` should match the quantity of the `aml_id` instead of attempting a UoM conversion based on a missing product UoM for the behavior to be consistent with the inverse method: https://github.com/odoo/odoo/blob/59d6232979b8499fde6cb700df1870e2e38d0d3e/addons/purchase/models/purchase_bill_line_match.py#L45-L54 opw-5911526 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves a crash that occurred when validating shared POS orders with loyalty discounts. The issue stemmed from how temporary discount IDs were handled during order serialization and validation, leading to a 'TypeError'. The fix ensures accurate loyalty point calculations and stable order validation across different POS configurations.
Original PR description
When a draft POS order saved by another session is loaded in a trusted POS, reward lines with an automatically applied discount cause a traceback. Steps to reproduce: ------------------- * In POS…
When a draft POS order saved by another session is loaded in a trusted POS, reward lines with an automatically applied discount cause a traceback. Steps to reproduce: ------------------- * In POS Settings, enable Trusted POS between two configs * Create an automatically applied discount on a product * In POS 1: add the product, select a customer, save the order for later * In POS 2 (trusted): open the saved order, select a payment method and validate > Observation: TypeError: Cannot read properties of undefined (reading 'id') Why the fix: ------------ When POS 1 serializes the draft order, temporary negative coupon IDs on reward lines are stripped to `undefined` (pos_order_line.js serialize()). When POS 2 loads the order and tries to validate it, several code paths access `.id` directly on `coupon_id` without guarding against `undefined`: Additionally, `updateRewards()` keeps the stale reward line while the auto-claim creates a fresh one, so the order briefly holds two discount lines. The second `orderUpdateLoyaltyPrograms()` then computes loyalty points against both lines, producing a wrong result. Fixed by deleting stale reward lines (coupon_id = undefined) at the start of `updateRewardsMutex.exec()` so the auto-claim creates a single correct line. opw-6049469
This update ensures event tickets are created correctly when selling event tickets in POS while offline. Previously, a page reload would cause the system to lose the event registration data. The fix changes how the system manages local data storage, guaranteeing that event tickets are generated when an offline order is synced with the server.
Original PR description
When selling event tickets in POS while offline, the order could be synced later but without creating event registrations (tickets) after a page reload. Steps to reproduce: ------------------- * Open…
When selling event tickets in POS while offline, the order could be synced later but without creating event registrations (tickets) after a page reload. Steps to reproduce: ------------------- * Open a POS session with `pos_event` * Sell an event ticket * Switch to offline mode * Validate payment while offline (order becomes paid but unsynced) * Reload/close and reopen POS, then reconnect * Let the order sync > Observation: The `pos.order` is created on the backend, but `event.registration` and `event.registration.answer` are missing so tickets are not generated. Why the fix: ------------ `pos_event` used `order.finalized` as IndexedDB cleanup condition for `event.registration` and `event.registration.answer`. For paid-but-unsynced orders, `finalized` is already true, so those records can be removed from IndexedDB too early. After reload, the order is restored/synced but without its event registration payload. Implementation: --------------- Use `order.canBeRemovedFromIndexedDB` instead of `order.finalized` for `event.registration` and `event.registration.answer` retention rules, so records are kept locally until the order is truly synced (server id assigned) or canceled. Test Note: --------------- Use case is hard to simulate exactly. Add a basic unit test to assert both registration models are kept for paid unsynced orders and only removable once synced. opw-6056079
This update resolves an issue where custom (free text) product attributes weren't correctly displayed in the POS system when settling website orders. The fix ensures that customer-entered text is accurately reflected in the order line, improving the customer experience and order accuracy. It corrects a data retrieval problem within the Odoo POS module.
Original PR description
When a sale order containing a product with a custom (free text) attribute was settled in POS, the order line displayed the placeholder attribute value name (e.g. "Custom") instead of the actual text…
When a sale order containing a product with a custom (free text) attribute was settled in POS, the order line displayed the placeholder attribute value name (e.g. "Custom") instead of the actual text entered by the customer. Steps to reproduce: ------------------- * Create a product with a free text attribute (create_variant='no_variant', is_custom=True) * Go to the website's shop (works best in a new private tab) * Fill the free text attribute and add the product to the cart * Click on checkout * In POS, open Quotation/Order and settle the order > Observation: the order line shows "Custom" instead of the text Why the fix: ------------ `SaleOrderLine._load_pos_data_fields` was not exposing `product_no_variant_attribute_value_ids` nor `product_custom_attribute_value_ids`, so the JS `settleSO` function received no attribute data on the `line` object. As a result, the new POS order line was created with empty `attribute_value_ids` and `custom_attribute_value_ids`, leaving `constructFullProductName` unable to find the custom text. The fix adds both fields to `_load_pos_data_fields` and updates `settleSO` to use them when building the new POS order line. The dynamic fetch path (`_getSaleOrder`) is also updated to explicitly read the `product.attribute.custom.value` records so the data is available for orders loaded at runtime. opw-5958678
This update fixes an issue where prepaid tax calculations were inaccurate due to rounding errors. The change ensures correct global rounding is applied during tax calculations for Saudi Arabia, preventing discrepancies in invoice amounts. This improves the accuracy of financial reporting.
Original PR description
### Steps to reproduce: - Download 'Sales', 'Accounting', and 'l10n_sa_edi' modules - Settings > Accounting > Rounding Method > Enable global rounding - Create sale order with 8 lines at 29.7 each…
### Steps to reproduce: - Download 'Sales', 'Accounting', and 'l10n_sa_edi' modules - Settings > Accounting > Rounding Method > Enable global rounding - Create sale order with 8 lines at 29.7 each with 15% taxes (triggers rounding precision issues) - Create and confirm 100% downpayment invoice - Deliver, then create final invoice with downpayment lines - Call `_l10n_sa_get_prepaid_amount()` on final invoice > Tax amount was calculated as 35.67 instead of correct 35.64 ### Cause of Issue: The prepaid amount calculation was summing pre-rounded `tax_amount_currency` values from individual downpayment lines (4.45 + 4.46 + 4.46... = 35.67), instead of summing unrounded `raw_tax_amount_currency` values (4.455 × 8 = 35.64) to calculate `tax_amount`. https://github.com/odoo/odoo/blob/27930ae41a5f03bd499983109de7f632472c3650/addons/l10n_sa_edi/models/account_edi_xml_ubl_21_zatca.py#L227-L240 This violates Odoo's [recent change](https://github.com/odoo/odoo/pull/180062) in `round_globally` pattern which states: https://github.com/odoo/odoo/blob/8a88756bed194910bc5a47e93f0e29610dbeee1f/addons/account/models/account_tax.py#L2208 ### Fix: Ensure cumulative rounding errors are avoided and correct global rounding is applied. opw-5881564
This update resolves a problem where custom attributes weren't selectable in kiosk mode, causing the attribute heading to appear but not the options. The fix ensures that custom attributes are correctly hidden when a single value is selected, and the 'Add to Cart' button functions properly. This improves the kiosk user experience.
Original PR description
Step to reproduce: - have two attributes A and B - A has only 1 attribute value with is_custom = True - B can have any two value ( ex. gender: male/female) - use it on a product and make it available…
Step to reproduce: - have two attributes A and B - A has only 1 attribute value with is_custom = True - B can have any two value ( ex. gender: male/female) - use it on a product and make it available in POS for kiosk - start kiosk and open that product Observation: - we do not get option to select option from A but the heading is visible - when we select from B, Add to cart is disabled. Cause: - we do not allow attribute values with is_custom = True in kiosk - but we display the attribute regardless - the Add to cart btn depends on `selectedValues`, which requires value from each attribute, in this case, we are not seletion anything from A - so it is disabled Fix: - we introduced `attributesToDisplay` which will hide heading in case of single custom value for any attribute - for Add to cart, wenow do not expect value from `is_custom` attribute values. Before: <img width="1834" height="854" alt="image" src="https://github.com/user-attachments/assets/ae0d6d91-c3b6-47e9-8c08-f55efc6e0a33" /> After: <img width="1830" height="828" alt="image" src="https://github.com/user-attachments/assets/7e2376b6-4704-4039-9db0-0b0bf822c33d" /> opw-6100965 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves a bug where invoices created from timesheeted sales orders incorrectly displayed product quantities. The fix ensures that invoiceable quantities are recalculated each time an invoice is created, regardless of provided dates, resulting in accurate invoicing for service-based sales.
Original PR description
Steps --------- 1. Install Accounting, Sale and Timesheet 2. Create 2 product a. Product A - storable - invoiced on Ordered Quantity b. Product B - service - create a task on order - invoice on…
Steps
---------
1. Install Accounting, Sale and Timesheet
2. Create 2 product
a. Product A - storable - invoiced on Ordered Quantity
b. Product B - service - create a task on order - invoice on
timesheeted
3. Create an SO with 3 product A and 3 product B
4. Add a timesheet line for 1 hour of product A - can be done thanks to
the button appearing on the SO at confirmation
5. Create Invoice
6. Don't add dates to the wizard and confirm -> Both product appear
7. Add date range that do NOT include the timesheeted lines -> Only the
storable product appear
8. Repeat step 6 -> Only the storable product appear
Problem
---------
During the creation of the invoice, the invoiceable lines would get
computed dates where provided to the wizard
(`sale.order.line.qty_to_invoice`). When no dates were provided, we
would not manually trigger the invoiceable lines recomputation and were
relying one the data store in cache.
Solution
---------
Force the invoiceable quantity recomputation upon each invoice creation.
opw-6001094
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr