Daily updates from Odoo
Wednesday, May 27, 2026
95 changes
15 changes
Resolved issues and error corrections
This update resolves a problem where icon assets (like `.woff2`) weren't loading correctly, causing errors. The fix ensures that asset versions are handled consistently, preventing mismatches and improving the display of icons on the website. This improves the user experience by ensuring all icons load properly.
Original PR description
Currently, an exception is raised while loading icon content assets such as `.woff` or `.woff2`, due to a mismatch between the requested asset version and the latest available version. Steps to…
Currently, an exception is raised while loading icon content assets such as `.woff` or `.woff2`, due to a mismatch between the requested asset version and the latest available version. Steps to produce: - Install website - Open page `/web/assets/1/6a783c3/web.odoo_ui_icons.min.woff2` Error: `UnboundLocalError: cannot access local variable 'assets' where it is not associated with a value` This issue occurs because the code at [1] compares `binary.extension` with `asset_type`, causing the condition to fail because `binary.extension` contains values such as `woff` or `woff2`, while `asset_type` is set to `'binary'`. The root cause is that `asset_type` with value `'binary'` is being passed as a parameter to the `bundle.get_link` method (see [2]). The `asset_type` value comes from the `_parse_bundle_name` method (see [3]), where it is set to `'binary'` whenever the file extension belongs to `BINARY_EXTENSIONS`, such as `woff` or `woff2` (see [4]). This commit fixes the inconsistency between `bundle.get_version()` and `bundle.get_link()` when `binary` is `True`. Currently, `bundle.get_version()` used `extension if binary else asset_type`, while `bundle.get_link()` always received `asset_type`. This could lead to an incorrect redirect when handling binary assets. The fix normalizes the value by updating `asset_type` beforehand and reusing it consistently in both `bundle.get_version()` and `bundle.get_link()`. This also improves readability by removing the inline conditional expression. [1]: https://github.com/odoo/odoo/blob/8a2e001cffd381a89ab192f2e391ccc0843108c4/odoo/addons/base/models/assetsbundle.py#L166 [2]: https://github.com/odoo/odoo/blob/8a2e001cffd381a89ab192f2e391ccc0843108c4/addons/web/controllers/binary.py#L146 [3]: https://github.com/odoo/odoo/blob/8a2e001cffd381a89ab192f2e391ccc0843108c4/odoo/addons/base/models/ir_asset.py#L93-L94 [4]: https://github.com/odoo/odoo/blob/8a2e001cffd381a89ab192f2e391ccc0843108c4/odoo/tools/constants.py#L6-L7 Sentry-7441025709 Forward-Port-Of: odoo/odoo#263506
This update fixes a problem where invoices with year-range invoice numbers wouldn't send correctly to MyInvois. The change ensures the system correctly processes these invoice numbers, allowing invoices to be successfully transmitted for accounting purposes. This resolves a disruption in the automated invoice submission process.
Original PR description
Currently, an error is produced when sending invoices to MyInvois if the invoice number uses a year-range sequence. **Steps to Reproduce:(v-19.0)** 1. Install the `accountant` and `l10n_my_edi`…
Currently, an error is produced when sending invoices to MyInvois if the invoice number uses a year-range sequence. **Steps to Reproduce:(v-19.0)** 1. Install the `accountant` and `l10n_my_edi` modules (with demo data). 2. Switch to "MY Company"(Malaysian company). 3. Enable "_Quick Encoding_" for Customer Invoices in Settings. 4. Create a customer invoice with customer "_MY Company_", set a Malaysian classification code and taxes on the invoice line, and confirm the invoice. 5. Set the invoice back to Draft and modify the invoice number with a year-range sequence (e.g., INV/2025-2026/00001), then confirm it again. 6. Open the invoice list view and click **"Send to MyInvois"**. **Error:** `ValueError: not enough values to unpack (expected 4, got 2)` The `_get_sequence_date_range()` method on `myinvois.document` overrides the method from `sequence.mixin` and returns only two values from `date_utils.get_fiscal_year()`. However, it expects the method to return four values at [1]. [1] - https://github.com/odoo/odoo/blob/57b6b8d63b038ede32dfcc833c30e93d0cf4166c/addons/account/models/sequence_mixin.py#L146 Ref: https://github.com/odoo/odoo/blob/1ce06257f877711bd5de5487364909d72b476318/addons/account/models/account_move.py#L4263 sentry-7320998540 Forward-Port-Of: odoo/odoo#266221 Forward-Port-Of: odoo/odoo#253237
This update fixes an issue where the End Balance columns in the Romanian Trial Balance reports were displaying incorrect totals when the report hierarchy was enabled. The fix eliminates double-counting of account groups, ensuring accurate and consistent financial reporting for Romanian businesses using Odoo Enterprise.
Original PR description
### Issue before this commit: The total row for the End Balance columns in the Romanian 4-column and 5-column Trial Balance reports displayed incorrect values when the report hierarchy was enabled. ### Steps to reproduce the issue: 1. Downaload Accounting and l10n_ro 2. Switch to RO company 3. Go to Trial Balance report and be sure that Posted Entries, Accrual Basis are setted on Hierarchy and Subtotals 4. See that the End Blance both debit and credit is not correct ### Cause of the issue: The _custom_line_postprocessor method iterated over all report lines indiscriminately, adding account group subtotals to the running accumulator and causing duplicate counting. ### Reason to introduce the fix: To eliminate group double-counting and providing consistency with the totals in all the trial balances reports. opw-6146200 Forward-Port-Of: odoo/enterprise#118080 Forward-Port-Of: odoo/enterprise#117855
This update fixes several issues identified by Runbot during testing of the restaurant POS module. Specifically, problems related to order identification and refund processing were addressed, preventing disruptions to the checkout and payment flow. The changes include safety measures like optional order ID handling and improved tour navigation.
Original PR description
Runbot failed in three cases: taxGroupLabels could run while order_id was missing and crash on fiscal_position_id. During sync, is_refund on the order could disagree, so _askForPreparation showed the kitchen prompt on refund flows and blocked payment. The delete-line tour sometimes asserted before the table was closed; the tour now opens the plan again to close and sync tables. Safety fix: Optional chaining on order_id; Wait for sync refund for the preparation check; Explicit plan navigation in the tour. runbot error - 242601-242604 Forward-Port-Of: odoo/odoo#260264
This update fixes an error that occurred when users reviewed eMPF contribution reports. Specifically, the system would fail if an employee wasn't assigned to a contribution line. The fix now prompts the user to assign an employee, ensuring reports can be accurately reviewed.
Original PR description
Currently, an error occurs when the user checks the report line errors. **Steps to Reproduce:** - Install the `l10n_hk_hr_payroll_empf` module with demo data. - Switch to the `Hong Kong` company. -…
Currently, an error occurs when the user checks the report line errors. **Steps to Reproduce:** - Install the `l10n_hk_hr_payroll_empf` module with demo data. - Switch to the `Hong Kong` company. - Go to `Payroll` > `Reporting` > `Hong Kong` > `eMPF Contributions`. - Create a record by setting the `Scheme` and adding a `contribution line`. - Ensure that the employee and payslip fields are empty in the contribution line. - Click on `Validate`, then click on the `error icon` on the report line. `ValueError: Expected singleton: hr.version()` This error occurs when the user manually adds a line and checks the errors on it.. The system attempts to open the employee record from the version [1], but the version is not set [2] on the line because there is no employee. And it raise the error [3]. This commit ensures that when checking errors, if the version is not set on the line, a UserError is raised, prompting the user to set the employee on the line. It also corrects a typo in the status message. [1]- https://github.com/odoo/enterprise/blob/7889b2b0b3d13b32e6e36e616e20379d8c8f8812/l10n_hk_hr_payroll_empf/model/l10n_hk_empf_contribution_report_line.py#L219 [2]- https://github.com/odoo/enterprise/blob/7889b2b0b3d13b32e6e36e616e20379d8c8f8812/l10n_hk_hr_payroll_empf/model/l10n_hk_empf_contribution_report_line.py#L142-L156 [3]: https://github.com/odoo/odoo/blob/98855c6b70df24500babe6027109aa9e17431ec1/addons/hr/models/hr_version.py#L609-L611 Forward-Port-Of: odoo/enterprise#116607
This update fixes an issue where extra prices on combo products weren't correctly converted to the sale order's currency, leading to inaccurate totals. The change ensures that combo product extra prices are now properly converted, resulting in correct pricing calculations for sales orders in different currencies. This improves the accuracy of sales quoting and invoicing.
Original PR description
The total of a sale order containing a combo product that has an extra price is not correclty converted to the sale order's pricelist currency Steps to reproduce: 1. Install Sales 2. Go to Invoicing…
The total of a sale order containing a combo product that has an extra price is not correclty converted to the sale order's pricelist currency Steps to reproduce: 1. Install Sales 2. Go to Invoicing > Configuration > Accounting > Currencies and activate currency MXN 3. Go to Sales > Products > Pricelists and create a new pricelist for currency MXN 4. Go to Sales > Products and create a new combo product "test" 5. Create a combo choice "combo" with options "Large Cabinet" and extra price 10000$ 6. Go to Sales and create a new quotation for customer Acme Corporation with product "test" (total is $10,001) 7. Change the pricelist to MXN and update prices 8. The total is ~MX$10,018 (it should be ~MX$186,682) Issue: The extra price of a combo product is not converted to the sale order's pricelist currency, so we end up adding the price of the product in the order's currency with the extra price not converted Solution: Convert the extra price of the combo product to the sale order's pricelist currency opw-6192935 Forward-Port-Of: odoo/odoo#266172 Forward-Port-Of: odoo/odoo#265008
This update resolves an issue where timesheet data wasn't consistently synchronized between Odoo tabs. The fix ensures that changes made in one tab's timesheet are accurately reflected in all other tabs, improving data accuracy and user experience. This prevents discrepancies in timesheet records.
Original PR description
This PR reworks the implementation of https://github.com/odoo/enterprise/pull/116007 Task-6180394 Forward-Port-Of: odoo/enterprise#117914
This update fixes an issue where Preparation Displays (PDIS) weren't properly synchronized when performing actions like transferring or merging orders on the POS system. Previously, new PDIS were created instead of reusing existing ones, leading to inconsistencies. Now, PDIS are correctly updated across all table actions, ensuring accurate data between the POS and kitchen screens.
Original PR description
Task: [#5005179](https://www.odoo.com/odoo/1737/tasks/5005179) --- When executing table actions such as transfer, merge, link, or unlink, the related Preparation Displays (PDIS) were not being updated. This caused inconsistencies between the POS orders and the kitchen screens. Also, when merging or linking orders and cancelling some lines, a new `pdis_order` was created instead of reusing the existing one. This fix ensures that PDIS are correctly synchronized and notified on any table actions. Forward-Port-Of: odoo/enterprise#108009 Forward-Port-Of: odoo/enterprise#98374
This update fixes a problem where preparation displays (PDIS) weren't correctly updated when transferring, merging, or linking POS orders. Previously, new PDIS were created instead of reusing existing ones, leading to inconsistencies between the POS and kitchen screens. Now, PDIS are synchronized across all table actions, ensuring accurate kitchen order information.
Original PR description
Task: [#5005179](https://www.odoo.com/odoo/1737/tasks/5005179) --- When executing table actions such as transfer, merge, link, or unlink, the related Preparation Displays (PDIS) were not being updated. This caused inconsistencies between the POS orders and the kitchen screens. Also, when merging or linking orders and cancelling some lines, a new `pdis_order` was created instead of reusing the existing one. This fix ensures that PDIS are correctly synchronized and notified on any table actions. Forward-Port-Of: odoo/odoo#249657 Forward-Port-Of: odoo/odoo#233630
This update resolves a memory issue that occurred during large product imports, preventing potential application crashes. The fix utilizes a more efficient batch processing method to reduce unnecessary calculations and memory usage, resulting in improved performance and stability for invoice and bill imports.
Original PR description
Before this commit, for DBs with a very large number of products it was possible for the thread to run out of memory when importing an invoice or a bill. The reason is that the name on…
Before this commit, for DBs with a very large number of products it was possible for the thread to run out of memory when importing an invoice or a bill. The reason is that the name on product.product is non stored and computed. This leads to tons of recomputes, which in turn leads to reads and stores in cache of the underlying `product.product`, which down the line uses up all of the available memory for the thread. The proposed method uses batches instead of a `search_fetch` as the latter would not solve the recompute problem and hence the underlying memory problem. Another alternative approach could be going straight for the `product.template.name`, but that approach might introduce a loss of precision or functionality when searching for products at invoice import. Here is the memory graph from memray before the fix: <img width="1106" height="450" alt="opw-6168737-memray-pre-fix" src="https://github.com/user-attachments/assets/f971dc4d-aa09-41e3-a8c5-e5ca53f9786d" /> And here is the same graph after the fix: <img width="1106" height="450" alt="opw-6168737-memray-post-fix" src="https://github.com/user-attachments/assets/0a784cdc-9b40-498b-bbcb-89114eec1ec9" /> We can see a much lower peak memory usage after the fix. We an also observe that the memory complexity shifts from `O(n)` to `O(1)`, with `n` being the number of `product.product` records stored in the DB. For both presented graphs, the same, unaltered database was tested. The database contains 389 467 `product.product` records. opw-6168737 Forward-Port-Of: odoo/odoo#265639 Forward-Port-Of: odoo/odoo#262591
This update ensures that payments received from providers are always fully reconciled, rather than allowing partial reconciliations. Previously, the system incorrectly permitted partial reconciliation for these payments, leading to inaccurate accounting records. This change guarantees accurate financial reporting for payments originating from external providers.
Original PR description
When we receive a payment from a provider, we allow partial reconciliations to be done on this move, but we shouldn't. Payments coming from providers are always either fully paid, or not paid at all. task-5893189 Forward-Port-Of: odoo/odoo#254597
This update corrects a bug where refund actions were incorrectly triggering the cancellation of original invoices. The fix adds a check to ensure the automatic cancellation flow only applies to invoice replacements, preventing credit notes from causing unintended cancellations. This ensures accurate accounting and avoids disruption for users.
Original PR description
Issue: Implementation of automatic CFDI cancel flow of an invoice substituted by a new one accidentally resulted in sending credit notes created from an invoice also triggering cancellation of the original. Solution: adding a check to only apply to invoice replacements and not refunds. ticket-6245456 Forward-Port-Of: odoo/enterprise#118327
This update resolves a critical issue that prevented the generation of PDF reports for Vietnamese tax filings (Appendix 142), specifically when reports had no data. It also corrects data references and ensures the correct naming and ordering of reports for accurate tax reporting, improving data integrity and usability.
Original PR description
This commit resolves multiple issues in the Vietnamese accounting reports module: 1. Appendix 142 PDF Export Crash: - Extracted the PDF sectioning logic into a new `_get_pdf_sections` method. - Added…
This commit resolves multiple issues in the Vietnamese accounting reports module: 1. Appendix 142 PDF Export Crash: - Extracted the PDF sectioning logic into a new `_get_pdf_sections` method. - Added safeguards to gracefully handle cases where the report has no lines, preventing an `IndexError` when attempting to access `lines[-1]`. - Added unit tests to ensure empty lines are correctly parsed without crashing. 2. XML Data and Dependency Fixes: - Fixed an invalid `report_id` reference in `account_return_data.xml` by correctly pointing it to `l10n_vn_reports.l10n_vn_tax_report` instead of `l10n_vn.form_01_gtgt_report`. - Reordered the `__manifest__.py` data loading sequence. `account_tax_report_data.xml` now loads before `account_return_data.xml` to prevent "External ID not found" errors during module installation/upgrades. 3. Naming and Sequencing Improvements: - Renamed "Vietnamese Tax Report" to "VAT Declaration - 01/GTGT" to reflect the actual Vietnamese tax form accurately. - Added explicit `sequence` fields to the tax reports (VAT Declaration: 10, Appendix 142: 20) to ensure proper UI ordering. Task-6216318
This update fixes an issue where invoices imported from UBL files were incorrectly calculating prices due to a missing discount application. The change ensures that discounts from AllowanceCharges 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 Forward-Port-Of: odoo/odoo#258964
This update optimizes how Odoo renders large pages, like account reports, by streamlining the styling process. The change avoids slow style calculations that can occur when targeting elements broadly, resulting in faster page loading and smoother interactions. This improves the overall user experience.
Original PR description
Avoid using the attribute substring selector (`*=`), which forces a broad match and can be slower than class selectors. Target the correct node directly using the `o-we-hint` class instead. On very large pages (thousands of DOM elements like account_report) `*=` can increase style recalculation time during actions like window resize, heavy scrolling, or table sorting. Replacing it with using the specific class reduces those global checks and improves rendering performance. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#266381
19 changes
Resolved issues and error corrections
This update resolves a bug in the HTML Editor where resizing the table would cause a crash when a table was deleted. The fix restricts resizing to the primary mouse button and prevents the resize logic from running when there's no valid target, ensuring a smoother and more stable user experience.
Original PR description
#### Description of the issue this PR addresses: - Table resize listeners are not cleaned when the table is removed while resizing - Next mousemove runs resize logic with a null target and throws traceback #### Desired behavior after PR is merged: - Restrict resize start to primary mouse button only - Prevent resize logic execution on null targets #### Steps to reproduce: - Open the todo app - Insert a table and select whole table - Move cursor on a table cell border to see resize cursor - Right click and choose Cut from browser context menu - Move the mouse again - Resize logic crashes with null target traceback task-6212279 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#266274 Forward-Port-Of: odoo/odoo#264065
This update resolves an error that occurred when users checked the details of eMPF contribution reports. The fix ensures that the system prompts users to correctly identify the employee before generating the report, preventing a technical error. This improves report accuracy and usability.
Original PR description
Currently, an error occurs when the user checks the report line errors. **Steps to Reproduce:** - Install the `l10n_hk_hr_payroll_empf` module with demo data. - Switch to the `Hong Kong` company. -…
Currently, an error occurs when the user checks the report line errors. **Steps to Reproduce:** - Install the `l10n_hk_hr_payroll_empf` module with demo data. - Switch to the `Hong Kong` company. - Go to `Payroll` > `Reporting` > `Hong Kong` > `eMPF Contributions`. - Create a record by setting the `Scheme` and adding a `contribution line`. - Ensure that the employee and payslip fields are empty in the contribution line. - Click on `Validate`, then click on the `error icon` on the report line. `ValueError: Expected singleton: hr.version()` This error occurs when the user manually adds a line and checks the errors on it.. The system attempts to open the employee record from the version [1], but the version is not set [2] on the line because there is no employee. And it raise the error [3]. This commit ensures that when checking errors, if the version is not set on the line, a UserError is raised, prompting the user to set the employee on the line. It also corrects a typo in the status message. [1]- https://github.com/odoo/enterprise/blob/7889b2b0b3d13b32e6e36e616e20379d8c8f8812/l10n_hk_hr_payroll_empf/model/l10n_hk_empf_contribution_report_line.py#L219 [2]- https://github.com/odoo/enterprise/blob/7889b2b0b3d13b32e6e36e616e20379d8c8f8812/l10n_hk_hr_payroll_empf/model/l10n_hk_empf_contribution_report_line.py#L142-L156 [3]: https://github.com/odoo/odoo/blob/98855c6b70df24500babe6027109aa9e17431ec1/addons/hr/models/hr_version.py#L609-L611 Forward-Port-Of: odoo/enterprise#116607
This update fixes an issue where extra prices on combo products weren't correctly converted to the sale order's currency, leading to inaccurate totals. The change ensures that extra prices are properly converted, resulting in accurate pricing calculations for combo products in different currencies. This improves the reliability of sales order pricing.
Original PR description
The total of a sale order containing a combo product that has an extra price is not correclty converted to the sale order's pricelist currency Steps to reproduce: 1. Install Sales 2. Go to Invoicing…
The total of a sale order containing a combo product that has an extra price is not correclty converted to the sale order's pricelist currency Steps to reproduce: 1. Install Sales 2. Go to Invoicing > Configuration > Accounting > Currencies and activate currency MXN 3. Go to Sales > Products > Pricelists and create a new pricelist for currency MXN 4. Go to Sales > Products and create a new combo product "test" 5. Create a combo choice "combo" with options "Large Cabinet" and extra price 10000$ 6. Go to Sales and create a new quotation for customer Acme Corporation with product "test" (total is $10,001) 7. Change the pricelist to MXN and update prices 8. The total is ~MX$10,018 (it should be ~MX$186,682) Issue: The extra price of a combo product is not converted to the sale order's pricelist currency, so we end up adding the price of the product in the order's currency with the extra price not converted Solution: Convert the extra price of the combo product to the sale order's pricelist currency opw-6192935 Forward-Port-Of: odoo/odoo#266172 Forward-Port-Of: odoo/odoo#265008
This update ensures Knowledge articles always load correctly when printed, regardless of the printing method. Previously, printing through various channels could cause blank pages. Now, CSS rules have been adjusted to prevent unintended styling issues in other Odoo modules, improving the overall printing experience.
Original PR description
Previously, the file containing the Knowledge print assets was lazy-loaded when the user triggered a print action through the UI. However, printing can also be initiated through other mechanisms…
Previously, the file containing the Knowledge print assets was lazy-loaded when the user triggered a print action through the UI. However, printing can also be initiated through other mechanisms (keyboard shortcuts, contextual menu, etc.), which prevented us from consistently detecting when to load the assets. In those cases, the assets were not loaded and the article appeared blank (see: odoo/enterprise#70243). To ensure the assets are always loaded regardless of how printing is triggered, we moved them to the common print bundle and adopted the standard asset-loading approach. This change also simplifies the codebase by removing JavaScript workarounds previously used to load the assets dynamically. However, some CSS rules in the Knowledge print stylesheet target global elements such as the web client container. Since the stylesheet is now included in a global asset bundle and always loaded, these rules apply to all modules and may cause rendering issues when printing views outside of Knowledge. To prevent such side effects, the CSS rules in `knowledge_print.scss` will be updated to use more specific selectors. The rules will be scoped so they only apply when the container includes the Knowledge view (using the `:has`). This PR also refactors the stylesheet by removing outdated rules that no longer match any elements. Several of these rules predate the major UI refactoring introduced in Odoo 16. Task-5999878 Forward-Port-Of: odoo/enterprise#109379
This update optimizes the process of exporting large datasets in Odoo, addressing potential memory issues that could cause slowdowns. By batching export calls and invalidating recordsets, the system now handles larger exports more efficiently, reducing memory usage and improving export speeds. This results in faster data exports for users.
Original PR description
When exporting a number N of records as XLSX or CSV file, we call the export_data() method for the N records at the same time. This method prefetches the selected fields for all the records which can lead to memory limit errors when N is too large. We propose to batch this call and invalidate the recordsets between batches. Benchmarks ----------- Execution time: | No records | Before PR | After PR | |------------|-----------|----------| | 70 260 | 3.82 s | 3.94 s | | 228 116 | 18.71 s | 19.36 s | | 394 381 | 31.02 s | 32.67 s | Memory usage: | No records | Before PR | After PR | |------------|-----------|----------| | 70 260 | 316.0 MB | 273.5 MB | | 228 116 | 796.9 MB | 620.8 MB | | 394 381 | 1.3 GB | 947.7 MB | opw-5881026 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#266078 Forward-Port-Of: odoo/odoo#257333
This update fixes a bug that prevented accurate IT tax closing validation, particularly when dealing with quarterly VAT reporting. The changes ensure correct handling of year-end gaps and utilize debit/credit columns in VAT reports, preventing errors and improving the reliability of tax closing processes.
Original PR description
Description of the issue this commit addresses: The IT tax closing validation compared month numbers only, which broke across year boundaries and could reject valid quarterly progressions. It also assumed a balance column existed in monthly VAT report lines, but this report uses debit/credit columns, which could trigger a traceback. --- Desired behavior after this commit is merged: This commit computes the period gap with year-aware month deltas and aligns the allowed gap with periodicity (monthly or quarterly). It also checks VP lines using balance when present, or debit/credit as fallback, preventing crashes and ensuring consistent tax closing validation. --- opw-6131080 Forward-Port-Of: odoo/enterprise#117428
This update fixes a bug where Preparation Displays (PDIS) weren't correctly updated during table actions like transferring or merging orders. Previously, new PDIS were created instead of reusing existing ones, leading to inconsistencies. Now, PDIS are synchronized across all table actions, ensuring accurate order information on both the POS and kitchen screens.
Original PR description
Task: [#5005179](https://www.odoo.com/odoo/1737/tasks/5005179) --- When executing table actions such as transfer, merge, link, or unlink, the related Preparation Displays (PDIS) were not being updated. This caused inconsistencies between the POS orders and the kitchen screens. Also, when merging or linking orders and cancelling some lines, a new `pdis_order` was created instead of reusing the existing one. This fix ensures that PDIS are correctly synchronized and notified on any table actions. Forward-Port-Of: odoo/enterprise#102623 Forward-Port-Of: odoo/enterprise#98374
This update fixes a problem where preparation displays (PDIS) weren't correctly updated when transferring, merging, or linking POS orders. Previously, new PDIS were created instead of reusing existing ones, leading to inconsistencies between the POS and kitchen screens. This ensures accurate order information is displayed on kitchen screens.
Original PR description
Task: [#5005179](https://www.odoo.com/odoo/1737/tasks/5005179) --- When executing table actions such as transfer, merge, link, or unlink, the related Preparation Displays (PDIS) were not being updated. This caused inconsistencies between the POS orders and the kitchen screens. Also, when merging or linking orders and cancelling some lines, a new `pdis_order` was created instead of reusing the existing one. This fix ensures that PDIS are correctly synchronized and notified on any table actions. Forward-Port-Of: odoo/odoo#240878 Forward-Port-Of: odoo/odoo#233630
This update corrects a bug where refund actions were incorrectly triggering the cancellation of original invoices. The fix adds a check to ensure the automatic cancellation process only applies to legitimate invoice replacements, preventing unintended credit note cancellations. This ensures accurate accounting and reporting for Mexican VAT (CFDI) transactions.
Original PR description
Issue: Implementation of automatic CFDI cancel flow of an invoice substituted by a new one accidentally resulted in sending credit notes created from an invoice also triggering cancellation of the original. Solution: adding a check to only apply to invoice replacements and not refunds. ticket-6245456 Forward-Port-Of: odoo/enterprise#118327
This update fixes an issue where invoices imported from UBL files were incorrectly calculating prices due to a missing discount application. The change ensures that discounts from AllowanceCharges are accurately added to the PriceAmount, resulting in correct invoice pricing. This resolves a problem that could lead to inaccurate 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 Forward-Port-Of: odoo/odoo#258964
This fix resolves an issue where confirming a sales order with multiple event registrations would cause a system error. The update now correctly creates multiple leads when multiple event registrations are associated with a single order, ensuring accurate lead tracking for events with multiple attendees. This improves the reliability of the event registration process.
Original PR description
# How to reproduce - Install the Events, Porject & CRM apps - Create two event A & B with tickets that can be purchased - Go to Events > Configuration > Lead Generation - Create a Lead Generation…
# How to reproduce - Install the Events, Porject & CRM apps - Create two event A & B with tickets that can be purchased - Go to Events > Configuration > Lead Generation - Create a Lead Generation Rule with : - Create : Per Order - When : Attendees are created - Event : None - Create a new quotation with two lines : - Product : Even Registration for event A 1st, then B - Confirm the SO # The problem A traceback will appear # Cause of the issue When confirming the SO, we create `event.registrations`s that will check for lead generation rules and create or update `crm.lead`s accordingly : https://github.com/odoo/odoo/blob/3bf89b4f467390807c20f7b007a875a77542e76f/addons/event_crm/models/event_registration.py#L35 We will then group the registrations by leads & grouping model : https://github.com/odoo/odoo/blob/3bf89b4f467390807c20f7b007a875a77542e76f/addons/event_crm/models/event_lead_rule.py#L166 For all groups, if the lead does not exist, we create one : https://github.com/odoo/odoo/blob/3bf89b4f467390807c20f7b007a875a77542e76f/addons/event_crm/models/event_lead_rule.py#L184-L187 `_get_lead_values()` works fine with multiple `event.registrations`s, but crashes when those registrations does not have all the same event, which is our case : https://github.com/odoo/odoo/blob/3bf89b4f467390807c20f7b007a875a77542e76f/addons/event_crm/models/event_registration.py#L170 # Proposed solution Since we have multiple events and leads are associated to a single event : https://github.com/odoo/odoo/blob/3bf89b4f467390807c20f7b007a875a77542e76f/addons/event_crm/models/crm_lead.py#L11 We group the registrations by event and create multiple leads accordingly opw-6167518 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265017
This update resolves a memory issue that could cause invoice imports to fail with large product catalogs. The fix uses a more efficient batch processing method to reduce unnecessary calculations and memory consumption, preventing performance bottlenecks.
Original PR description
Before this commit, for DBs with a very large number of products it was possible for the thread to run out of memory when importing an invoice or a bill. The reason is that the name on…
Before this commit, for DBs with a very large number of products it was possible for the thread to run out of memory when importing an invoice or a bill. The reason is that the name on product.product is non stored and computed. This leads to tons of recomputes, which in turn leads to reads and stores in cache of the underlying `product.product`, which down the line uses up all of the available memory for the thread. The proposed method uses batches instead of a `search_fetch` as the latter would not solve the recompute problem and hence the underlying memory problem. Another alternative approach could be going straight for the `product.template.name`, but that approach might introduce a loss of precision or functionality when searching for products at invoice import. Here is the memory graph from memray before the fix: <img width="1106" height="450" alt="opw-6168737-memray-pre-fix" src="https://github.com/user-attachments/assets/f971dc4d-aa09-41e3-a8c5-e5ca53f9786d" /> And here is the same graph after the fix: <img width="1106" height="450" alt="opw-6168737-memray-post-fix" src="https://github.com/user-attachments/assets/0a784cdc-9b40-498b-bbcb-89114eec1ec9" /> We can see a much lower peak memory usage after the fix. We an also observe that the memory complexity shifts from `O(n)` to `O(1)`, with `n` being the number of `product.product` records stored in the DB. For both presented graphs, the same, unaltered database was tested. The database contains 389 467 `product.product` records. opw-6168737 Forward-Port-Of: odoo/odoo#265639 Forward-Port-Of: odoo/odoo#262591
This update corrects a bug where payments received from providers were sometimes partially reconciled, leading to inaccurate accounting records. Now, all payments from providers are fully reconciled, ensuring accurate financial reporting. This change improves the reliability of our accounting system.
Original PR description
When we receive a payment from a provider, we allow partial reconciliations to be done on this move, but we shouldn't. Payments coming from providers are always either fully paid, or not paid at all. task-5893189 Forward-Port-Of: odoo/odoo#254597
This update fixes an issue where COGS calculations were inaccurate due to incorrect unit of measure conversions and a bug related to customer returns. Specifically, the system now correctly handles different unit of measure conversions for COGS lines and prevents incorrect monetary values from being applied to intermediate stock moves during return processing, ensuring accurate financial reporting.
Original PR description
[FIX] sale_stock: convert quantity using correct UoM The quantity unit conversion was applied to an already summed value, ignoring the fact that individual COGS lines may have different UoMs. --- [FIX] stock_account: Do not copy field 'value' of StockMove When a customer return is split into multiple steps (e.g., Customer -> Input -> Stock), the `value` field of the stock move was being copied from the first step to the second. This caused the second step (which should not be valued) to inherit the monetary value, leading to incorrect COGS entries when the invoice was posted. The value should only be set when the move is Done, not during a copy. --- OPW-6076350 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#260495 Forward-Port-Of: odoo/odoo#257543
This update prevents a user without sign admin rights from encountering an access error when viewing records with sign request activities. The change uses 'sudo' to ensure visibility and disables actions to avoid errors, while also creating activities directly linked to the request creator. This improves the sign request workflow for all users.
Original PR description
**Steps to reproduce** - Have user A with Sign admin rights and user B without Sign rights. - With user A, create a sign request activity on a record that user B can access. Send the signature…
**Steps to reproduce** - Have user A with Sign admin rights and user B without Sign rights. - With user A, create a sign request activity on a record that user B can access. Send the signature request. - With user B, try to access the record. -> AccessError when trying to fetch the chatter. **Cause** By default, users get access to all the activities associated to records they have access to (see `_search` of `mail.activity`). This is an issue since some of the fields added in `_store_activity_fields` for the sign request activity display might not be accessible for a user with access to the activity. **Change** Use `sudo` to be able to display the activity, even if the user doesn't have access to the sign request. Also, in that case, `can_write` should be `False` in order to hide the action buttons of the activity, which trigger access errors when trying to make operations on the sign request. Another related change is to create the activity for the user creating the sign request, this avoids falling back on the `user_id` of the record associated with the activity and makes sure the activity's user has access to the sign request. opw-6157455
This update corrects a rounding issue that previously caused the withholding base amount on invoices to exceed the total invoice amount. The fix ensures accurate calculations by limiting the withholding base amount to prevent over-reporting. This improves invoice data integrity and compliance.
Original PR description
**PROBLEM** In some case, because of rounding issues, the withholding base amount can be bigger than the total amount of the invoice, which should not be the case. **STEP TO REPRODUCE** 1. Install…
**PROBLEM** In some case, because of rounding issues, the withholding base amount can be bigger than the total amount of the invoice, which should not be the case. **STEP TO REPRODUCE** 1. Install l10n_pe_edi 2. Create an invoice with those 2 lines: qty: 300, unit_price: 0.481936, tax: VAT 18% + 3% IGV Withholding qty: 300, unit_price: 0.747376, tax: VAT 18% + 3% IGV Withholding 3. Confirm the invoice, and send the xml (if this fail, you may have to change the name of the invoice, using odoo inspector or other means). 4. Open the xml, and notice the base amount for the allowance on the document level is 435.18 which is bigger than the invoice payable amount. **CAUSE** We exclude the withholding taxes to compute the invoice taxInclusiveAmount. When computing this amount, we round the line base and the tax total of the VAT 18% tax leading to the result of 435.17. When creating the allowance node for the Withholding taxes, the base used for the withholding taxes is the sum of the line base, and the tax total of previous tax NOT rounded. There is no easy way to change the withholding tax computation, so we just limit the base to not be bigger than the invoice total when there is rounding issues. opw-6010388 Forward-Port-Of: odoo/enterprise#113689
This update fixes an issue where payments weren't automatically linked to invoices when invoices were created after payment processing. Previously, this caused reconciliation problems with automated payment records. Now, payments are correctly linked to the invoice, ensuring accurate financial reporting.
Original PR description
Steps to reproduce: - Ensure Automatic Invoice setting is on - Create sales order for product with ordered quantites invoicing policy - Generate a Payment Link - Pay with the ACH Direct Debit method via a provider (e.g. Stripe) - While the payment is processing, confirm the sales order, create an invoice, confirm the invoice Current Behavior: When the payment is finished processing, the payment is not automatically linked to the corresponding invoice Expected Behavior: When the payment is finished processing, the payment should be linked to the invoice despite it being created by a user Explanation: The payment transaction's link to invoice_id is severed in PaymentTransaction._invoice_sale_orders if an invoice is created before the payment is cleared. This will eventually lead to the account.payment created automatically later on not being reconciled with the invoice. opw-6087656 Forward-Port-Of: odoo/odoo#264800
This update resolves an issue where production orders created from sale orders (using multi-step routes) didn't always correctly update delivery quantities. The fix ensures that the `move_dest_ids` are properly propagated across all production orders created from a single sale order, particularly when using batch sizes. This guarantees accurate inventory tracking and order fulfillment.
Original PR description
### Steps to reproduce: - In the settings enable: Multi-steps routes - Inventory > Configuration > Warehouse Management > Routes - Unarchive MTO - Create a storable product P with a bom using the MTO…
### Steps to reproduce: - In the settings enable: Multi-steps routes - Inventory > Configuration > Warehouse Management > Routes - Unarchive MTO - Create a storable product P with a bom using the MTO Route - In the Miscellaneous tab of the bom tick Batch Size and set it to 2 - Create and confirm a sale order for 6 units of P #### > Three MO's are created but only the last one will update the quantities of the delivery at validation of the production. ### Cause of the issue: The `move_dest_ids` of the `move_finished_ids` is only set on the last of the three productions. That is only the last MO is properly chained to the delivery via an MTO chain. This happens because the `move_dest_ids` field of the `mrp.production` model is a `One2Many` field: https://github.com/odoo/odoo/blob/a2f072fe99a03aaf521bba1965e7f29a1c99e325/addons/mrp/models/mrp_production.py#L223-L224 Which implies that each move can be linked to at most one mrp.production via the `created_production_id` field. However, if you have set a batch size on your bom, it is expected for a single move to create multiple mo's. While the `move_dest_ids` of each of these MO is appropriately set in the create vals to be the mto `stock.move` of the delivery, due to the nature of the `created_production_id` field only the *last* mo will created with a set `move_dest_ids` as this is the only record that will be set as `created_production_id`. However, after the creation of these MO's, the related `move_finished_ids` will be recomputed: https://github.com/odoo/odoo/blob/a2f072fe99a03aaf521bba1965e7f29a1c99e325/addons/mrp/models/mrp_production.py#L1089-L1093 However, the `move_dest_ids` of the created moves will be set to be either the `move_dest_ids` of their production (which is unset for all but the last one) or these of the first production of the same `production_group` that is these generated by a common production split: https://github.com/odoo/odoo/blob/a2f072fe99a03aaf521bba1965e7f29a1c99e325/addons/mrp/models/mrp_production.py#L1263-L1267 Now, since neither are set in our use case, the `move_dest_ids` will not be set on the `move_finished_ids` which implies in particular that the mto link between our productions (but the last one) and the delivery is lost. Fix: Since we can not change the nature of the `move_dest_ids` and `created_production_id` in stable to become Many2Many fields, we need to find a way to propagate the `move_dest_ids` on moves without relying on the probably inaccurate value provided by the production. And, since the compute of the `move_finished_ids` could be launched at many other points than during a create process (because of the many dependencies), we can not solely rely on the creation context but rather new to provide a way to recreate the link from relations at any given point. We therefore rely on the `stock.reference`'s similar to what was done prior to 19.0 via the `procurement_group_ids`: https://github.com/odoo/odoo/blob/132f042ca14012877f608783b57a0ca9c4e565f3/addons/mrp/models/mrp_production.py#L1198-L1202 opw-6188069 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264951
This update fixes a bug where adding serial numbers to outgoing stock picks (when the quantity is zero) would incorrectly add additional serial numbers, leading to quantity mismatches. The change ensures that only the manually added serial numbers are applied, maintaining accurate stock counts. This improves the reliability of our inventory tracking.
Original PR description
**Problem**: When we set the quantity of a move to zero, then add serial numbers manually, if the serial numbers are not the first ones in the list of available serial numbers, The first few…
**Problem**: When we set the quantity of a move to zero, then add serial numbers manually, if the serial numbers are not the first ones in the list of available serial numbers, The first few available serial numbers will be added to the move, which causes a mismatch of quantity and the number of serial numbers. **Before this commit:** If we have three serial number SN-001, SN-002, SN-003 created in order, and we set the quantity of the move to zero, then add SN-002 and SN-003 manually, SN-001 will be added automatically while saving. **After this commit:** Only SN-002 and SN-003 will be added to the move, which matches the quantity. **Steps to reproduce:** 1. Create a product with tracking by unique serial number, and create 3 lots SN-001, SN-002, SN-003 for this product. 2. Create a picking and add a move for this product, set the demand to 3 and quantity to 0. 3. Set the quantity to 2, and add SN-002 and SN-003 to the move, then save the picking. 4. SN-001 will be added to the move automatically, but the quantity stays at 2. opw-6121208 Forward-Port-Of: odoo/odoo#266259 Forward-Port-Of: odoo/odoo#263080
19 changes
Resolved issues and error corrections
This update corrects a bug in the stock account configuration process. Previously, new stock accounts were created with missing data, leading to incomplete records. This fix ensures updates only apply to existing accounts, guaranteeing accurate and fully populated stock account information.
Original PR description
In the post-init stock configuration we update the chart accounts to add stock-related fields using `_load_data`. The values provided by `_get_stock_account_account` only contain partial data meant…
In the post-init stock configuration we update the chart accounts to add stock-related fields using `_load_data`. The values provided by `_get_stock_account_account` only contain partial data meant to enrich accounts created by the chart template.
The update should only be performed on accounts that already exist. Otherwise, the load creates new account records with most fields left null (e.g. account_type), which is not the intention here.
This fix filters the updates to existing accounts only, so the step only enriches accounts created by the chart template and avoids creating incomplete account records.
steps to reproduce:
- Install account app in a odoo 19 db
- Delete account 'stock valuation'
- Install `stock_account` module
```py
File "/home/odoo/src/odoo/19.0/addons/stock_account/__init__.py", line 13, in _post_init_hook
_configure_stock_account_company_data(env)
File "/home/odoo/src/odoo/19.0/addons/stock_account/__init__.py", line 79, in _configure_stock_account_company_data
ChartTemplate._load_data({
File "/tmp/tmplqo7rmpu/migrations/account/0.0.0/pre-ensure-deferred-accounts.py", line 36, in _load_data
return super()._load_data(data, *args, **kwargs)
File "/home/odoo/src/odoo/19.0/addons/account/models/chart_template.py", line 697, in _load_data
created_records[model] = self.with_context(lang='en_US').env[model]._load_records(all_records_vals)
File "/home/odoo/src/odoo/19.0/odoo/orm/models.py", line 5194, in _load_records
records = self._load_records_create([data['values'] for data in to_create])
# [...]
File "/home/odoo/src/odoo/19.0/odoo/sql_db.py", line 433, in execute
self._obj.execute(query, params)
psycopg2.errors.NotNullViolation: null value in column "account_type" of relation "account_account" violates not-null constraint
DETAIL: Failing row contains (2315, null, 1, 1, null, null, null, t, f, f, 2026-02-17 05:53:58.84587, 2026-02-17 05:53:58.84587, no, f, null, null, null
```
opw-5913248
upg-3879881
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#249211This update resolves an error that occurred when users reviewed eMPF contribution reports. Specifically, the system was attempting to access employee information without it being properly set, leading to a system error. The fix ensures a user-friendly error message is displayed, prompting the user to correctly populate the employee details before reviewing the report.
Original PR description
Currently, an error occurs when the user checks the report line errors. **Steps to Reproduce:** - Install the `l10n_hk_hr_payroll_empf` module with demo data. - Switch to the `Hong Kong` company. -…
Currently, an error occurs when the user checks the report line errors. **Steps to Reproduce:** - Install the `l10n_hk_hr_payroll_empf` module with demo data. - Switch to the `Hong Kong` company. - Go to `Payroll` > `Reporting` > `Hong Kong` > `eMPF Contributions`. - Create a record by setting the `Scheme` and adding a `contribution line`. - Ensure that the employee and payslip fields are empty in the contribution line. - Click on `Validate`, then click on the `error icon` on the report line. `ValueError: Expected singleton: hr.version()` This error occurs when the user manually adds a line and checks the errors on it.. The system attempts to open the employee record from the version [1], but the version is not set [2] on the line because there is no employee. And it raise the error [3]. This commit ensures that when checking errors, if the version is not set on the line, a UserError is raised, prompting the user to set the employee on the line. It also corrects a typo in the status message. [1]- https://github.com/odoo/enterprise/blob/7889b2b0b3d13b32e6e36e616e20379d8c8f8812/l10n_hk_hr_payroll_empf/model/l10n_hk_empf_contribution_report_line.py#L219 [2]- https://github.com/odoo/enterprise/blob/7889b2b0b3d13b32e6e36e616e20379d8c8f8812/l10n_hk_hr_payroll_empf/model/l10n_hk_empf_contribution_report_line.py#L142-L156 [3]: https://github.com/odoo/odoo/blob/98855c6b70df24500babe6027109aa9e17431ec1/addons/hr/models/hr_version.py#L609-L611 Forward-Port-Of: odoo/enterprise#116607
This update fixes a bug that prevented accurate IT tax closing validation, particularly when dealing with quarterly VAT reporting in Italy. The changes ensure correct handling of year-end gaps and utilize debit/credit columns in reports, preventing errors and improving the reliability of tax calculations.
Original PR description
Description of the issue this commit addresses: The IT tax closing validation compared month numbers only, which broke across year boundaries and could reject valid quarterly progressions. It also assumed a balance column existed in monthly VAT report lines, but this report uses debit/credit columns, which could trigger a traceback. --- Desired behavior after this commit is merged: This commit computes the period gap with year-aware month deltas and aligns the allowed gap with periodicity (monthly or quarterly). It also checks VP lines using balance when present, or debit/credit as fallback, preventing crashes and ensuring consistent tax closing validation. --- opw-6131080 Forward-Port-Of: odoo/enterprise#117428
This update resolves an issue where account reconciliation lines remained incorrectly marked as reconciled after being deleted. The fix ensures that matching numbers are properly cleared from related account move lines, preventing misleading UI displays and maintaining data integrity. This improves the accuracy of financial reporting.
Original PR description
### Description `account.full.reconcile` has no `unlink()` override, so when the record is removed PostgreSQL nulls `full_reconcile_id` on the linked `account.move.line` rows via the default…
### Description
`account.full.reconcile` has no `unlink()` override, so when the record is removed PostgreSQL nulls `full_reconcile_id` on the linked `account.move.line` rows via the default `ondelete='set null'` FK rule, but `matching_number` is a plain `fields.Char` that nobody recomputes. The line ends up with a decimal `matching_number` (the id of the deleted full) while `full_reconcile_id` is `False`, no partials point to it and `amount_residual` is the full open amount. The line is rendered as reconciled in the UI even though the reconciliation is gone.
This PR mirrors `account.full.reconcile.create()`'s contract on the unlink path: invoke `_update_matching_number(amls)` after the records are removed, so every previously-linked line is cleaned. The integrity check `_constrains_matching_number` is also extended with `full_reconcile_id` in its `@api.constrains` tuple, so future ORM writes that desync the field surface the inconsistency immediately.
### Steps to reproduce
A single-call reproducer on a vanilla `19.0-all` runbot, no third-party modules:
```python
company = env.ref('base.main_company') # USD company
partner = env['res.partner'].create({'name': 'demo'})
# Foreign currency rates with a sharp move so the payment generates an FX diff
env['res.currency.rate'].create([
{'currency_id': env.ref('base.EUR').id, 'name': '2026-01-15', 'rate': 0.90, 'company_id': company.id},
{'currency_id': env.ref('base.EUR').id, 'name': '2026-03-15', 'rate': 1.20, 'company_id': company.id},
])
inv = env['account.move'].create({
'move_type': 'out_invoice', 'partner_id': partner.id,
'currency_id': env.ref('base.EUR').id,
'invoice_date': '2026-01-15', 'date': '2026-01-15',
'journal_id': env['account.journal'].search([('type','=','sale')], limit=1).id,
'invoice_line_ids': [(0,0,{'name':'x','quantity':1,'price_unit':1000.0})],
})
inv.action_post()
env['account.payment.register'].with_context(
active_model='account.move', active_ids=inv.ids
).create({'payment_date': '2026-03-15'}).action_create_payments()
recv = inv.line_ids.filtered(lambda l: l.display_type == 'payment_term')
full = recv.full_reconcile_id
assert full and recv.matching_number == str(full.id)
full.unlink() # the bug detonator
recv.invalidate_recordset()
assert recv.matching_number is False # FAILS without this PR
assert not recv.full_reconcile_id
```
Before the PR `recv.matching_number` keeps the decimal id of the deleted `account.full.reconcile`. After the PR it is cleared together with `full_reconcile_id`.
### Diagnostic query
```python
env['account.move.line'].search([
('matching_number', '!=', False),
('matching_number', 'not like', 'P%'),
('matching_number', 'not like', 'I%'),
('full_reconcile_id', '=', False),
])
```
Returns lines in the orphan state on any database.
### Impact
Observed on a real production database: 142 `account.move.line` records in this orphan state accumulated over ~13 days of normal accounting activity, on receivable, payable and bank accounts. All those lines display as reconciled in the UI while the underlying reconciliation is gone. Empty `account.full.reconcile` rows are also left behind.
### Tests
`addons/account/tests/test_account_move_reconcile.py::TestAccountMoveReconcile::test_full_reconcile_unlink_clears_matching_number`
### Linked
* Bug report: closes #264790
The change is a single-file 13-line `unlink()` override plus a one-character extension to an existing `@api.constrains` tuple. No data migration is needed for new databases; existing orphans on databases that hit the bug before the fix lands can be cleaned with a one-off:
```python
env['account.move.line'].search([
('matching_number', '!=', False),
('matching_number', 'not like', 'P%'),
('matching_number', 'not like', 'I%'),
('full_reconcile_id', '=', False),
]).write({'matching_number': False})
env['account.full.reconcile'].search([
('reconciled_line_ids', '=', False),
('partial_reconcile_ids', '=', False),
]).unlink()
```
Forward-Port-Of: odoo/odoo#264805This update fixes a problem where preparation displays (PDIS) weren't correctly updated when transferring, merging, or modifying orders in the POS system. Previously, new PDIS were created instead of reusing existing ones, leading to inconsistencies between the POS and kitchen screens. Now, PDIS are synchronized across all table actions, ensuring accurate kitchen order information.
Original PR description
Task: [#5005179](https://www.odoo.com/odoo/1737/tasks/5005179) --- When executing table actions such as transfer, merge, link, or unlink, the related Preparation Displays (PDIS) were not being updated. This caused inconsistencies between the POS orders and the kitchen screens. Also, when merging or linking orders and cancelling some lines, a new `pdis_order` was created instead of reusing the existing one. This fix ensures that PDIS are correctly synchronized and notified on any table actions. Forward-Port-Of: odoo/odoo#236613 Forward-Port-Of: odoo/odoo#233630
This update fixes a bug where Preparation Displays (PDIS) weren't correctly updated during table actions like transferring or merging orders. Previously, new PDIS were created instead of reusing existing ones, leading to inconsistencies. Now, PDIS are synchronized across all table actions, ensuring accurate information on both the POS and kitchen screens.
Original PR description
Task: [#5005179](https://www.odoo.com/odoo/1737/tasks/5005179) --- When executing table actions such as transfer, merge, link, or unlink, the related Preparation Displays (PDIS) were not being updated. This caused inconsistencies between the POS orders and the kitchen screens. Also, when merging or linking orders and cancelling some lines, a new `pdis_order` was created instead of reusing the existing one. This fix ensures that PDIS are correctly synchronized and notified on any table actions. Forward-Port-Of: odoo/enterprise#99975 Forward-Port-Of: odoo/enterprise#98374
This update resolves a problem where kiosk transactions would unexpectedly disconnect, leading to lost sales. The update also improves the user experience by providing clearer error messages when issues occur during transactions. This ensures smoother operation for self-order kiosks.
Original PR description
This PR fixes the scneario when the terminal transaction times out during kiosk request. It also adapts the error messages shown to the user whenever an error occurs community: https://github.com/odoo/odoo/pull/249101 task-5946033 Forward-Port-Of: odoo/enterprise#107709
This update corrects a bug where refund actions were incorrectly triggering the cancellation of original invoices. The fix ensures that the automatic CFDI cancellation process only applies to legitimate invoice replacements, preventing unintended consequences for credit notes and other refund-related transactions. This improves the accuracy of financial reporting and reduces potential disruptions to business processes.
Original PR description
Issue: Implementation of automatic CFDI cancel flow of an invoice substituted by a new one accidentally resulted in sending credit notes created from an invoice also triggering cancellation of the original. Solution: adding a check to only apply to invoice replacements and not refunds. ticket-6245456 Forward-Port-Of: odoo/enterprise#118327
This update fixes a problem where backorders created during point-of-sale (POS) transactions weren't properly linked to the original order. Now, all backorder pickings are correctly associated with the POS order, improving inventory accuracy and reporting in the Point of Sale module. This ensures consistent tracking of sales and reduces potential discrepancies.
Original PR description
The delivery transfer for a product tracked by serial number is not linked to the POS order when there is no available stock. When validating a POS delivery in real time, stock can split the transfer…
The delivery transfer for a product tracked by serial number is not linked to the POS order when there is no available stock. When validating a POS delivery in real time, stock can split the transfer into a completed picking and a backorder (e.g. one line fully delivered with lots, another serial-tracked line with no stock and no serial number). Steps to reproduce: ------------------- * Setup two products: one tracked by qunatity with some quantity on-hand an other tracked by SN but no quantity on-hand * Open Pos * Sell in one order, both products without providing SN * Validate payment * Open Inventory: two deliveries sould exist under Inventory Overview of PoS Orders > Observation: The first picking shows the POS order as Source Document but the backorder has no source document and is not linked to the POS order. Why the fix: ------------ Pos Origin (Source Document, POS order, session) was only written on the pickings returned by `_create_picking_from_pos_order_lines`, which did not include pickings created during `_action_done()`. Extend the write to the initial pickings and their backorders so every transfer stays tied to the originating `pos.order`. opw-6090606 Forward-Port-Of: odoo/odoo#266111 Forward-Port-Of: odoo/odoo#259370
This change optimizes the process of exporting large datasets in Odoo reports. Previously, the system used a method that consumed excessive memory, leading to potential errors with large exports. The update batches export calls, reducing memory usage and improving export speeds.
Original PR description
When exporting a number N of records as XLSX or CSV file, we call the export_data() method for the N records at the same time. This method prefetches the selected fields for all the records which can lead to memory limit errors when N is too large. We propose to batch this call and invalidate the recordsets between batches. Benchmarks ----------- Execution time: | No records | Before PR | After PR | |------------|-----------|----------| | 70 260 | 3.82 s | 3.94 s | | 228 116 | 18.71 s | 19.36 s | | 394 381 | 31.02 s | 32.67 s | Memory usage: | No records | Before PR | After PR | |------------|-----------|----------| | 70 260 | 316.0 MB | 273.5 MB | | 228 116 | 796.9 MB | 620.8 MB | | 394 381 | 1.3 GB | 947.7 MB | opw-5881026 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#266078 Forward-Port-Of: odoo/odoo#257333
This update fixes an issue where invoices imported from UBL files were incorrectly calculating prices due to a missing discount application. The change ensures that discounts from AllowanceCharges are accurately added to the PriceAmount, resulting in correct invoice pricing. This resolves a problem where invoices displayed the wrong total amount.
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 Forward-Port-Of: odoo/odoo#258964
This fix resolves an issue where confirming a sales order would only create one lead, even when multiple event registrations were involved. The update now correctly creates multiple leads when multiple event registrations are associated with a single order, ensuring accurate lead tracking for event sales. This improves the reliability of lead generation from sales orders.
Original PR description
# How to reproduce - Install the Events, Porject & CRM apps - Create two event A & B with tickets that can be purchased - Go to Events > Configuration > Lead Generation - Create a Lead Generation…
# How to reproduce - Install the Events, Porject & CRM apps - Create two event A & B with tickets that can be purchased - Go to Events > Configuration > Lead Generation - Create a Lead Generation Rule with : - Create : Per Order - When : Attendees are created - Event : None - Create a new quotation with two lines : - Product : Even Registration for event A 1st, then B - Confirm the SO # The problem A traceback will appear # Cause of the issue When confirming the SO, we create `event.registrations`s that will check for lead generation rules and create or update `crm.lead`s accordingly : https://github.com/odoo/odoo/blob/3bf89b4f467390807c20f7b007a875a77542e76f/addons/event_crm/models/event_registration.py#L35 We will then group the registrations by leads & grouping model : https://github.com/odoo/odoo/blob/3bf89b4f467390807c20f7b007a875a77542e76f/addons/event_crm/models/event_lead_rule.py#L166 For all groups, if the lead does not exist, we create one : https://github.com/odoo/odoo/blob/3bf89b4f467390807c20f7b007a875a77542e76f/addons/event_crm/models/event_lead_rule.py#L184-L187 `_get_lead_values()` works fine with multiple `event.registrations`s, but crashes when those registrations does not have all the same event, which is our case : https://github.com/odoo/odoo/blob/3bf89b4f467390807c20f7b007a875a77542e76f/addons/event_crm/models/event_registration.py#L170 # Proposed solution Since we have multiple events and leads are associated to a single event : https://github.com/odoo/odoo/blob/3bf89b4f467390807c20f7b007a875a77542e76f/addons/event_crm/models/crm_lead.py#L11 We group the registrations by event and create multiple leads accordingly opw-6167518 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265017
This update resolves a memory issue that could cause invoice imports to fail with large product catalogs. The fix uses a more efficient batch processing method to reduce unnecessary calculations and memory usage, resulting in improved stability and performance.
Original PR description
Before this commit, for DBs with a very large number of products it was possible for the thread to run out of memory when importing an invoice or a bill. The reason is that the name on…
Before this commit, for DBs with a very large number of products it was possible for the thread to run out of memory when importing an invoice or a bill. The reason is that the name on product.product is non stored and computed. This leads to tons of recomputes, which in turn leads to reads and stores in cache of the underlying `product.product`, which down the line uses up all of the available memory for the thread. The proposed method uses batches instead of a `search_fetch` as the latter would not solve the recompute problem and hence the underlying memory problem. Another alternative approach could be going straight for the `product.template.name`, but that approach might introduce a loss of precision or functionality when searching for products at invoice import. Here is the memory graph from memray before the fix: <img width="1106" height="450" alt="opw-6168737-memray-pre-fix" src="https://github.com/user-attachments/assets/f971dc4d-aa09-41e3-a8c5-e5ca53f9786d" /> And here is the same graph after the fix: <img width="1106" height="450" alt="opw-6168737-memray-post-fix" src="https://github.com/user-attachments/assets/0a784cdc-9b40-498b-bbcb-89114eec1ec9" /> We can see a much lower peak memory usage after the fix. We an also observe that the memory complexity shifts from `O(n)` to `O(1)`, with `n` being the number of `product.product` records stored in the DB. For both presented graphs, the same, unaltered database was tested. The database contains 389 467 `product.product` records. opw-6168737 Forward-Port-Of: odoo/odoo#265639 Forward-Port-Of: odoo/odoo#262591
This fix ensures that account moves generated during inventory valuation use the correct company – the main branch company – instead of the parent company. This resolves an access error when navigating to the inventory valuation view, ensuring accurate financial reporting. The change updates how the company ID is determined during account move creation.
Original PR description
**Steps to reproduce:** - create a new company A - in the branch tab, create a new branch A for this company - create a warehouse for the company A and a warehouse for the branch A - from the company…
**Steps to reproduce:** - create a new company A - in the branch tab, create a new branch A for this company - create a warehouse for the company A and a warehouse for the branch A - from the company A, in settings for the 'fiscal localization' set Package : Generic Chart of account, if not already set (to have account journals). From the branch A: - create a storable product with standard perpetual category - set a cost of 10 - confirm a PO for 10 and validate delivery - navigate to 'inventory valuation' Make sure the branch A is the main company, but both branch A and company A are selected: - click on generate entry - click on the 'Other Info' tab **Current behavior:** The company of the account move is the parent company (Company A) **Expected behavior:** It should be the branch A. (As it is the case if only branch A is selected when clicking on "Generate entry") IAs a consequence, f you click on 'Inventory Valuation' on the top left to go back to the view, you will have an access error. **Cause of the issue:** When computing the company_id on the account move, move.journal_id.company_id will be the parent company because the journal_id of the branch is the one of the parent company (by default). So we will call _accessible_branches() on the parent company. https://github.com/odoo/odoo/blob/661ddbb7f12e32394a3c11b5a4cd2f38a9e156f5/addons/account/models/account_move.py#L878-L881 Inside __accessible_branches(), 'accessible' will be based on self.env.companies https://github.com/odoo/odoo/blob/661ddbb7f12e32394a3c11b5a4cd2f38a9e156f5/odoo/addons/base/models/res_company.py#L430-L439 (which is based on 'allowed_company_ids' in the context. https://github.com/odoo/odoo/blob/661ddbb7f12e32394a3c11b5a4cd2f38a9e156f5/odoo/orm/environments.py#L266) So the return value of __accessible_branches() will be a list with 2 ids, the one of the parent company and the one of the branch. And we will use the first element of this list, which will be the parent company_id, in _compute_company_id to set the company of the account move. **fix:** When fetching the data for the inventory valuation view, only the data from the main company selected matters, https://github.com/odoo/odoo/blob/dd84309df7fd39e9e97ed02d135d25b211085135/addons/stock_account/report/stock_valuation_report.py#L13 Therefore, when creating the account move the company of the move should be the main company. We already did something very similar in this PR https://github.com/odoo/odoo/pull/262776 where we modified the context in action_close_stock_valuation() before calling _action_close_stock_valuation() https://github.com/odoo/odoo/blob/43f5ceadbc1f7df9898c327bf65bffdbe9860c1c/addons/stock_account/models/res_company.py#L56 opw-6144294 Forward-Port-Of: odoo/odoo#263828
This update resolves an issue where the withholding tax base amount on invoices could exceed the total invoice amount due to rounding discrepancies. The fix limits the withholding base amount to prevent over-calculation, ensuring accurate invoice totals and compliance. This improves financial reporting accuracy.
Original PR description
**PROBLEM** In some case, because of rounding issues, the withholding base amount can be bigger than the total amount of the invoice, which should not be the case. **STEP TO REPRODUCE** 1. Install…
**PROBLEM** In some case, because of rounding issues, the withholding base amount can be bigger than the total amount of the invoice, which should not be the case. **STEP TO REPRODUCE** 1. Install l10n_pe_edi 2. Create an invoice with those 2 lines: qty: 300, unit_price: 0.481936, tax: VAT 18% + 3% IGV Withholding qty: 300, unit_price: 0.747376, tax: VAT 18% + 3% IGV Withholding 3. Confirm the invoice, and send the xml (if this fail, you may have to change the name of the invoice, using odoo inspector or other means). 4. Open the xml, and notice the base amount for the allowance on the document level is 435.18 which is bigger than the invoice payable amount. **CAUSE** We exclude the withholding taxes to compute the invoice taxInclusiveAmount. When computing this amount, we round the line base and the tax total of the VAT 18% tax leading to the result of 435.17. When creating the allowance node for the Withholding taxes, the base used for the withholding taxes is the sum of the line base, and the tax total of previous tax NOT rounded. There is no easy way to change the withholding tax computation, so we just limit the base to not be bigger than the invoice total when there is rounding issues. opw-6010388 Forward-Port-Of: odoo/enterprise#113689
This update resolves an issue where payments weren't automatically linked to invoices when an invoice was created before the payment fully processed. This ensures accurate reconciliation of payments and invoices, preventing potential accounting discrepancies. The fix guarantees that all payments are correctly associated with their corresponding invoices.
Original PR description
Steps to reproduce: - Ensure Automatic Invoice setting is on - Create sales order for product with ordered quantites invoicing policy - Generate a Payment Link - Pay with the ACH Direct Debit method via a provider (e.g. Stripe) - While the payment is processing, confirm the sales order, create an invoice, confirm the invoice Current Behavior: When the payment is finished processing, the payment is not automatically linked to the corresponding invoice Expected Behavior: When the payment is finished processing, the payment should be linked to the invoice despite it being created by a user Explanation: The payment transaction's link to invoice_id is severed in PaymentTransaction._invoice_sale_orders if an invoice is created before the payment is cleared. This will eventually lead to the account.payment created automatically later on not being reconciled with the invoice. opw-6087656 Forward-Port-Of: odoo/odoo#264800
This update resolves a bug where resetting payroll work entries caused them to disappear due to mismatched time zone calculations. The fix ensures work entries are correctly localized using the user's time zone, preventing data loss and improving payroll accuracy. This impacts the way employees' work hours are recorded and processed.
Original PR description
Setup: Set the work entry source to attendance for an employee with active contract and change his timezone so that it differs from the working schedule one. Reset previous/next day delete Work Entry (payroll) - Step to reproduce: after an attendance was created, go to "Work Entries" in payroll, select the previous/next day and hit "Reset Selected Work Entries". The Work Entry will disappear. - Cause: reset window computed with calendar tz and work entry computed with user tz - Solution: localize work entries using calendar or user tz - Test: testing positive ans negative tz in hr_work_entry_attendance (enterprise) Task: 6072325 Forward-Port-Of: odoo/odoo#257309
This update resolves a bug where the 'Reset Selected Work Entries' function in the payroll module was unexpectedly deleting work entries due to incorrect time zone handling. The fix ensures accurate work entry management by using the correct calendar time zone, preventing data loss and improving payroll accuracy.
Original PR description
Setup: Set the work entry source to attendance for an employee with active contract and change his timezone so that it differs from the working schedule one. Reset previous/next day delete Work Entry (payroll) - Step to reproduce: after an attendance was created, go to "Work Entries" in payroll, select the previous/next day and hit "Reset Selected Work Entries". The Work Entry will disappear. - Cause: domain to nullify using wrong tz - Solution: adjust domain to use calendar tz - Test: testing positive ans negative tz in hr_work_entry_attendance (enterprise) Task: 6072325 Forward-Port-Of: odoo/enterprise#114148
This update resolves a printing problem reported by a client who was unable to print without LNA. The fix addresses a missing check that was causing the issue, ensuring consistent printing functionality. This improves the reliability of the POS system for all users.
Original PR description
Based on the ticket below the client is experiencing an issue when printing without LNA. This PR fixes the missing key check opw-https://www.odoo.com/odoo/project/49/tasks/6232008 Forward-Port-Of: odoo/enterprise#118005
1 change
Resolved issues and error corrections
This update resolves a potential issue that caused Out of Memory errors during the installation of the `sale_subscription` module on databases with many sales orders. The fix ensures that newly added fields are correctly initialized to 'null' during installation, preventing performance bottlenecks and installation failures.
Original PR description
### Description: Installing `sale_subscription` on databases with a large number of `sale.order` and `sale.order.line` can cause Out of Memory (OOM) errors. The issue comes from two stored compute fields, `last_invoiced_date` and `plan_id`. Since these depend on newly added fields, they should default to `null` during installation. ### Reference: opw-6201267 Forward-Port-Of: odoo/enterprise#118203 Forward-Port-Of: odoo/enterprise#118008
5 changes
Resolved issues and error corrections
This update resolves an issue where delivery orders for serial-tracked products could be completed without recording the necessary serial numbers. The fix ensures that when a user removes all serial numbers from a move line during a delivery order creation, the system prevents the order from being validated as 'done' without a serial number recorded. This maintains data accuracy and compliance.
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 Forward-Port-Of: odoo/odoo#266394
This update fixes an issue where UBL invoice imports were incorrectly calculating prices due to a missing discount application. The change ensures that discounts from AllowanceCharges are properly added to the PriceAmount, resulting in accurate invoice pricing. This resolves a problem where invoices were created with the wrong total price.
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 Forward-Port-Of: odoo/odoo#258964
This update resolves an issue where invoices with excessively long item descriptions were being rejected by the Kenyan Revenue Authority (KRA) eTIMS system. The fix truncates the description to meet the 200-character limit specified by eTIMS, ensuring successful invoice submission and avoiding delays. This prevents potential disruptions to tax reporting.
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
This update dynamically syncs product tags with UrbanPiper, resolving an issue where a single, hardcoded tag was used. Now, users can define relevant tags based on their tax settings and aggregator needs, ensuring UrbanPiper receives the correct information for accurate order processing.
Original PR description
Before this commit: ------------------------------------------ - The UrbanPiper payload used a hardcoded tag when the tax percentage was not 5%. - There was no mechanism to add additional tags based on providers, even though UrbanPiper supports multiple tags. After this commit: ------------------------------------------ - Tags are now dynamically handled using the Tag field in the product. - Users can define tags according to their tax configurations and aggregator requirements. - UrbanPiper only accepts relevant tags (default or provider-specific). task - 5154061 Forward-Port-Of: odoo/enterprise#107038 Forward-Port-Of: odoo/enterprise#96742
This update fixes an issue where payments weren't automatically linked to invoices when invoices were created before the payment was fully processed. Now, payments are correctly associated with the invoice, ensuring accurate accounting and reconciliation, particularly for automated invoicing setups.
Original PR description
Steps to reproduce: - Ensure Automatic Invoice setting is on - Create sales order for product with ordered quantites invoicing policy - Generate a Payment Link - Pay with the ACH Direct Debit method via a provider (e.g. Stripe) - While the payment is processing, confirm the sales order, create an invoice, confirm the invoice Current Behavior: When the payment is finished processing, the payment is not automatically linked to the corresponding invoice Expected Behavior: When the payment is finished processing, the payment should be linked to the invoice despite it being created by a user Explanation: The payment transaction's link to invoice_id is severed in PaymentTransaction._invoice_sale_orders if an invoice is created before the payment is cleared. This will eventually lead to the account.payment created automatically later on not being reconciled with the invoice. opw-6087656 Forward-Port-Of: odoo/odoo#264800
2 changes
Resolved issues and error corrections
This update resolves an issue where account consolidation reports incorrectly excluded accounts without a code on the selected company. The fix ensures that all relevant accounts are included in the consolidation, leading to more accurate financial reporting. This improves the reliability of consolidated reports for financial analysis.
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…
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-6204601
Forward-Port-Of: odoo/enterprise#117103This update resolves an issue where '&' characters in partner names and addresses were incorrectly replaced, leading to bank file rejections. The fix ensures '&' is preserved in human-readable fields, aligning with SEPA standards and preventing export failures. This improves data accuracy for international payments.
Original PR description
Problem: The previous fix (replacing '&' with '+' in _replace_characters_SEPA) was applied globally, affecting both reference/identifier fields and human-readable fields such as <Nm> (partner name)…
Problem:
The previous fix (replacing '&' with '+' in _replace_characters_SEPA) was applied globally, affecting both reference/identifier fields and human-readable fields such as <Nm> (partner name) and address lines.
As a result, a partner named "test & test GMBH" was exported as:
<Nm>test + test GMBH</Nm>
instead of the expected:
<Nm>test & test GMBH</Nm>
This caused bank file rejections because '&' is the correct XML encoding of '&' and is accepted by banks in human-readable fields.
Root cause:
ISO 20022 / EPC217-08 distinguishes two categories of data elements:
- Reference/identifier fields (InstrId, Ustrd, etc.): must use the restricted basic Latin character set — '&' is not allowed and must be replaced with '+'.
- Human-readable fields (Nm, AdrLine, etc.): may contain the extended Latin character set — '&' is valid and must be preserved so lxml can XML-escape it to '&' in the output.
Fix:
Revert the global '&' → '+' replacement in _replace_characters_SEPA so that '&' is preserved for name/address fields. The replacement of '&' with '+' for reference/identifier fields is already handled explicitly at the call sites in _get_CdtTrfTxInf (InstrId, Ustrd) via .replace('&', '+') before sanitize_communication is called.
ref commit : https://github.com/odoo/enterprise/pull/110809/changes/9e698e4ac9fdf66189ff6712f90a144560a1b484
documentation https://www.europeanpaymentscouncil.eu/sites/default/files/KB/files/EPC217-08%20Draft%20Best%20Practices%20SEPA%20Requirements%20for%20Character%20Set%20v1.1.pdf:
Forward-Port-Of: odoo/enterprise#118427
Forward-Port-Of: odoo/enterprise#11540917 changes
New functionality added to Odoo
This update allows users to import their existing websites directly from Ghost, a popular blogging platform. Users will need to provide their Ghost API key during the import process. This expands website generation options and simplifies content migration.
Original PR description
Allows the user to import website from the Ghost blog platform. They must provide their API key for this service.
This update introduces a new feature allowing users to dictate messages within the AI chat interface. Simultaneously, the underlying voice recording system has been strengthened to support this functionality. This improves accessibility and efficiency for users interacting with the AI chat.
Original PR description
This commit adds a native voice-to-text dictation feature, while hardening the underlying community voice recorder architecture to support it. task-5948112 community https://github.com/odoo/odoo/pull/253611
Enhancements to existing features
This update simplifies how contract availability is displayed in the Gantt view, making it easier to visualize resource scheduling. The changes include refactoring test cases and adding new functionality to integrate contract unavailabilities directly into the Gantt chart. This improves the overall planning process and resource management.
Original PR description
<h3><b>[REF] planning: refactor changes from planning_contract</b></h3> Contract unavailabilities have been simplified using gantt unavailabilities. The hoot test cases have been refactored as we have unified the mock models. Moved a test case to community. --- <h3><b>[IMP] project_enterprise_hr: add contract based graying in gantt view</b></h3> Added contract unavailabilities through gantt unavailabilities. Added some hoot test cases. task-3885152
This update refactors the existing Hong Kong AutoPay module to create a more flexible and extensible system. The changes broaden support beyond just HSBC, allowing for easier integration with other banks in Hong Kong and future expansion. This improves the overall automation of payment processing for Hong Kong businesses.
Original PR description
Refactor the hsbcnet module, aiming to: - Transform it into a general 'Hong Kong AutoPay' module, covering more than just HSBC - Re-design the module to be easily extensible for future support of extra banks. task-6007861
This update provides users with the option to view financial changes between periods as either a percentage or a precise monetary amount. Previously, only percentage changes were available, which could be misleading when tracking large financial impacts. This change offers a more direct and accurate representation of the actual financial difference.
Original PR description
Right now the period-comparison filter allows for a % change to be visible as an additional column between two periods. Sometimes, if you are trying to keep track of large figures and want to see the real world financial impact of changes between periods, a percentage can't help. This commit allows for users to decide if they want a **Percentage** comparison (the default that preserves the current behavior) or an absolute **Amount** shown via the comparison filter. As we are dealing with currency, the amount column will show the real v1 - v2 difference displayed as a monetary field and works off the source column to properly support multi-currency reports. In addition, it takes into account the rounding unit for better display views. The column header switches between "Change (%)" and "Change (<currency_symbol>)". task-6116196
This update enhances the usability of the Manufacturing, Quality, and Shop Floor apps by refining the Gantt view scales and improving the Quality Point form. Specifically, the Quality Check form now includes access to worksheets and attachments, streamlining the inspection process and aligning the Shop Floor interface for a more consistent user experience.
Original PR description
This PR improves the user experience in the Manufacturing, Quality and Shop Floor app and adds the worksheet to the quality check form. Task-id: 6164381
This update introduces a new system for managing salary rules within Odoo's payroll, allowing for more flexible and granular control over employee compensation. Specifically, it enables the definition of multiple 'structures' associated with salary rules, improving the handling of diverse payroll scenarios and supporting more complex business requirements. This change enhances the accuracy and adaptability of payroll calculations.
This update enhances the Odoo Enterprise website's SEO capabilities, allowing users to review and optimize their website's search engine ranking for each language they've enabled. This improvement ensures better visibility and potential customer acquisition across all supported languages, aligning with our global business strategy.
Original PR description
*: appointment_hr, test_appointment_full This commit ensures the user is able to review his SEO for each language installed for the website. task-4876478
This update ensures that companies can now initiate signature requests directly from the contact form, mirroring the functionality available for individual contacts. Previously, companies were excluded from this feature, which has now been implemented to align with their ability to act as signers. This improves the user experience for all company users.
Original PR description
The signature requests smart button on the contact form was previously hidden for companies and only displayed on individual contacts. Companies can also be signers, so the button is now shown for them as well. task-6235242
This update adjusts the order in which planning slots are displayed, prioritizing slots based on their start date and then by priority and ID. This change ensures that the most relevant planning slots are presented first, streamlining the planning process and improving efficiency.
Original PR description
This commit changes the default order set on `planning.slot` model to first order by start_datetime then priority and id. task-6176314
Resolved issues and error corrections
This update fixes an issue preventing users from importing emissions data within the ESG module. The change allows the 'import' action to appear in the COG menu, even with the 'create' attribute disabled, ensuring seamless data import functionality. This improves the usability of the ESG reporting features.
Original PR description
Before this commit, the "import" action of emissions in the ESG module was not visible in the COG menu. It is because the "create" attribute of the list view is disabled, which prevents the menu item from being displayed. With this commit, we override the standard behavior in this particular action, by allowing the import action to show up in the COG menu, even if the "create" attribute is disabled. version-19.1 Forward-Port-Of: odoo/enterprise#118004
This update fixes a bug where Preparation Displays (PDIS) weren't correctly updated during table actions like transferring or merging orders. Previously, new PDIS were created instead of reusing existing ones, leading to inconsistencies. Now, PDIS are synchronized across all table actions, ensuring accurate order information on both the POS and kitchen screens.
Original PR description
Task: [#5005179](https://www.odoo.com/odoo/1737/tasks/5005179) --- When executing table actions such as transfer, merge, link, or unlink, the related Preparation Displays (PDIS) were not being updated. This caused inconsistencies between the POS orders and the kitchen screens. Also, when merging or linking orders and cancelling some lines, a new `pdis_order` was created instead of reusing the existing one. This fix ensures that PDIS are correctly synchronized and notified on any table actions. Forward-Port-Of: odoo/enterprise#99975 Forward-Port-Of: odoo/enterprise#98374
This update corrects a bug where refund processing triggered the unintended cancellation of original invoices within the Mexican CFDI integration. The fix adds a check to ensure the automatic cancellation flow only applies to invoice replacements, preventing credit notes from causing incorrect cancellations. This ensures accurate accounting and avoids disruptions for users.
Original PR description
Issue: Implementation of automatic CFDI cancel flow of an invoice substituted by a new one accidentally resulted in sending credit notes created from an invoice also triggering cancellation of the original. Solution: adding a check to only apply to invoice replacements and not refunds. ticket-6245456 Forward-Port-Of: odoo/enterprise#118327
This update ensures that signatories receive the signed document and Certificate of Completion (COC) as email attachments after completing a signature request via WhatsApp. Previously, the system only sent a WhatsApp link, causing delays in receiving the official signed document. This change improves the user experience and compliance with standard document delivery processes.
Original PR description
Previously, if a signature request was completed via the WhatsApp channel, the system only sent a WhatsApp message containing a link to the document. It bypassed standard email delivery entirely, meaning signatories never received the actual signed PDF or the Certificate of Completion (COC) as attachments. This commit improves the completion flow across both the backend and the generated reports: - **Backend:** Refactored `_send_completed_documents_message` to always call `super()`. This ensures the final signed document and COC are reliably delivered as email attachments, even after the WhatsApp link is sent. - **Reports:** Inherited the `sign_request_logs` QWeb template. When `send_channel == 'whatsapp'`, the PDF now dynamically replaces the "Email Verification" headers and footnotes with "Phone Verification". Additionally, it replaces the generic checkmark with the signer's masked phone number. Task: 5951833
This update ensures that when a food delivery order is cancelled through the aggregator (Atlas), the corresponding order in the POS system is also correctly marked as cancelled. Previously, the POS order remained in an active state, leading to confusion. This change improves order visibility and accuracy for both staff and customers.
Original PR description
pos*: pos_urban_piper, pos_enterprise When a food delivery order is cancelled from the aggregator side, the PoS order remains active on the frontend instead of reflecting the cancelled state. Steps to reproduce: - Configure UrbanPiper with Atlas - Place an order via Atlas - Open the order from the notification bar - Cancel the order from Atlas Issues: - Cancelled orders continue to appear in `Draft` - Accepted/preparation orders are not cancelled on the preparation display Fix: - Synchronise the PoS order state with the delivery state on cancellation - Update preparation display orders when delivery orders are cancelled Task-6217704 Forward-Port-Of: odoo/enterprise#118294 Forward-Port-Of: odoo/enterprise#117374
This update resolves an issue where the timesheet timer wouldn't function when accessed from a subtask. The fix ensures the timer correctly opens and pre-fills with the subtask's project details, preventing a 'missing record' error. This improves the user experience for managing timesheets on subtasks.
Original PR description
**Problem:** Clicking the timesheet timer in the systray while viewing a subtask raises a MissingError, preventing the user from starting the timer. **Steps to reproduce:** 1. Open a project task…
**Problem:** Clicking the timesheet timer in the systray while viewing a subtask raises a MissingError, preventing the user from starting the timer. **Steps to reproduce:** 1. Open a project task that has subtasks 2. Click the subtasks smart button and open a subtask 3. Click the timesheet timer icon in the systray 4. Observe the "missing record" error **Current behavior:** The systray RPC fails with MissingError. **Expected behavior:** The timer opens, with the subtask's project and task prefilled. **Cause of the issue:** The frontend sends `currentState.active_id` regardless of the model it refers to. When the user navigates to a subtask via the smart button, `active_id` is the parent task's id. The systray controller then does `request.env['project.project'].browse(active_id)`, which returns a truthy recordset for an id that does not exist in `project_project`. Reading `.allow_timesheets` on that recordset triggers the DB fetch and raises MissingError. The same pattern exists in the `helpdesk_timesheet` override for both the `project.task` and `helpdesk.ticket` branches. **Fix:** Adding `.exists()` after the browse validates the recordset before any field access, so a stray `active_id` falls through to the task's own project (or ticket's project) instead of crashing. opw-6169548 Forward-Port-Of: odoo/enterprise#117039
This update resolves a bug where the Gantt view incorrectly displayed working hours for employees on public holidays. The fix converts all time zone calculations to UTC, ensuring accurate representation of unavailable time slots. This prevents employees from being incorrectly scheduled to work on holidays.
Original PR description
[FIX] hr_attendance_gantt: fix gantt view with public holidays Bug reproduction: 1 - Select flex schedule employee (or change its schedule to 40h flex one) and make its contract before 01/01/2026 2 -…
[FIX] hr_attendance_gantt: fix gantt view with public holidays
Bug reproduction:
1 - Select flex schedule employee (or change its schedule to 40h flex one) and make its contract before 01/01/2026
2 - Create a new public holiday on 01/01/2026 (from 00.00 to 23.59 or 23.55 (depends on version, it does not matter))
3 - in attendance app the cell from 00.00 to 01.00 seems white for that day and for selected employee (this cell seems like not holiday and employee can work)
Bug cause:
1 - After a long traceback, _gantt_unavailability in hr_attendance_gantt/HrAttendance, if an employee is flexible then unavailable_intervals is calculated with the Brussel time zone
2 - All other unavailable intervals are converted to the UTC in the function of _gantt_unavailability except in the final lines of the function.
3 - When the employee is flexible and since the conversion is not done in the final lines, it remains 1 hour more (UTC+1), it is from 1 am to 1 am of next day instead of 0 am to 23.59.
Bug solution:
1 - I converted the timezone to UTC to solve the problem.
task - 6067070
Forward-Port-Of: odoo/enterprise#1124935 changes
Enhancements to existing features
This update improves the speed of auditing large financial reports. Previously, navigating back and forth between reports and their details caused slow reloads and blank screens. Now, the system caches report data, speeding up the auditing process and making it more efficient.
Original PR description
When auditing large reports, users often navigate back and forth between the report and its underlying move lines. Each time the user returns to the report, it triggers a full reload, resulting in a blank screen and long wait time making auditing slow and painful. This commit caches the report information, and line expansion rpc calls in disk. RPC calls are being called asynchronously, and the report is updated if data changed. While data is being refreshed in the background, cached report is displayed along with a warning banner informing the user that report is being loaded. task-5145462
Resolved issues and error corrections
This update ensures that when a marketing automation email fails and is retried, it only resends to records within the original campaign filter, not the entire mailing template. Previously, clicking 'Retry' sent emails to all records matching the template, causing unintended distribution. This fix maintains accurate targeting and prevents wasted email sends.
Original PR description
Clicking Retry on a mailing tied to a marketing automation campaign resends the email to records outside the campaign filter instead of only the failed recipients. ### Steps to reproduce 1. Create a…
Clicking Retry on a mailing tied to a marketing automation campaign resends the email to records outside the campaign filter instead of only the failed recipients. ### Steps to reproduce 1. Create a marketing automation campaign with a filter. 2. Add an email activity and start the campaign. 3. Force at least one email to fail. 4. Click Retry on the mailing form. The email is sent to every record matching the mailing template, not just the failed ones. ### Cause When an activity runs, it computes the matching record ids from the campaign filter and calls `action_send_mail(res_ids)` with that explicit list. The Retry button calls `action_retry_failed`, which deletes the failed mails and traces, flips the mailing to `in_queue`, and lets the mass mailing cron resend it. That cron calls `_action_send_mail()` with no ids, so it falls back to the mailing template's own domain, which is unrelated to the campaign filter. ### Fix Override `action_retry_failed` for mailings tied to a marketing activity. Instead of requeuing through the mass mailing cron, reset the failed `marketing.trace` rows back to `scheduled`, cancel their already scheduled children so the next run does not double up, reactivate any participant that was marked `completed`, and trigger the marketing automation cron. That cron runs `execute_on_traces`, which re-applies the campaign filter before sending. Non automation mailings keep the original behavior via `super()`. opw-6010465
This update corrects a bug where refund processing triggered the unintended cancellation of original invoices in the Mexican CFDI module. The fix adds a check to ensure the automatic cancellation flow only applies to invoice replacements, preventing credit notes from causing incorrect cancellations. This ensures accurate financial reporting and avoids disruptions to business operations.
Original PR description
Issue: Implementation of automatic CFDI cancel flow of an invoice substituted by a new one accidentally resulted in sending credit notes created from an invoice also triggering cancellation of the original. Solution: adding a check to only apply to invoice replacements and not refunds. ticket-6245456
This update resolves a potential issue that caused Out of Memory errors during the installation of the `sale_subscription` module on databases with a large number of sales orders. The fix ensures that newly added fields are correctly initialized to 'null' during installation, preventing performance bottlenecks and installation failures.
Original PR description
### Description: Installing `sale_subscription` on databases with a large number of `sale.order` and `sale.order.line` can cause Out of Memory (OOM) errors. The issue comes from two stored compute fields, `last_invoiced_date` and `plan_id`. Since these depend on newly added fields, they should default to `null` during installation. ### Reference: opw-6201267 Forward-Port-Of: odoo/enterprise#118203 Forward-Port-Of: odoo/enterprise#118008
This update fixes a problem where users weren't notified when an expense's payment authorization status changed (e.g., cancelled). The update ensures that users receive timely updates about their expenses, improving accuracy and reducing potential issues. This resolves a previous bug where authorization updates were missed.
Original PR description
## [FIX] hr_expense_stripe: Fix error messages coherence Fix the incoherent punctuation ## [FIX] hr_expense_stripe: Fix reversed and expired authorizations Before this, when receiving an `issuing_authorization.updated` event, the event would be ignored and the user would never know that the expense had been cancelled opw-6210055
12 changes
New functionality added to Odoo
This update introduces a new module for generating ISO 20022 payment files specifically tailored for Swedish banks. It automates the creation of compliant XML files for domestic payments (Bankgiro, Plusgiro, BBAN) and includes validation rules to ensure accuracy and prevent errors.
Original PR description
**Summary** This PR introduces a new module that provides support for generating ISO 20022 payment files tailored for Swedish banks. It adds native support for domestic payment formats such as…
**Summary** This PR introduces a new module that provides support for generating ISO 20022 payment files tailored for Swedish banks. It adds native support for domestic payment formats such as Bankgiro, Plusgiro, and BBAN, including structural validation and checksum logic. The module is designed to work in conjunction with Odoo's account_iso20022 and l10n_se. **Features** - Payment file generation Generates ISO 20022-compliant XML files for Swedish banks Supports Bankgiro, Plusgiro, and structured BBAN domestic accounts - Payment batch splitting Automatically separates domestic and foreign payments in the same batch Produces one file per payment type (local/foreign), as required by banks - Account type detection and validation Auto-detects account type based on format and structure **Validates using:** Regex and Luhn for Bankgiro/Plusgiro Mod10 and Mod11 algorithms for BBAN based on bank specification Bank code validation via bank.code.range - Bank code integrity checks New model: bank.code.range Defines allowed clearing number ranges per country Prevents overlaps and out-of-bound values (e.g., SE: 1000–9999) - Treasury settings Lead time configuration for both domestic and international payments Allows scheduling of payments after due date, enabling payment planning - Views and configuration Admin views for managing banks, clearing intervals, and payment behavior System settings integrated via res.config.settings - Localization and data Includes translations (sv.po) and base POT Preloads Swedish bank list and clearing number ranges from CSV **Technical details** Depends on: account_iso20022, l10n_se Fully modular; integrates with existing payment batch and SEPA infrastructure No overrides of core logic – all extensions via inheritance Logging and warnings included for fallback cases (e.g. unparseable BBAN) Enforces validation at both form level and compute level **Example use case** A Swedish company processing supplier payments uploads a single batch containing both Swedish and EU vendors. This module: Detects Plusgiro and Bankgiro accounts Validates BBAN using Mod10 or Mod11 based on bank rules Applies company-defined lead times Splits the payments into two ISO 20022 files: one for Swedish banks, one for cross-border SEPA
Resolved issues and error corrections
This update fixes an issue where the calculation of gross total amounts with both line and global discounts was incorrect. The change ensures accurate calculations by reordering the discount application process, resulting in the correct total before taxes and discounts are applied. This improves invoice accuracy and reliability.
Original PR description
Problem: When both line discounts and global discounts are applied on a product in an invoice, the method `_add_and_round_raw_gross_total_excluded_and_discount` does not return the exact…
Problem: When both line discounts and global discounts are applied on a product in an invoice, the method `_add_and_round_raw_gross_total_excluded_and_discount` does not return the exact raw_gross_total_excluded before the modification done by other AccountTax helper methods, such as dispatching and squashing global discount lines. Current Behavior: The calculation is done in the wrong order of operations. For example, there is an invoice for Product A valued at $100 with a discount of 10% and a global discount of $10. The raw_total_excluded will be $80 after the both discounts. The discount_factor is based on only the line discount of 10%. The formula of the current calculation for raw_gross_total_excluded is: (raw_total_excluded / (1 - (line_discount / 100))) - global_discount = (80 / 0.90) - (-10) = 98.889 This does not equal the expected outcome of $100. Expected Behavior: Based on the previous example, the formula for the calculation should be: (raw_total_excluded - global_discount) / (1 - (line_discount/100)) = (80 - (-10)) / 0.9 = 100 The global discount needs to be added back to the raw_total_excluded to get the line discounted amount in order to divide by the discount_factor to gain the expected raw_gross_total_excluded before taxes and discounts. Steps to reproduce the issue: - Bug was encountered when implementing a global discount solution for l10n_co_dian. - Create an invoice with a product line and in-line discount and another line for global discount - Setup the base lines for the invoice and attempt the following: - _dispatch_global_discount_lines - _squash_global_discount_lines - _add_and_round_raw_gross_total_excluded_and_discount opw-5412446 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes a bug in the Mexican VAT (l10n_mx_edi) module that resulted in incorrect discount and subtotal calculations on invoices with both product and global discounts. The change ensures accurate test coverage and reliable invoice totals for Mexican businesses. This resolves a discrepancy in how discounts were applied.
Original PR description
Purpose: A bug was found in the calculation of the `raw_discount_amount` and `raw_gross_total_excluded` when `_add_and_round_raw_gross_total_excluded_and_discount` is called on an invoice that contains both product line discounts and global discounts. Therefore, the discount and subtotal amounts for the test case testing both line and global discounts need to be corrected to ensure accurate test coverage. opw-5412446
This update resolves a bug where payment transaction details weren't being saved correctly after payments were processed via polling. The fix ensures all transaction details, including card information, are now consistently saved regardless of the payment method (webhook or polling), improving data accuracy for reporting and reconciliation.
Original PR description
After odoo/odoo#236454, a bug was introduced where the transaction details would only be saved if the payment was resolved via webhook, not via polling. This commit fixes the issue by using the same field names in the webhook payload as is received from the polling endpoint. In addition, the card number and card brand fields are now saved too. opw-6244960 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an issue preventing kiosk app installations when a company logo was set. The fix ensures the standard app icon is always used, allowing users to correctly install the kiosk app from their browser. This improves the user experience for companies utilizing the self-order kiosk.
Original PR description
Currently, if a company has a logo, it is very likely that the kiosk app (pwa) cannot be installed. Steps to reproduce: ------------------- * In the company settings, set up a company logo…
Currently, if a company has a logo, it is very likely that the kiosk app (pwa) cannot be installed. Steps to reproduce: ------------------- * In the company settings, set up a company logo (screenshot size image) * Go to point of sale app, find the kiosk * Select "Open kiosk" * Select "Install app" > Observation: Instead of seeing the button to download the app you see "You can install the app from the browser menu" With company logo: <img width="545" height="219" alt="image" src="https://github.com/user-attachments/assets/03053242-235a-43dd-be2d-29bcec87da1f" /> Without: <img width="414" height="205" alt="image" src="https://github.com/user-attachments/assets/4cbd9ca7-3c91-4c04-89ab-3ef3ec7b4540" /> Why the fix: ------------ When the company has a logo, `company.uses_default_logo` is False which means we're trying to use to company logo as the app logo. When the company logo doesn't have a precise size the PWA beforeInstallPrompEvent is not triggered. If this event is not triggered, `_handleBeforeInstallPrompt` is not called and `state.isAvailable` is not set to true. https://github.com/odoo/odoo/blob/cdded72f0d7adfa3b3b19f6117905a273d7ef199/addons/web/static/src/core/pwa/pwa_service.js#L111 Which ultimately leads to not being able to see the button to download the app. After discussing, there's no real need to use the company logo anyway. Instead of seeing to resize it we'll just use the app icon all the time. opw-6111280
This update fixes an issue where expected working hours displayed in the Attendances Gantt view were inaccurate for employees with flexible schedules and non-UTC time zones. The fix ensures that hour calculations now correctly account for the user's local time, providing more reliable attendance data. This improves the accuracy of time tracking and reporting.
Original PR description
Steps to reproduce: 1. Ensure your browser is in a non-UTC timezone (e.g. Europe/Zurich) 2. Set an employee to have a flexible working schedule 3. Enter the Attendances app 4. When hovering over the employee in the gantt view, the expected hours do not match their working schedule When we calculate the expected hours for the Gantt view in attendances, we calculate this based on an incorrect number of attendance intervals given from _attendance_intervals_batch(). To ensure that we recieve accurate intervals, we need to ensure that we calculate intervals based on the correct date range with respect to the browsers timezone, instead of the UTC date range. [opw-6175441](https://www.odoo.com/odoo/my-tasks/6175441?debug=assets)
This pull request updates the o_spreadsheet library, addressing several issues related to spreadsheet formulas and pivot tables. It includes improvements for data export accuracy and stability, ensuring the spreadsheet feature continues to function reliably for users. The update also incorporates new features and skills related to Claude.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/50b85ba821 [REL] 18.0.69 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/50b85ba821 [REL] 18.0.69 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/bdbbd561b8 [FIX] formulas: add IFERROR second argument when exporting data [Task: 5993405](https://www.odoo.com/odoo/2328/tasks/5993405) https://github.com/odoo/o-spreadsheet/commit/6fab32ce9c [FIX] pivot: unused pivot detection with composed formula [Task: 6105894](https://www.odoo.com/odoo/2328/tasks/6105894) https://github.com/odoo/o-spreadsheet/commit/76db3fd593 [FIX] pivot: unused pivot detection with calculated measure [Task: 6105894](https://www.odoo.com/odoo/2328/tasks/6105894) https://github.com/odoo/o-spreadsheet/commit/cb7495111b [IMP] claude: add review skill [Task: 6223095](https://www.odoo.com/odoo/2328/tasks/6223095) https://github.com/odoo/o-spreadsheet/commit/6f9561dde5 [IMP] claude: add testing skill [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/9d85891b99 [IMP] claude: add CLAUDE.md file [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/56c4ce1c04 [IMP] packages: rolldown is released in 1.0.0 [](https://www.odoo.com/odoo/2328/tasks/) https://github.com/odoo/o-spreadsheet/commit/a0763ab621 [REL] 18.0.68 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/b9dbc33c4e [FIX] packages: update odoo dependencies [](https://www.odoo.com/odoo/2328/tasks/) https://github.com/odoo/o-spreadsheet/commit/9ee74660ae [FIX] package: update package-lock [](https://www.odoo.com/odoo/2328/tasks/) https://github.com/odoo/o-spreadsheet/commit/d0fca1409e [FIX] package: package install is broken [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/06413dab98 [REL] 18.0.67 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/533e5f08da [FIX] package: update package-lock.json [](https://www.odoo.com/odoo/2328/tasks/) https://github.com/odoo/o-spreadsheet/commit/090f75ba4d [FIX] package: husky should run at post install [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/2effff1d86 [FIX] workflow: fix the tag definition [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/6a24b125d4 [FIX] Workflow: fix missing permission to use OpenID Connect [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/d86edeb9f7 [FIX] workflow: Split the workflow in parallel jobs [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> Co-authored-by: Anthony Hendrickx (anhe) <anhe@odoo.com> Co-authored-by: Alexis Lacroix (laa) <laa@odoo.com> Co-authored-by: Lucas Lefèvre (lul) <lul@odoo.com> Co-authored-by: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya (rmbh) <rmbh@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@odoo.com> Co-authored-by: Rémi Rahir (rar) <rar@odoo.com> Co-authored-by: Pierre Rousseau (pro) <pro@odoo.com> Co-authored-by: Vincent Schippefilt (vsc) <vsc@odoo.com> Co-authored-by: Marceline Thomas (matho) <matho@odoo.com>
This update fixes an issue where intercompany sales and purchases with multiple identical products resulted in incorrect stock reservation during receipt picking. Specifically, the system was failing to properly reserve all units of a product when creating intercompany transactions with multiple lines of the same item. This ensures accurate stock tracking and order fulfillment for intercompany business operations.
Original PR description
…lit for same-product lines When doing an intercompany Sale->Purchase with multiple lines having the same products, the receipt picking would be incorrectly assigned: - Enable Inter-Company…
…lit for same-product lines
When doing an intercompany Sale->Purchase with multiple lines having the same products, the receipt picking would be incorrectly assigned:
- Enable Inter-Company Transactions on both companies (Create and validate)
- Create SO in company A to company B with 2 lines having the same product P, Confirm. => Delivery in company A, Purchase and Receipts in company will be created => The SO/PO/Delivery/Receipt will all have 2 lines
- Validate delivery => On the receipt, the 2 units of P are reserved on the 1st move, and the 2nd move is not reserved.
https://github.com/user-attachments/assets/b4816051-120e-4226-9228-fd552649d5ef
---
### Test result without fix:
```
2026-04-23 13:16:44,577 48027 INFO oes_test_18.0 odoo.addons.sale_purchase_stock_inter_company_rules.tests.test_inter_company_so_to_po: Starting TestInterCompanySaleToPurchaseWithStock.test_02_inter_company_multiple_lines_with_same_product ...
2026-04-23 13:16:44,949 48027 INFO oes_test_18.0 odoo.addons.sale_purchase_stock_inter_company_rules.tests.test_inter_company_so_to_po: ======================================================================
2026-04-23 13:16:44,949 48027 ERROR oes_test_18.0 odoo.addons.sale_purchase_stock_inter_company_rules.tests.test_inter_company_so_to_po: FAIL: TestInterCompanySaleToPurchaseWithStock.test_02_inter_company_multiple_lines_with_same_product
Traceback (most recent call last):
File "/home/odoo/Odoo/src/18.0/enterprise/sale_purchase_stock_inter_company_rules/tests/test_inter_company_so_to_po.py", line 109, in test_02_inter_company_multiple_lines_with_same_product
self.assertRecordValues(purchase_from_a.picking_ids.move_ids, [
File "/home/odoo/Odoo/src/18.0/odoo/odoo/tests/common.py", line 709, in assertRecordValues
self.assertSequenceEqual(expected_reformatted, record_reformatted, seq_type=list)
AssertionError: Lists differ: [{'pr[18 chars]0, 'quantity': 1.0}, {'product_uom_qty': 1.0, 'quantity': 1.0}] != [{'pr[18 chars]0, 'quantity': 2.0}, {'product_uom_qty': 1.0, 'quantity': 0.0}]
First differing element 0:
{'product_uom_qty': 1.0, 'quantity': 1.0}
{'product_uom_qty': 1.0, 'quantity': 2.0}
- [{'product_uom_qty': 1.0, 'quantity': 1.0},
? ^
+ [{'product_uom_qty': 1.0, 'quantity': 2.0},
? ^
- {'product_uom_qty': 1.0, 'quantity': 1.0}]
? ^
+ {'product_uom_qty': 1.0, 'quantity': 0.0}]
? ^
```
OPW-6145683This update ensures that payments made via ACH Direct Debit are automatically linked to the corresponding invoice, even if the invoice is created after the payment. Previously, this process was broken, leading to reconciliation issues. This change improves the accuracy of financial reporting and streamlines payment processing.
Original PR description
Steps to reproduce: - Ensure Automatic Invoice setting is on - Create sales order for product with ordered quantites invoicing policy - Generate a Payment Link - Pay with the ACH Direct Debit method via a provider (e.g. Stripe) - While the payment is processing, confirm the sales order, create an invoice, confirm the invoice Current Behavior: When the payment is finished processing, the payment is not automatically linked to the corresponding invoice Expected Behavior: When the payment is finished processing, the payment should be linked to the invoice despite it being created by a user Explanation: The payment transaction's link to invoice_id is severed in PaymentTransaction._invoice_sale_orders if an invoice is created before the payment is cleared. This will eventually lead to the account.payment created automatically later on not being reconciled with the invoice. opw-6087656 Forward-Port-Of: odoo/odoo#264800
This update ensures that the project associated with a Sale Order is automatically included in the generated Manufacturing Order, even with multi-step delivery routes (Pick + Deliver). Previously, the system didn't correctly propagate the project information, leading to missing project assignments. This change resolves a critical issue impacting order fulfillment accuracy.
Original PR description
### Issue before this commit: When confirming a Sale Order with multi-step delivery routes (Pick + Deliver), the generated Manufacturing Order did not inherit the project_id from the Sale Order, even…
### Issue before this commit: When confirming a Sale Order with multi-step delivery routes (Pick + Deliver), the generated Manufacturing Order did not inherit the project_id from the Sale Order, even though the project was correctly set on the SO. ### Steps to reproduce the issue: 1. Download Inventory, Sales, PLM, Project 2. Enable multi-step routes in settings and unarchive MTO from routes 3. Go to Products and modify 1. Furniture Assembly inserting Project in "Create on Order" attribute and a test project template 2. Drawer selecting MTO and Manifacture in Inventory tab 4. Create a new quotation inserting 2 products: Furniture Assembly and Drawer and confirm it 5. Go to "Manufacturing" smart button 6. See in Miscellaneous tab the Project is setted as default 7. Go to warehouses, select the WH of your company and select Pick then Deliver (2 steps) as Outgoing Shipments 8. Go to Routes, select Deliver in two steps (pick + ship) and change "Destination location" of "Pull From" from Parteners/Customers into WH/output 9. Go to Rules: 1. "Pull From" (the one with Partener/Customers as destination location and MTO as route): change "Destination location" of from Parteners/Customers into WH/output 2. "Push To" (the one with Partener/Customers as destination location and with the deliver in 2 steps as route): change action from "Push To" to "Pull from" 10. Create a new quotation inserting 2 products: Furniture Assembly and Drawer and confirm it 5. Go to "Manufacturing" smart button 6. See in Miscellaneous tab the Project is not setted ### Cause of the issue: https://github.com/odoo/odoo/blob/d1955028bb95eff8d33c1c2b1c211d8520bb33a2/addons/sale_project_stock/models/stock_move.py#L71-L76 This function retrieves the project only based on the sale_line_id, which is correctly populated in a one-step delivery because the procurement is directly linked to the Sales Order (SO). However, the sale_line_id is not propagated to procurements that are not directly linked to the SO. In this scenario, with a two-step delivery, there are two stock moves: from Stock to WH/Output, and from WH/Output to the Customer. Only the second move (WH/Output > Customer) is linked to the SO, while this information is not propagated to the first move. As a result, the project_id information is lost. ### Reason to introduce the fix: Be sure that the project is automatically setted in the MO when a SO is confirmed whatever the intial delivery configuration is. opw-5913988 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update prevents a "Invalid Operation" error during bill matching when no new purchase order lines need to be added. Previously, Odoo would attempt to update a posted bill, causing a block in the process. Now, the system intelligently skips the update if no new lines are required, ensuring smooth bill matching.
Original PR description
**Description of the issue/feature this PR addresses:** This PR fixes an "Invalid Operation" UserError during the Bill Matching process. The error occurs when Odoo attempts to call the line addition…
**Description of the issue/feature this PR addresses:** This PR fixes an "Invalid Operation" UserError during the Bill Matching process. The error occurs when Odoo attempts to call the line addition method on a Posted Vendor Bill, even when there are no new residual lines to add. This triggers a write attempt on read-only fields (such as invoice_line_ids) of a validated account move, which is prohibited by Odoo’s ORM. Furthermore, this addresses a functional inconsistency: Odoo allows users to select "Posted" bills in the matching view, but the underlying code is not prepared to handle a "zero residual" scenario on a validated move. If Odoo intends to prevent matching on posted bills, they should be filtered out from the view; since they are available to select, the system must be able to process them when no further modifications to the accounting entries are required. **Current behavior before PR:** When performing a match between a posted Vendor Bill and Purchase Order lines where the "residual" (lines left to add) is zero: The system executes _add_purchase_order_lines() regardless of whether the recordset of lines is empty. Odoo's ORM detects an update attempt on a posted record. A UserError is raised: "You cannot modify the following readonly fields on a posted move: invoice_line_ids". This blocks the user from completing the matching process even if the lines are already technically accounted for. **Desired behavior after PR is merged:** The system will check if residual_purchase_order_lines contains any records before attempting to update the bill. If there are no lines to add, the method call is skipped. The matching process completes successfully without attempting an illegal write on a posted move. **Steps to Reproduce** 1) Create a Purchase Order (PO): Add a product (e.g., "Acoustic Bloc Screens") and confirm the order. 2) Create a Vendor Bill manually: Do not use the "Create Bill" button from the PO. Instead, go to Accounting -> Vendors -> Bills and create a new bill for the same vendor and product. 3) Post the Bill: Set a bill date and click Confirm to move it to the "Posted" state. 4) Open Bill Matching: Go back to the Purchase Order and click the Bill Matching button (or navigate to the matching view). 5) Select Lines: Select the PO line and the corresponding Bill line (which are already equal in quantity/price). 6) Trigger the Match: Click on the Match button. Observe Error: An "Invalid Operation" popup appears, preventing the link because Odoo tries to "add" zero lines to a posted invoice. **Video:** https://drive.google.com/file/d/12aeZIx1JRRSKA9TaWfXy0TeSOgMUMQcg/view --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes an issue where global invoices in Mexico (l10n_mx_edi_pos) were incorrectly displaying the month of the order instead of the invoice month. The fix converts POS order dates to the correct MX timezone before calculating invoice dates, ensuring accurate reporting and compliance.
Original PR description
**PROBLEM** When creating a global invoice, with the last order being at the end of the last day of the month, the month of the global invoice will not be correct. (e.g, order made at the end of May and global invoice created for June). date_order is stored in utc. To compute the day the order was made, we need to convert to a MX timezone. **STEP TO REPRODUCE** 1. Create an pos order at the end of the last day of a month (for example, at 10PM in local MX time). 2. Create a global invoice with this order. 3. Notice the global invoice month will be the month after the one of the order. opw-6221049