Daily updates from Odoo
Tuesday, May 26, 2026
23 changes · 18.0
Resolved issues and error corrections
This update fixes an issue where imported Peppol invoices with tax-included prices were incorrectly inflating unit prices when multiple quantities were imported. The fix ensures accurate tax calculations and correct unit pricing, preventing overcharging and improving data integrity during invoice imports. This impacts how tax is handled on imported invoices.
Original PR description
When importing a Peppol invoice with tax-included prices, the importer was incorrectly adding the total line tax to the per-unit price, which caused the price_unit to be inflated for quantities greater than 1. This fix computes the per-unit tax by dividing the total tax by quantity and restores the correct formula price_unit * (1 + rate). Step to reproduce: - Configure a company with "Tax-Included" Prices. - Receive a Peppo invoice from supplier A with a line named TEST, with quantity 1 and a tax. - Import the same invoice but with quantity 2. Expected behavior: The price_unit of the line TEST should be the same in both cases, and the total tax should be correctly computed as price_unit * quantity * tax_rate. Actual behavior: The price_unit of the line TEST with quantity 2 is inflated opw-6177504
This update resolves an issue where account consolidation reports would exclude accounts without a defined code on the selected company. Now, the system intelligently uses account codes from other companies within the consolidation to ensure accurate reporting and financial figures. This improves the reliability of consolidated reports.
Original PR description
When having an horizontal group with domain including two companies that
share the same account codes, report lines with account codes engine
don't display the two companies values when both are selected in the
company selector.
Steps to reproduce:
- Install l10n_ch and create two CH companies (CH1 and CH2)
- Create an horizontal group with the field 'Company' and domain '["|",
("name", "=", "CH Company"), ("name", "=", "CH 2")]"
- Apply the Horizontal group to CH balance sheet report
- Select both companies in the company selector
- Open CH BS report and activate the horizontal group
-> Only the column of one company is filled
Fix:
https://github.com/odoo/enterprise/commit/9b775ed9d8b2a18e708219c72e95652571f3936a
was introduced in 19.0 to fix the same issue, we fix by backporting it
but we also need to backport this perf commit https://github.com/odoo/enterprise/commit/7da3123dc4487a7092deef8503a9791ceffddcfb
that refactored the code before in a first place
opw-6204601This update fixes an issue where automatic check-out was incorrectly calculating overtime hours when employees took time off. By using a more accurate method for determining expected work hours, the system now correctly accounts for employee leave, breaks, and contracts, ensuring accurate overtime tracking. This improves the reliability of time tracking data.
Original PR description
# Steps to reproduce 1. Set the Working schedule 40h/week 2. Employee takes 2 hours off from 15:00 to 17:00 and enable automatic check-out 3. Odoo will automatically checks out at 17:06 (scheduled end + tolerance) # Issue - This leads to 2h06 of extra hours being incorrectly recorded. # Fix - Use employee._get_expected_attendances instead, so contract-aware calendar resolution, leaves, and break time handling stay centralized in HR. task-5052044 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an issue where Verifactu invoice generation failed after invoicing a Point of Sale order. The fix allows for successful invoice creation even when the order is already invoiced, ensuring consistent functionality with the original PoS invoice process. It streamlines the invoicing workflow for Spanish companies using Verifactu.
Original PR description
**Steps to reproduce:** - Setup a Verifactu installation and a Spanish company - Go to the PoS, make a Sale - Keep the ticket - Go to the /pos/ticket URL and enter the ticket informations - Last step…
**Steps to reproduce:** - Setup a Verifactu installation and a Spanish company - Go to the PoS, make a Sale - Keep the ticket - Go to the /pos/ticket URL and enter the ticket informations - Last step also works when requesting an invoice in the backend on the order - Go to the order in the backend, an error is shown, the cancellation didn't go through **Veri*Factu documents can only be generated for paid or posted Point of Sale Orders.** **Why the fix:** When we directly invoice an order, we do not go through the verification of being paid and done. This is why is works, but when making the invoice after the sale is done, we cancel the order first, then we register the invoice instead. When trying to cancel the order, we check if the order is either paid or done, but it is currently invoiced as we just generated the invoice. We now allow no errors if the order is in the invoiced state, and let it pass through. With this flow we get the same result as the direct invoice from the PoS. The new cancellation on the order and submission on the invoice may take a bit of time to get accepted but they will be eventually. opw-6139200
This update resolves a bug where double-clicking an image in the Media Dialog triggered multiple actions, leading to performance issues. A simple flag has been added to ensure that the media flow is only processed once during a single click event, improving the user experience.
Original PR description
Before this commit: When double-clicking an image in the Media Dialog, the onClickAttachment method was executed twice, causing the media flow to be processed multiple times. After this commit: The issue is fixed using a boolean flag: isProcessingClick. Initially, the flag is set to false. When the first click starts, it is updated to true. If another click occurs during the same flow (e.g during a double click), isProcessingClick is already true, so the function immediately returns and prevents the action from being executed multiple times. task-6033320
This update resolves an issue where error handling for API responses was failing due to inconsistencies in how the Requests library parses JSON data. By adjusting the error handling, the system now reliably catches and manages potential JSON parsing errors, ensuring smoother operation of Odoo's integrations.
Original PR description
The requests library uses different libraries to parse json objects depending on whether or not the simplejson library is installed (https://github.com/psf/requests/blob/dc9dbdfb3434c6e58d48fd102f93e5342308817e/src/requests/compat.py#L74). This in turn causes our try/excepts to fail if the simplejson library is installed in the env we simply re-raise the json error in case the simplejson library is installed so our try/excepts flows are not broken by the existence of a random package opw-6150349 Forward-Port-Of: odoo/odoo#264303
This update fixes a visual issue in the project Kanban view where status colors weren't rendering correctly due to a mismatch between the frontend and stylesheet. The fix ensures that project updates are displayed with the intended color codes, improving the user experience.
Original PR description
### The Issue: The frontend Kanban view enforces a strict 12-color limit using a modulo 12 mathematical rule (which calculates the remainder after dividing by 12). When the frontend receives our high backend IDs (20-24), it runs this modulo math (e.g., 23 % 12) to force them into the allowed limit, converting them into the remainders: IDs 8, 9, 10, 11 and 0. Because stylesheet was still searching for the original high numbers (20-24) instead of these modulo results, the custom colors were completely ignored by the browser. ### The Fix: Updated the stylesheet to target the actual modulo-computed classes (.oe_kanban_color_8 through 11 and 0). Mapped these classes to their correct variables (-success, -info, -warning, -danger, -primary) and fixed the left border styling so the colors render properly. task-6064106 Forward-Port-Of: odoo/odoo#256023
This update fixes a technical issue where Odoo experienced errors during Google Calendar synchronization when recurring events were modified with new attendees or start time changes. The fix prevents silent errors from appearing in server logs, ensuring smoother and more reliable synchronization of events between Odoo and Google Calendar. This improves the overall stability of the integration.
Original PR description
When a recurrence is updated in Google Calendar simultaneously with a new attendee and a changed start time, Odoo silently logs MissingError during the post-commit Google API callback Steps to reproduce: 1. Have a recurring event already synced between Odoo and Google Calendar 2. In Google Calendar, open the recurrence and edit "all events": - Add a new attendee - Change the start time 3. Trigger a Google Calendar sync 4. MissingError exceptions appear in server logs, one per event in the recurrence opw-6024835 Forward-Port-Of: odoo/odoo#265247
This update resolves an issue where foreign currency amounts in reports (Partner Ledger, General Ledger) weren't consistently displaying the currency code in the exported XLSX files. The fix ensures the 'Currency Code' column is always included after the 'amount_currency' column, regardless of the report generation method, improving report accuracy and clarity.
Original PR description
Step to reproduce: 1. Generate an invoice with a foreign currency (different from the company currency) 2. Go to ‘Partner Ledger’ or ‘General Ledger’ 3. Export the XLSX The bug happens because in the function _add_xlsx_currency_codes_columns we did not take into account dynamic lines. With this fix, a column ‘Currency Code’ will be added after the column ‘amount_currency’ if such column exists in the report, no matter the engine used to create the lines. opw-6150600
This update resolves an issue preventing users from correctly inserting dynamic fields within SMS templates in Marketing Automation. The fix ensures the system recognizes the correct data source (`mailing_model_real`) for Lead and Opportunity targets, allowing users to build more effective SMS campaigns. This improves the overall user experience and campaign effectiveness.
Original PR description
The SMS template form view in Marketing Automation was missing the `dynamic_placeholder_model_reference_field` option on the `body_plaintext` field. Without this option, the dynamic placeholder hook falls back to looking for a `model` field in the record data, but `mailing.mailing` uses `mailing_model_real` instead. Steps To Reproduce: - Install marketing_automation_sms and CRM modules (also activate Leads). - Start a new Campaign in Marketing Automation. - Set Target to Lead/Opportunity. - Add New Activity > Activity Type = SMS > SMS Template = create one. - In the SMS template dialog, click the "Insert Field" button. - Error appears: "You need to select a model before opening the dynamic placeholder selector." Ticket [link](https://www.odoo.com/odoo/project.task/5488849) opw-5488849
This update fixes an issue where the cursor position was incorrect after moving content within the HTML editor. Now, when moving a node (like a table), the cursor automatically adjusts to the start of the moved content, preserving selections within the moved node. This ensures a smoother and more intuitive editing experience.
Original PR description
#### Description of the issue/feature this PR addresses: - MoveNode restores the cursor at the container end position - After moving a table, the cursor ends outside the table body #### Desired behavior after PR is merged: - Preserve the selection if it was inside the moved node - Otherwise place the cursor at the start of the moved node #### Steps to reproduce: - Create a table in the editor - Move the table using Movenode - Drop the table and check the cursor position - The cursor ends outside the moved table body - Select some text in a paragraph - Move that paragraph using Movenode - The selection is placed at the end of the moved node task-6215743 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update corrects a bug where the default URL code for new languages didn't always align with existing configurations, causing errors during database upgrades. The fix ensures that if an ISO code conflicts with a pre-defined URL code, the system now uses the language's 'code' field as the default, preventing these errors and maintaining proper language setup.
Original PR description
Steps to reproduce the issue: 1. Create a fresh DB 2. Remove the language `base.lang_es` 3. Upgrade the `base` module This would throw an error because, when recreating the record, the default value for the `url_code` field is [taken from the `iso_code` field], which is `es` in this case. However, the `es` url_code is the value defined for `base.lang_es419` [here]. Proposed fix: When creating a new language, check if the `iso_code` would create a conflict with an existing `url_code`. If so, use the `code` field as default. [taken from the `iso_code` field]: https://github.com/odoo/odoo/blob/ed0d1bd21131920cb9c7b2ae69d7baedc2818e85/odoo/addons/base/models/res_lang.py#L337-342 [here]: https://github.com/odoo/odoo/blob/ed0d1bd21131920cb9c7b2ae69d7baedc2818e85/odoo/addons/base/data/res_lang_data.xml#L3
This update resolves inconsistencies in HTML parsing caused by recent updates to libxml2 and lxml. Specifically, it ensures consistent HTML output across different versions, improving the reliability of how Odoo renders web pages. This change also enhances error handling for type checking related to lxml and libxml2.
Original PR description
## [FIX] core: lxml compatibility v2.14.0+ (HTML parsing) In version 2.14.0, libxml2 fixed a long standing quirk in its HTML handling where it always implies `<p>` start tags [1]. As a result, there…
## [FIX] core: lxml compatibility v2.14.0+ (HTML parsing) In version 2.14.0, libxml2 fixed a long standing quirk in its HTML handling where it always implies `<p>` start tags [1]. As a result, there is a difference in behavior between pre and post 2.14.0 produced HTML when no start tag is provided: - pre: always has a `<p>` tag - post: depending on the case, could have either a `<span>` or `<p>` tag. This commit introduces a monkeypatch of the lxml's HTML parser when built with libxml2 2.14.0+ to maintain a similar behavior with older versions. [1]: https://gitlab.gnome.org/GNOME/libxml2/-/commit/8cf6129bbd836e666e7eda8c9e61c00387ae388b ## [FIX] base,l10n_it_edi: catch TypeError/ValueError for lxml 6+ compat Updates exception handling to account for stricter type checking introduced in lxml 5/6 and libxml2 2.12+. Note: Ubuntu 26.04 (Resolute) provides lxml 6.9.2/libxml2 2.15 while Debian Trixie has lxml 5.4.0/libxml2 2.9.14. Don't be fooled by the version `2.12.7+dfsg+really2.9.14-2.1+deb13u1` which actually means that Debian has reverted/held back the core engine to 2.9.14 while adding commits from 2.12.7. Forward-Port-Of: odoo/odoo#259348
This update resolves a critical issue where the SIE 4 report export crashed due to excessive memory usage. By optimizing the database query and leveraging efficient data processing techniques, the report now handles large datasets quickly and reliably, significantly improving performance. This ensures seamless reporting for users with extensive accounting data.
Original PR description
### Description of the issue/feature this PR addresses: Prevent Out of Memory (OOM) crashes and drastically improve execution speed when generating the Swedish SIE4 verification export for massive…
### Description of the issue/feature this PR addresses: Prevent Out of Memory (OOM) crashes and drastically improve execution speed when generating the Swedish SIE4 verification export for massive datasets. ### Current behavior before PR: When exporting a large volume of journal entries (e.g., 190,000+ account moves), the `_export_l10n_se_sie4_verification` method relies on iterating through heavy ORM recordsets and accessing relational child fields (move.line_ids) inside a loop. This triggers a severe N+1 query problem, maxing out server RAM and causing an OOM crash. ### Desired behavior after PR is merged: The method now utilizes a hybrid data extraction approach: - The ORM is used strictly to safely evaluate domains (multi-company rules, dates, states) and fetch a lightweight list of valid move_ids. - A single SQL query with JOIN statements fetches all parent moves, child lines, and account codes in exactly one database query. - itertools.groupby chunks the flat, lightweight dictionary results back into their respective journal entries. The export now handles massive datasets in seconds with minimal memory overhead, while remaining perfectly secure. ### Benchmark: For Memory: | # Input Data | Before PR | After PR | | -------- | -------- | -------- | | ~190,000 moves | MemoryError | 407MB| | ~200,000 moves | 1.8GB | 174.8 MB| For Speed: | # Input Data | Before PR | After PR | | -------- | -------- | -------- | | ~190,000 moves | MemoryError | 5.10s | | ~200,000 moves | 1m29s| 5.3s| ### Reference: opw-6067999 Forward-Port-Of: odoo/enterprise#113227
This update corrects a flaw in the FAIA report export that caused incorrect references to suppliers. Specifically, the report was misidentifying Azure Interior as a supplier when it should have been listed as a customer due to the absence of open balances. This ensures accurate reporting and compliance.
Original PR description
## Steps to reproduce: 1. Install `l10n_lu_reports`, swap to the LU company 2. Look at the partner Azure Interior. 1. They have no open balances on `asset_receivable` or `liability_payable` accounts.…
## Steps to reproduce:
1. Install `l10n_lu_reports`, swap to the LU company
2. Look at the partner Azure Interior.
1. They have no open balances on `asset_receivable` or `liability_payable` accounts.
2. Their `supplier_count` is higher than their `customer_count`.
3. Navigate to Accounting > Reporting > General Ledger.
4. Select the 2026 fiscal year.
5. Select gear > FAIA report.
6. Open the downloaded file. Notice:
1. Azure Interior is listed under /MasterFiles/Customers/Customer.
2. There are no /MasterFiles/Suppliers.
3. Azure Interior's ID (14 in this case) is referenced in a /SupplierID section.
7. Take a gander at the official XSD for LU [1]. The SupplierID must match an element in /MasterFiles/Suppliers.
Video: [2]
## Explanation
This is one of several errors found with the FAIA export. See PR #113316 for more.
It's possible to have a /SupplierID listed on a /Transaction/Line element but not have a /Suppliers/Supplier element that it refers to. This is not valid according to the FAIA report's schema [1].
This happens because /Transaction/Line and /MasterFiles use different criteria to determine if a partner is a Customer or a Supplier.
The element /Transaction/Line [3] determines this from the `partner_vals['type']` value [4]. This value is 'customer' or 'supplier' and is determined by comparing the ResPartner fields `customer_rank` and `supplier_rank`. In case of a tie, the partner is assigned as a 'supplier'.
The element /MasterFiles allows a partner to be both a Customer and a Supplier via `partner_vals['types']` [5]. Partners with an open `asset_receivable` balance at the start or end of the reporting period are listed as Customers [6]. Likewise, partners with an open `liability_payable` balance are listed as Suppliers [7]. If there are no open balances, partners are put in the Customer list by default.
The XSD validation error will not show up in a standard Runbot database because the namespace for the XSD is incorrect. If you manually fix the XSD namespace (`xmlns:doc` instead of `xmlns`) and use xmllint to check a generated XML against the XSD, it will raise the following error.
> No match found for key-sequence ['14'] of keyref 'RefGLTransactionLineSupplier'. Downloads/general_ledger (5).xml fails to validate
[1] https://pfi.public.lu/dam-assets/backup/FAIA/FAIA/XSD_Files.zip. I will note that there are three XSDs. Version A has a different namespace and appears to be more restrictive. The "full" XSD document does not raise these errors.
[2] https://drive.google.com/file/d/1xeULpCcGgZk-kYcCjBTKxcfv4ICYRzaB/view?usp=sharing
[3] https://github.com/odoo/enterprise/blob/434d88960abb5e424fdc1106fc93935d328bff78/account_saft/data/saft_report.xml#L244-L248
[4] https://github.com/odoo/enterprise/blob/434d88960abb5e424fdc1106fc93935d328bff78/account_saft/models/account_general_ledger.py#L299
[5] https://github.com/odoo/enterprise/blob/434d88960abb5e424fdc1106fc93935d328bff78/account_saft/models/account_general_ledger.py#L303-L309
[6] https://github.com/odoo/enterprise/blob/434d88960abb5e424fdc1106fc93935d328bff78/account_saft/data/saft_report.xml#L153
[7] https://github.com/odoo/enterprise/blob/434d88960abb5e424fdc1106fc93935d328bff78/account_saft/data/saft_report.xml#L173
opw-6107107
Forward-Port-Of: odoo/enterprise#117799This update resolves an issue where deleting an action linked to an inactive user-defined filter would sometimes fail. The change ensures that inactive filters are also removed during the action deletion process, preventing data inconsistencies and improving overall system stability.
Original PR description
How to reproduce: - Delete an action linked to an inactive user-defined filter. - Go to the User-Defined menu, - Show inactive filters (with "Archived filter") - Got a MissingError. Explanation: odoo/odoo#156622 fixes an inconsistency when deleting an action, but the reviewer was "amorti" so he (I) forgot to account for inactive "ir.filters". Add active_test=False to ensure inactive "ir.filters" are also removed. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves a problem where Xrechnung invoices generated in Odoo weren't consistently passing validation checks used by some German clients. The fix ensures the invoices conform to required standards, preventing potential issues with invoice processing. This improves compatibility with key German customers.
Original PR description
**PROBLEM** xrechnung pdf invoices are not compliant with some validators used german clients. **STEP TO REPRODUCE** 1. Create an invoice for a german customer. 2. Set the edi format on the customer as Xrechnung. 3. Download the invoice pdf, and verify it on https://www.portinvoice.com/ 4. Notice the pdf is not valid. To verify my fix works, you need to have the fontTools python package installed (for pdfa conversion). opw-6030481 Forward-Port-Of: odoo/odoo#259318
This update resolves an issue where delivery orders could be completed without recording serial numbers for tracked products, even when quantities were specified. The fix ensures that the product's quantity remains accurate when a delivery is marked as 'done' without a serial number, improving order fulfillment accuracy. This change was made to address a bug impacting product tracking.
Original PR description
Writing both `quantity` and `lot_ids` on a tracked move in the same form save leaves `move.quantity` stored at the user value while `_set_lot_ids` unlinks the remaining move line; the picking can then be validated to 'done' with no serial recorded. Force `_compute_quantity` at the end of `_set_lot_ids` so the stored value stays in sync with the move lines. Steps to reproduce: - Serial-tracked product, 6 in stock - Create a delivery order for 6 units of that product - In the delivery form, on the move row: type "1" in Quantity and remove all 6 lots from the Serial Numbers widget. - Save, Validate Before: picking goes to Done with quantity=1 and no serial. After: clear UserError, quantity stays in sync with mls. opw-6192841
This update resolves an issue where validating delivery costs on confirmed sales orders with real-cost invoicing policies caused errors. The fix prevents the system from incorrectly applying delivery prices when a sale order is locked, ensuring a smoother user experience. It specifically addresses a restriction on modifying delivery line details within locked orders.
Original PR description
Sale module has setting `Lock Confirmed Sales`, which particularly doesn't allow order line modification on a confirmed order. However, when a delivery carrier is set up with Invoicing Policy = Real cost, validating the picking pushes the actual carrier price onto the delivery line, writing `price_unit` and `name`. On a locked SO this raises a UserError. Fix it by excluding the delivery line's `price_unit` and `name` from the protected fields, only when the write originates from `_add_delivery_cost_to_so`. The code path is identified by the context `allow_delivery_cost_update`, so a regular UI edit of those fields on a locked SO is still blocked. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an issue where UBL invoice imports were incorrectly calculating prices due to a missing discount application. The fix ensures that discounts from AllowanceCharge are accurately added to the PriceAmount, resulting in correct invoice pricing. This improves data accuracy for financial reporting.
Original PR description
**PROBLEM** When importing a ubl bis3 file, with only the amount in the AllowanceCharge on PriceAmount it doesn't add the discount to PriceAmount to get the undiscounted price. Which means we create an invoice with the wrong price. This PR fixes that. opw-6102962
This update resolves a technical error preventing successful Adyen payments within the Point of Sale (POS) system. The issue stemmed from a problem accessing the terminal service ID, which is now corrected. This ensures reliable payment processing for our POS users.
Original PR description
This PR fixes the following error as seen in pos: ``` TypeError: Cannot read properties of undefined (reading 'terminalServiceId') at Proxy.isPaymentSuccessful (https://www.honu.ch/web/assets/43566c7/point_of_sale.assets_prod.min.js:16657:146) at Proxy.handleAdyenStatusResponse (https://www.honu.ch/web/assets/43566c7/point_of_sale.assets_prod.min.js:16655:215) ``` opw-6237987
This update fixes an issue where generated PDF invoices were missing item reference information. The change ensures that all product lines display the correct internal item reference, improving invoice accuracy and clarity. This resolves a problem with vendor bills generated by external systems.
Original PR description
Some XML vendor bills generated by external ERPs were missing the Description tag, which typically contains both the [ITEM_REF] and ITEM_NAME. As a result, product lines in the generated PDF could appear without the internal item reference. This commit ensures that the item reference is always included in the displayed product line. task-6080328 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an issue where invoices with excessively long item descriptions were being rejected by the eTIMS system. The fix truncates the description to meet the 200-character limit specified by eTIMS, ensuring successful invoice submission and compliance. This prevents potential delays in receiving VAT refunds.
Original PR description
The eTIMs specification limit the `itemNm` to 200 characters, so truncate the invoice line description to that limit to ensure that the invoice can be correctly submitted eTIMS server. Otherwise it will be rejected with: ``` Error sending to the KRA: - Request parameter error[<ItemList><itemNm>: length must be between 0 and 200] ``` Task-Id: 5220129 Forward-Port-Of: odoo/enterprise#118152