Daily updates from Odoo
Navigate
Branch
Monday, April 20, 2026
188 changes
14 changes
Resolved issues and error corrections
This update prevents an error when incoming Chilean electronic invoices are processed without a specific LATAM purchase journal configured. It ensures the system selects a valid default journal so invoices can be created and recorded normally.
Original PR description
Currently, when receiving a DTE XML fetched by the fetchmail server, if there is no purchase journal with `l10n_latam_use_documents` enabled, an empty recordset (account.journal()) is set in the default context values. This prevents the proper computation of the field and raises an error, since the `journal_id` is mandatory on account moves. Steps to reproduce: - Ensure you have no purchase journal with `l10n_latam_use_documents` enabled - Simulate the reception of a DTE XML via the fetchmail server - Observe the error: "NotNullViolation: null value in column 'journal_id'" opw-5950116 opw-6111041 Forward-Port-Of: odoo/enterprise#112168
This change corrects how landed costs are calculated when a bill is entered in a different currency than the company’s currency. It prevents the amount from being overstated, so the landed cost now matches the intended purchase price and avoids incorrect inventory costing.
Original PR description
Issue introduced by commit daf196e365f481ffcc8b56664fa361fa9c9bbda9
Steps to reproduce:
- Enable two currencies (e.g., USD and EUR)
- Set exchange rate: 2 EUR = 1 USD
- Set current company currency to USD
- Create a service product "Landed Cost":
- Purchase tab:
- Mark as "Is a Landed Cost"
- Cost: $10
- Create a bill:
- Vendor: any vendor
- Currency: EUR
- Add 1 unit of "Landed Cost" → correctly shows 20 EUR
- Click the "Create Landed Cost" button
Expected behavior:
Landed cost should be calculated as $10
Actual behavior:
Landed cost is incorrectly calculated as $40, because the AML (Account Move Line) price subtotal is multiplied by the currency exchange rate (2) instead of dividing.
opw-6121706
opw-6121407
Opw-6124771
Opw-6123193
Forward-Port-Of: odoo/odoo#259632When users save certain website snippets as custom snippets, they will now appear both in the block list and in the inner content list when appropriate. This restores the expected behavior and makes reusable snippets easier to find and use while editing a website.
Original PR description
Steps to reproduce: 1. Go to Website > Edit mode. 2. Drag and drop a `Map` from `Inner Content` snippets. 3. Save it as a custom snippet. Current behavior: - The custom snippet is saved only as inner content and does not appear as a block in custom snippets. Expected behavior: - The snippet should be available both as a block and as inner content, consistent with behavior in `saas-18.3`. Issue: - Custom inner content snippets were systematically extracted from `snippet_custom`. As a result, snippets that can serve both purposes were only kept as inner content, preventing their usage as blocks. Solution: - Update the logic to: 1. Keep dual-purpose snippets in `snippet_custom` (block usage). 2. Also add them to `snippet_custom_content` (inner content usage). 3. Remove only inner-only snippets from the block category to avoid display issues. task-6064917 Forward-Port-Of: odoo/odoo#259588 Forward-Port-Of: odoo/odoo#256777
This change prevents database synchronization from failing with an error when the user no longer has access, when a new document arrives from a remote database, or when the remote database cannot be reached. Instead, the sync now finishes cleanly and correctly reflects any loss of access from the remote side.
Original PR description
The aim of this commit is to allow a db_user to synchronize a database without facing a Traceback. Context: - A new document has been received by a remote db and we try to synchronize it. - The current user access has been removed from the remote db. - The database is unreachable. Before this commit: In all 3 previous cases, an access error would be raised because a db_user can't write on a database. After this commit: The synchronization finish gracefully and the db_user should have lost his access if it was removed from the remote db. task-id: 6046087 Forward-Port-Of: odoo/enterprise#114129 Forward-Port-Of: odoo/enterprise#113826
This change updates the rules for creating asset entries so they depend on how an account is configured, not on whether it was used in older records. This prevents customers with legacy asset data from being blocked from creating new assets, and also keeps certain configured accounts out of the depreciation selection list.
Original PR description
This commit fixes the `can_create_asset` flag on accounts to limit the creation of asset based on if account is used as an accumulated depreciation on another account, instead of used by an asset. This requirement came after users with old assets couldn't create assets using some accounts because they were used by the old assets with no possible way to change that. Better to limit on configuration data instead of business data. Also now, accounts that have models set do not show up in the accumulated depreciation dropdown. no-task
This update adds the unit of measure information to the data sent to ECPay, so invoice lines are easier to understand. As a result, the printed invoice now shows the item’s unit alongside the existing product details, reducing confusion for recipients.
Original PR description
Issue: -- The documents returned by the ECpay API can be confusing as it does not include the measurement (UOM). The make it clearer a description is provided to ECpay through the json with the Key "ItemRemark" Current behavior: -- displayed data in PDF 品名 數量 單價 金額 備註 test 1 5 5 Expected behavior: -- displayed data in PDF 品名 數量 單價 金額 備註 test 1 5 5 商品單位: Units opw-6070269 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#259536
This change prevents an employee holiday pay field from being read too early during payroll updates. As a result, the value is now calculated at the right time, which avoids incorrect payroll results and related test failures.
Original PR description
…ield The computed, non-stored field `l10n_be_holiday_pay_recovered_n1` had tracking enabled. When writing to any field on the employee, the `write` method calls `_track_prepare` for tracked fields if `mail_notrack` is not set in the context. `_track_prepare` reads the current value of tracked fields to store initial values. Because `l10n_be_holiday_pay_recovered_n1` is non-stored with no dependencies, this triggered a computation at the very beginning of the test, before payslips existed. Later, when payslips were created, the field was never recomputed, causing incorrect values and test failures. Previously, the `tracking_disable` context prevented early computation. The fix removes the tracking attribute entirely, so the field is only computed when accessed, avoiding premature reads and fixing the tests. task: 6095445 Forward-Port-Of: odoo/enterprise#114063 Forward-Port-Of: odoo/enterprise#113015
The Dutch ICP report now uses the same rounding method as the export files, rounding amounts down to whole numbers. This removes confusing differences between the report and the submitted export, helping users verify figures more easily.
Original PR description
Description of the issue this commit addresses: The Dutch tax authority lets ICP amounts be rounded down which is the behavior of the exports but not of the report itself meaning the values to not match and is quite confusing. --- Desired habevior after this commit is merged: The integer rounding DOWN is added on the ICP report to restore matching values --- task-6065382 Forward-Port-Of: odoo/enterprise#114277 Forward-Port-Of: odoo/enterprise#112953
The Point of Sale session report now calculates discount amounts more accurately when fiscal positions change the taxes applied to an order. This ensures the report matches the real sales data and avoids incorrect discount figures in end-of-session summaries.
Original PR description
Steps: ---- - Create a fiscal position with 2 different taxes - Add a line in POS - Apply fiscal position and add line discount - Finish the order cycle - Download the session report Issue: ---- - The discount amount was calculated incorrectly in the session report Cause: ---- - The discount amount calculation used taxes before applying the fiscal position Fix: ---- - Used `tax_ids_after_fiscal_position` for tax calculation while computing the discount amount task-5421215 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#256704 Forward-Port-Of: odoo/odoo#244650
This change fixes a testing issue where repeated test attempts could accidentally reuse leftover state from a previous run and cause confusing failures. By recreating the test for each retry, the test process is more reliable and easier to trust.
Original PR description
The autoretry don't recreate the test instance meaning that some pollution can remain there breaking the next test with a strange error. This pr recreates the test instance for each retry to avoid this kind of issue, and move the retry mechanism to the suite level. The core part of the fix is `test = test.__class__(test._testMethodName) # re-create the test to reset its state` While on it, moving the retry mechanism in the test suite since it makes more sense and allow a better control on what is retried or not since we don't rely on inheritance, and avoid dirty code with super(test) call to recreate the instance and execute it again. The tests needs to be adapted since the retry attribute is now in the loop, but we can have a quite reliable way to know if we are in a retry or not using inspect. Forward-Port-Of: odoo/odoo#258833
If the connection drops while waiting for a Viva.com payment confirmation, the POS now keeps checking instead of stopping too early. This reduces the risk of a customer being charged on Viva.com without the payment being confirmed in the point of sale, while also showing a one-time warning that connectivity was lost.
Original PR description
When a payment was sent to Viva.com and the connection dropped before receiving confirmation, the polling loop in waitForPaymentConfirmation would stop because _handleOdooConnectionFailure set the payment status to "retry" and rejected the promise. This left the payment debited on Viva's side but unconfirmed in the POS. Now the polling uses a direct silent ORM call instead of _call_viva_com to avoid triggering _handleOdooConnectionFailure. On connection failure, the poll silently retries on the next interval until a definitive success/failure response is received. A one-time warning notification informs the user that connectivity was lost. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#259564
This change prevents discounts from being recalculated and cleared on optional sales lines when a portal customer updates the quantity. It helps preserve the expected pricing on quotes and avoids confusing changes for customers and sales teams.
Original PR description
Issue: --- Discount compute depends on `product_uom_qty`. On optional lines, this recompute will reset the discount on lines, when portal user updates the quanity. Cause: --- `discount` needs to depend on `product_uom_qty` because discount needs to be computed based on the quantity due to pricelist rules. Fix: --- We can prevent this compute if the quantity update comes from portal. opw-6078083 Forward-Port-Of: odoo/odoo#259696
This change fixes an issue where exporting account reports could fail when a fiscal year date was included. Users will now be able to export these reports without encountering a JSON processing error.
Original PR description
When calling export_file with a fiscal year set we pass a fiscal year into it. This function then calls json.dumps with the date object passed into it through a dictionary, which json.dumps cannot process and users experience an error. https://drive.google.com/file/d/1VBOIAxuzcXT5b5BBnLDqd6ibWqOPxe4P/view?usp=drive_link
The website editor now correctly treats buttons with size or shape classes as custom buttons. This prevents the wrong style from being shown in the button settings popover and keeps the editor behavior aligned with how those buttons are actually built.
Original PR description
Before this commit: Since the removal of button style options for the preset primary and secondary styling, the type of a primary/secondary button with size or shape defined in the class should be "custom". The fix is made to saas-18.4 cause the custom button option is removed in saas-18.3 and reintroduced only from saas-18.4. The button option removal commit: https://github.com/odoo/odoo/commit/a7b71d700e4997e4a2f646e2ae12f58f20058dc4 The button custom option reintroduction: https://github.com/odoo/odoo/commit/ea22b28bbae009c9eab4ff397affa9a3cb71037a After this commit: when the button has size or shape classes, we consider it as "custom" button. task-6061443 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#257410 Forward-Port-Of: odoo/odoo#256015
3 changes
Resolved issues and error corrections
This update corrects a problem with the message right-click menu so it behaves as expected again. It helps users quickly access message options without interruptions or unexpected behavior.
The Dutch ICP report now uses the same downward integer rounding as the tax export. This keeps the reported amounts consistent and avoids confusing differences between the report and the exported figures.
Original PR description
Description of the issue this commit addresses: The Dutch tax authority lets ICP amounts be rounded down which is the behavior of the exports but not of the report itself meaning the values to not match and is quite confusing. --- Desired habevior after this commit is merged: The integer rounding DOWN is added on the ICP report to restore matching values --- task-6065382 Forward-Port-Of: odoo/enterprise#112953
This fix allows Belgian companies to change their fiscal localization from Companies to Associations and Foundations without failing during the chart update. It removes hidden links to old accounting settings first, so the change completes successfully and existing cash rounding remains intact.
Original PR description
### Issue before this commit: Switching the fiscal localization of a Belgian company from "Companies" to "Associations and Foundations" caused a traceback during the chart reload process. The…
### Issue before this commit:
Switching the fiscal localization of a Belgian company from "Companies" to "Associations and Foundations" caused a traceback during the chart reload process. The operation failed because some accounts from the previous localization could not be deleted.
### Steps to reproduce the issue:
1. Download Accounting
2. Create a new Belgian company
3. Switch to that company
4. Go into Settings -> Fiscal Localization
5. Switch to Associations and Foundations
6. Traceback: The operation cannot be completed: Another model is using the record you are trying to delete. The troublemaker is: 'Account Cash Rounding' (account.cash.rounding). Thanks to the following constraint: 'Profit Account' (profit_account_id). How about archiving the record instead?
### Cause of the issue:
The Belgian localization creates a default cash rounding method ("Round to 0.05") linked to specific profit and loss accounts. When switching localization, it was tried to delete the old chart of accounts, but these accounts are still referenced by account.cash.rounding through profit_account_id and loss_account_id, which use ondelete='restrict'. This prevents account deletion and blocks the localization change. Commit that caused the issue: https://github.com/odoo/odoo/commit/412fc9bed36645dd950c9a60d9b6ffdd9b4bce67
### Reason to introduce the fix:
Before reloading the Belgian chart template, the fix clears the profit_account_id and loss_account_id on the existing cash rounding records. This removes the blocking references, allows the old accounts to be deleted safely, and lets the fiscal localization switch complete successfully without affecting existing cash rounding configurations.
opw-6050537
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr10 changes
Enhancements to existing features
This update improves how tax amounts are calculated for Argentine electronic invoicing and related reports. It helps ensure totals are computed more consistently and displayed with the right precision, reducing rounding differences and improving the reliability of generated tax data.
Original PR description
- Rewrite all tax amounts calculations on `_get_tributes` and `_get_line_details` to properly use the tax computation engine helpers (`base_line`, and aggregating methods) - Ensure that all final amounts from the calculation are formatted with `float_repr` with appropriate precision. related-community-PR: https://github.com/odoo/odoo/pull/223393 task-4891206 Forward-Port-Of: odoo/enterprise#92639
The invoice import process was updated so records are matched more reliably, especially when partner information is involved. This helps reduce inconsistencies during BIS3/UBL invoice imports and improves the accuracy of imported data.
Original PR description
This commit is part of a bigger commit on the community side- to refactor the import code of BIS3 Invoice to fix various unsynchronized values issues. task-id: 5058687 Forward-Port-Of: odoo/enterprise#113719 Forward-Port-Of: odoo/enterprise#108356
Resolved issues and error corrections
The Dutch ICP report now uses the same rounding-down rule as the export files. This avoids confusing mismatches between the report and the submitted amounts, making the figures easier to trust and reconcile.
Original PR description
Description of the issue this commit addresses: The Dutch tax authority lets ICP amounts be rounded down which is the behavior of the exports but not of the report itself meaning the values to not match and is quite confusing. --- Desired habevior after this commit is merged: The integer rounding DOWN is added on the ICP report to restore matching values --- task-6065382 Forward-Port-Of: odoo/enterprise#112953
The comparison view in tax reports now works correctly even when a report line contains text instead of only numbers. This prevents the report from crashing when users compare against one past period, so they can review results without interruption.
Original PR description
To reproduce: - Create a company in LU - Open the annual tax report for LU - Click on the comparison filter, compare with 1 period in the past ==> Traceback. This happens because that report contains a string value (an editable one, but it's not important here). Since there are only 2 comparison periods, we try creating the "%" column, comparing their amounts. The condition checking whether or not to display "N/A" was wrong, as it considered the values could only be int/float or None. Here, they are strings, so we don't enter that condition and crash when trying to evaluate float_is_zero on a string. Forward-Port-Of: odoo/enterprise#113330 Forward-Port-Of: odoo/enterprise#112619
This update corrects ISO20022 payment files so currencies like JPY are exported with the proper number of decimal places. It prevents bank rejections caused by amounts being formatted with two decimals when the currency should not have them.
Original PR description
Steps to reproduce: ------------------- 1. Activate JPY and create a JPY bank journal with ISO20022 as an outgoing payment method 2. Create a vendor (with a country) and add a trusted bank account 3.…
Steps to reproduce: ------------------- 1. Activate JPY and create a JPY bank journal with ISO20022 as an outgoing payment method 2. Create a vendor (with a country) and add a trusted bank account 3. Create and confirm a vendor bill in JPY (e.g. ¥1000), and pay it using the ISO20022 method on the JPY journal 4. Create a batch payment containing that payment, with Batch Type Outbound, on the JPY journal, with ISO20022 as payment method 5. Validate the batch — the XML file is generated and attached 6. Download it -> The `<InstdAmt Ccy="JPY">` node outputs `1000.00`, while JPY has no decimals. The file is rejected by banks. The fix: -------- Backport of 8da91d94ed1e8fad0e827f96172e3785e9f0e28d: > Generating the xml file for iso20022 always generates the amount with two decimals which is hard coded and can cause error for currencies without decimals for example JPY. > The fix is to have the currency decimal number dynamically set through the currency decimal places field. opw-6103849 Forward-Port-Of: odoo/enterprise#113296
This change removes a tracking setting from a payroll field so it is no longer read too early in the employee update flow. As a result, holiday pay values are calculated at the right time and payroll tests and outputs stay accurate.
Original PR description
…ield The computed, non-stored field `l10n_be_holiday_pay_recovered_n1` had tracking enabled. When writing to any field on the employee, the `write` method calls `_track_prepare` for tracked fields if `mail_notrack` is not set in the context. `_track_prepare` reads the current value of tracked fields to store initial values. Because `l10n_be_holiday_pay_recovered_n1` is non-stored with no dependencies, this triggered a computation at the very beginning of the test, before payslips existed. Later, when payslips were created, the field was never recomputed, causing incorrect values and test failures. Previously, the `tracking_disable` context prevented early computation. The fix removes the tracking attribute entirely, so the field is only computed when accessed, avoiding premature reads and fixing the tests. task: 6095445 Forward-Port-Of: odoo/enterprise#114063 Forward-Port-Of: odoo/enterprise#113015
There were some translation overrides for `fr_BE` and `fr_CA` that were incorrect or unnecessary. We are deleting these files so they use the correct translations in `fr` instead. In the `nl_BE` translation, we are fixing a menu item so it is shorter, but still correct. task-5921458 Forward-Port-Of: odoo/enterprise#114069 Forward-Port-Of: odoo/enterprise#106998
Original PR description
There were some translation overrides for `fr_BE` and `fr_CA` that were incorrect or unnecessary. We are deleting these files so they use the correct translations in `fr` instead. In the `nl_BE` translation, we are fixing a menu item so it is shorter, but still correct. task-5921458 Forward-Port-Of: odoo/enterprise#114069 Forward-Port-Of: odoo/enterprise#106998
The manufacturing report now converts unit quantities correctly when products are tracked in different units of measure. This fixes incorrect totals and averages in report groupings, so production figures and cost analysis are reliable again.
Original PR description
Steps to reproduce:
- Create a product W1 with UoM = Kg with the following BoM:
- Component C1: 1 unit, cost = $1
- Create and confirm MO1:
- Produce 1 Kg of W1 → total cost = $1
- Create and confirm MO2:
- Produce 1 Ton of W1 → total cost = $1000
- Open the Manufacturing Report and group results
Problem:
- qty_produced ≈ 1.001 instead of 1001
- unit_cost average ≈ 1000 instead of 1
Expected behavior:
- qty_produced = 1001
- unit_cost average = 1 (consistent across MOs)
The manufacturing report (`mrp.report`) incorrectly converts quantities from move UoM to product UoM, leading to wrong `qty_produced` and `qty_demanded` values when different units of measure are used
The current implementation uses:
sm.quantity / uom.factor * uom_prod.factor
This inverts the conversion ratio. As a result:
- 1 Ton is converted to 0.001 Kg instead of 1000 Kg
opw-6097098
Forward-Port-Of: odoo/enterprise#113979When a delivery is scanned using a packaging barcode, the system now correctly keeps the due date from the barcode when creating the lot. This avoids lots being created with the wrong expiration date and helps ensure inventory tracking stays accurate.
Original PR description
Issue
-----
Scanning a GS1 barcode containing:
- packaging
- lot
- due date
disregards the due date when creating the new lot.
Steps to reproduce
-----
- Enable GS1 nomenclature & packagings
- Create a product
- barcode 23456789012344
- packaging with barcode 01234567890128
- some on hand quantity
- Create a delivery for a full packaging of the product
- Open the delivery in barcode
- Scan 02 01234567890128 15 270101 10 LOT1
- Validate
- Open the lot
> Expiration date is set to today
Cause
-----
The code expects the product be scanned, there is no logic to retrieve it from the packaging when missing.
-----
Ticket:
opw-6073489
Forward-Port-Of: odoo/enterprise#113136
Forward-Port-Of: odoo/enterprise#112490When a subscription payment is processed through certain bank settings, the related invoice could stay marked as unpaid even though the payment succeeded. This fix ensures the invoice is properly matched with the payment so customers and teams see the correct payment status.
Original PR description
Currently, when a subscription payment is processed through a provider configured to use as outstanding account the bank default account, the resulting invoice may remain in an 'open' state even…
Currently, when a subscription payment is processed through a provider configured to use as outstanding account the bank default account, the resulting invoice may remain in an 'open' state even though the payment transaction is 'done'. This type of configuration is usually done when users want to skip the bank reconciliation process, and just create payments without the need to reconcile the payments with transactions. Steps to reproduce: - In Settings, under Sales > Invoicing, disable Automatic Invoice - Activate demo payment method - In the main Bank account add the default account as outstanding account for demo payment method. - Create a sales order with a subscription product - Open Preview - Pay - Go back to the sales order and open the created invoice Issue: The invoice is created and the payment is registered, but the invoice remains 'Not Paid'. Analysis: The invoice and the payment move lines are not automatically reconciled during the post-processing of the transaction, leaving the invoice unbalanced. opw-5869303 Forward-Port-Of: odoo/enterprise#110656
14 changes
Enhancements to existing features
This change improves how tax amounts are calculated for Argentine electronic documents, making the results more consistent and reliable. It also formats the final values with the right precision, which helps avoid rounding issues in invoices and reports.
Original PR description
- Rewrite all tax amounts calculations on `_get_tributes` and `_get_line_details` to properly use the tax computation engine helpers (`base_line`, and aggregating methods) - Ensure that all final amounts from the calculation are formatted with `float_repr` with appropriate precision. related-community-PR: https://github.com/odoo/odoo/pull/223393 task-4891206 Forward-Port-Of: odoo/enterprise#92639
This change updates how Argentina-specific tax amounts are calculated so they rely on Odoo’s standard tax computation methods instead of custom line queries. It makes the calculation logic more reliable and prepares the system for future improvements in tax handling.
Original PR description
This commit refactors the tax amount calculations on the `_get_vat` and `_l10n_ar_get_amounts` method so that it uses the tax computation engine helpers properly, to prepare for any future fixes done on how Argentina tax calculations differs from all other localizations. This replaces all move line queries with the proper `base_line` calculation, with the proper aggregating methods. related-enterprise-PR: https://github.com/odoo/enterprise/pull/92639 task-4891206 Forward-Port-Of: odoo/odoo#223393
Resolved issues and error corrections
This change ensures that when aggregate withholding is turned on, the aggregation period must also be filled in. It prevents invoice creation from failing with an error if that required field was left empty.
Original PR description
Previously, if `is_aggregate_limit` was set to True while `aggregate_period` was left empty, it would raise a traceback during invoice creation. Although `aggregate_period` has a default value, it can still be manually cleared. With this commit, `aggregate_period` is enforced as mandatory whenever `is_aggregate_limit` is enabled, preventing such errors. Forward-Port-Of: odoo/odoo#259737 Forward-Port-Of: odoo/odoo#259634
When a GS1 barcode includes a product packaging, lot number, and due date, the system now correctly keeps the due date when creating the lot. This avoids setting the expiration date to today by mistake and helps warehouse teams record product expiry information accurately.
Original PR description
Issue
-----
Scanning a GS1 barcode containing:
- packaging
- lot
- due date
disregards the due date when creating the new lot.
Steps to reproduce
-----
- Enable GS1 nomenclature & packagings
- Create a product
- barcode 23456789012344
- packaging with barcode 01234567890128
- some on hand quantity
- Create a delivery for a full packaging of the product
- Open the delivery in barcode
- Scan 02 01234567890128 15 270101 10 LOT1
- Validate
- Open the lot
> Expiration date is set to today
Cause
-----
The code expects the product be scanned, there is no logic to retrieve it from the packaging when missing.
-----
Ticket:
opw-6073489
Forward-Port-Of: odoo/enterprise#113136
Forward-Port-Of: odoo/enterprise#112490This update adds the product unit of measure to the information sent to ECPay, making invoice lines easier to understand. As a result, printed documents now show the unit description alongside each item, reducing confusion for customers and accounting teams.
Original PR description
Issue: -- The documents returned by the ECpay API can be confusing as it does not include the measurement (UOM). The make it clearer a description is provided to ECpay through the json with the Key "ItemRemark" Current behavior: -- displayed data in PDF 品名 數量 單價 金額 備註 test 1 5 5 Expected behavior: -- displayed data in PDF 品名 數量 單價 金額 備註 test 1 5 5 商品單位: Units opw-6070269 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#259536
This change removes automatic tracking from a payroll field that was being read too early during employee updates. As a result, holiday pay values are now computed at the right time, preventing incorrect payroll calculations and related test failures.
Original PR description
…ield The computed, non-stored field `l10n_be_holiday_pay_recovered_n1` had tracking enabled. When writing to any field on the employee, the `write` method calls `_track_prepare` for tracked fields if `mail_notrack` is not set in the context. `_track_prepare` reads the current value of tracked fields to store initial values. Because `l10n_be_holiday_pay_recovered_n1` is non-stored with no dependencies, this triggered a computation at the very beginning of the test, before payslips existed. Later, when payslips were created, the field was never recomputed, causing incorrect values and test failures. Previously, the `tracking_disable` context prevented early computation. The fix removes the tracking attribute entirely, so the field is only computed when accessed, avoiding premature reads and fixing the tests. task: 6095445 Forward-Port-Of: odoo/enterprise#114063 Forward-Port-Of: odoo/enterprise#113015
There were some translation overrides for `fr_BE` and `fr_CA` that were incorrect or unnecessary. We are deleting these files so they use the correct translations in `fr` instead. In the `nl_BE` translation, we are fixing a menu item so it is shorter, but still correct. task-5921458 Forward-Port-Of: odoo/enterprise#114069 Forward-Port-Of: odoo/enterprise#106998
Original PR description
There were some translation overrides for `fr_BE` and `fr_CA` that were incorrect or unnecessary. We are deleting these files so they use the correct translations in `fr` instead. In the `nl_BE` translation, we are fixing a menu item so it is shorter, but still correct. task-5921458 Forward-Port-Of: odoo/enterprise#114069 Forward-Port-Of: odoo/enterprise#106998
The Reference field in Inventory move history is now read-only, so users no longer see a field they can edit when changes would not actually be saved. This removes confusion and makes the screen behave consistently with the system's behavior.
Original PR description
### Issue before this commit: Before this commit, the Reference field displayed on stock.move.line was editable in the user interface, even if the modification made by the user was not persisted.…
### Issue before this commit: Before this commit, the Reference field displayed on stock.move.line was editable in the user interface, even if the modification made by the user was not persisted. After saving and reloading the Move History view, the original value was restored. ### Steps to reproduce the issue: 1. Go to Move history in Inventory app 2. Try to change the name of a line and save 3. If you go back to the Move history you can see that the name is not changed ### Cause of the issue: The issue was caused by a mismatch between the stock.move.line.reference field and its target field stock.move.reference. The field on stock.move.line is a related field that appears editable (readonly=False), but the underlying stock.move.reference field was not writable. As a result, user could edit the field but the modifications were ignored, preventing changes from being effectively saved. ### Reason to introduce the fix: The fix ensures that the reference field in stock.move and in stock.move.line are readonly. opw-6055708 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#256434
This change corrects a test barcode format used by the point of sale barcode scanning checks. It ensures the scanned product is recognized properly during the test, preventing false failures in the POS test suite.
Original PR description
The test_GS1_pos_barcodes_scan was failing because the "GS1 Variant Product" barcode was defined as a 13-digit string, while the tour scans it using the GS1 AI 01 (GTIN), which expects a 14-digit GTIN-14. By adding a leading zero to the barcode in the test setup, we align it with the GTIN-14 format parsed by the POS barcode parser during the scan, ensuring the product is correctly added to the order. runbot-error: 242323 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#258089
The self-ordering system now sends only the fields the frontend actually needs. This reduces unnecessary data transfer and helps keep the client-side payload simpler and more efficient.
Original PR description
Fix _generate_return_values to remove some fields that are not needed on the frontend Forward-Port-Of: odoo/odoo#259915
This update fixes an automated POS loyalty test that was failing because a customer list in a popup could scroll indefinitely. It helps keep the loyalty feature’s checks reliable so future updates can be validated more safely.
Original PR description
fw-port fails because of infinite scroll in pop modal .modal .partner-list Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#218604
The Bill of Materials overview now handles companies that do not have a warehouse configured. Instead of showing an error, it displays product availability as “Not available” and warns the user about the missing setup.
Original PR description
**Steps to Reproduce:** - Install MRP module. - Create a new company and switch to it. - Create a new BoM. - Click on the "BoM Overview" smart button. **Error:** `IndexError - list index out of range` **Cause:** When a new company is created, no warehouse is automatically generated for it. If no warehouse is configured for the company, the list is empty, causing an error. **Fix:** This commit raises a redirection warning if no warehouse is linked with the company. sentry-7286332859 Forward-Port-Of: odoo/odoo#250602
When invoice lines are grouped during UBL/CII import, the tax total is now adjusted so it stays accurate after grouping. This prevents small but important discrepancies in reported tax amounts and improves the reliability of imported invoices.
Original PR description
[FIX] account_edi_ubl_cii: correct tax amount when grouping lines When the user group lines of a move, the tax amount is now corrected if there's a difference in the tax amount before and after grouping This commit also removes the `ungroup_lines` context key, as the flow was changed in odoo/odoo#252458 Reword the `test_import_and_group_lines_by_tax` test: use belgian company and belgian taxes task-5993555 Forward-Port-Of: odoo/odoo#257581 Forward-Port-Of: odoo/odoo#252719
When an invoice is sent through Indian E-Invoicing, the IRN number is now saved directly on the invoice record as soon as the response is received. This means users can see the same information in both the PDF and the invoice form, improving consistency and making invoice tracking easier.
Original PR description
**Steps to reproduce:** * Install module *Indian E-Invoicing (l10n_in_edi)*. * Configure *Indian integration* with required credentials (E-Invoicing, E-Way bill, etc.). * Save the settings. * Create a *customer invoice*. * Post the invoice. * Send the invoice through *E-Invoicing (EDI)*. * Open the generated *Invoice PDF* and the *form view*. **Observed behavior:** * The *IRN number* is correctly present in the *Invoice PDF*. * However, it is *not saved/displayed* in the invoice form view. **Cause:** * No specific condition existed in the invoice flow to store the *IRN number* in the corresponding field, even though the value was available in the EDI response. **Fix:** * Update *_get_l10n_in_edi_response_json* to store the IRN number directly on the invoice when the response is received. * This ensures the value is saved without impacting the existing EDI flow. opw-6097923
2 changes
Resolved issues and error corrections
This fix prevents Point of Sale from crashing when a payment is cancelled directly on the payment terminal instead of in the POS screen. It improves reliability for cashiers by handling this cancellation case cleanly and avoiding an error message.
Original PR description
Currently if you cancel a transaction on the terminal (not in pos) this lead to a traceback TypeError: this.cancel_resolve is not a function at Proxy._waitingPayment (https://varoconsult-be-itve.odoo.com/web/assets/4473ba8/point_of_sale.assets_prod.min.js:16764:298) at Proxy._onValueChange (https://varoconsult-be-itve.odoo.com/web/assets/4473ba8/point_of_sale.assets_prod.min.js:16758:184) at Proxy._onSuccess (https://varoconsult-be-itve.odoo.com/web/assets/4473ba8/point_of_sale.assets_prod.min.js:16674:190) at Proxy._onSuccess (https://varoconsult-be-itve.odoo.com/web/assets/4473ba8/point_of_sale.assets_prod.min.js:16778:1228) at https://varoconsult-be-itve.odoo.com/web/assets/4473ba8/point_of_sale.assets_prod.min.js:16672:417 This PR fixes the issue to ensure the scenario when the pos didnt ask for cancellation is managed Forward-Port-Of: odoo/enterprise#114215
This update moves the tax amount for “12% I” to the correct section of the Philippine SLSP report. It now appears under “Purchase of Other than Capital Goods” instead of “Purchase of Capital Goods,” ensuring the report is more accurate for business reporting and compliance.
Original PR description
Before this commit: - The amount of tax '12% I' is shown under 'Purchase of Capital Goods'. After this commit: - The amount of tax '12% I' is shown under 'Purchase of Other than Capital Goods'. task-6092566 Forward-Port-Of: odoo/enterprise#113810
36 changes
New functionality added to Odoo
Rental orders created from a sales opportunity now automatically keep the related project attached. This helps teams maintain a clear link between the customer opportunity, the rental order, and project work without manual updates.
Original PR description
This commit links the project, CRM, and rental by setting the project on rental orders created from an opportunity. Task-6024387
AI agents can now help create one or multiple records in the database, with user confirmation required before anything is saved. This expands agent capabilities while keeping users in control through previews and approval steps.
Original PR description
This commit adds the tools and topics that allow the agents to create new records on the database. Specifically, it adds: - One tool "Create records", that allow to create one (or multiple) records at once. This tool must be confirmed by the user (similarly to the `Update records`. - One topic "Create records", that contains the instructions to use the new `Create records` tool. - Some utilities for previewing the records that are going to be created by the agent. task-5153871
A new AI assistant helps users edit website pages by adding and modifying content, images, headers, footers, and styling through conversational requests. This makes website creation and updates faster and more accessible for users without requiring manual page editing skills.
Original PR description
Introduction of an AI agent to edit the website page being edited. __What it can currently do__ - Add some snippets to the page and edit them on the fly. - Make any modifications on the header,…
Introduction of an AI agent to edit the website page being edited. __What it can currently do__ - Add some snippets to the page and edit them on the fly. - Make any modifications on the header, footer and wrap element. - Add some images given by the user or fetched from Unsplash - Read and write user_custom_rules.scss - Generate pictures __What it cannot currently do__ - Change theme and use tools from the editor - Add some JavaScript to the page - etc. __Basic flow__ Every time the user sends a message, the context given in the prompt is updated with the page information and content as well as the CSS variable values of the theme. When asking for a change on the page, the agent can use a tool to retrieve the HTML of standard snippets, it can also search for images. When it has everything it needs, it will call the tool to apply changes on the page. It has a lot of liberty to do so as it can add and replace any element with arbitrary (sanitized) HTML. Community PR: odoo/odoo#258133 task-5411100
AI agents and AI-powered server actions can now search the web to answer requests with more current information and include more reliable source links. The update also limits agent access to sensitive system models and makes AI server action logs shorter and easier to read.
Original PR description
Purpose: -------- Allow agents and AI server actions to search for info on the web when answering a user request. Since Gemini does not support web grounding with tool calls, one added a web…
Purpose: -------- Allow agents and AI server actions to search for info on the web when answering a user request. Since Gemini does not support web grounding with tool calls, one added a web grounding tool (and use it for every provider for consistency). This also allows to keep the web search in a separate context with more specific instructions. The tool will make an independent request to the LLM without any tools but with the web_grounding feature enabled. LLMs are really bad at recopying URLs and tend to hallucinate links. Therefore, the sources are inserted in the tool result using a uuid, and stored in the session state so that when the main agent references a source, it needs to reference a uuid instead of the source's url. These uuid's are then replaced by the source's urls manually using the mapping stored in the session state. Web Search can be added on AI agents by using the dedicated Web Search topic, and on server actions of type "AI" by adding the Web Search tool. The AI APIs request time out was increased to 90 seconds as the web searches might take some time. ### Models restrictions Some models are now non-accessible by the agents. For example, there's no reason to give the ability to the agent to access private keys; nor to allow it to edit views or access rights. If it is really necessary then these should be dedicated AI tools (eg. to avoid breaking views or to create attachments), or the agent should ask for confirmation to access some values. There is no real usecase at this moment so the access to these models is currently simply restricted. By default, every model starting with 'ir.' is restricted. Other models can be restricted by adding them in the AI_MODELS_BLOCKLIST set. To restrict access to these models, the AI tools **must** use the method `_parse_domain` method defined on `ai.agent`. Task-6025732
Enhancements to existing features
The Belgian salary configurator and employee offer view now present company car options in a simpler, clearer way. This makes it easier for employees and HR teams to understand and choose fleet-related salary benefits.
Original PR description
-Introducing some UX changes in salary configurator and employee's offer view to simplify car options.
Manufacturing teams get clearer and more flexible work order planning screens, including a kanban option, richer Gantt popovers, and a cleaner form header. These updates make it easier to review work orders and related manufacturing orders during production planning.
Original PR description
- add kanban to work orders views list - add infos in gantt view popover - adapt form view header - fix test task: 5990446 See odoo/odoo#257900
Quality checks can now target the exact bill of materials line or by-product line instead of only the product, preventing duplicate or incorrect checks when the same component appears multiple times. BoM revision reviews also better reflect by-product unit changes and Studio-edited forms keep component and by-product change tracking consistent.
Original PR description
_* = quality_mrp_workorders - When the same component is used multiple times in a BoM, it is not possible to specify exactly which one to use in Product to Register, and quality checks are created for each occurrence of that component unnecessarily. - This change replaces product selection with BoM lines and by-product lines with the Product to Register field of the Quality Point, ensuring that quality checks are created for the specific BoM line during operations and preventing duplicate or unnecessary checks. - Solve the issue where changing the UoM of a by-product in a BoM revision was not reflected in the By-Product Changes, ensuring a consistent and reliable revision review. - Adds missing dependencies so that when the form view is made editable via Studio, changes are still correctly reflected in Component Changes and By-Product Changes. Com PR https://github.com/odoo/odoo/pull/239243 task-5365739
This update improves how company cars are handled in Belgian salary package offers, including related configuration, employee views, and offer presentation. It helps HR teams present and manage fleet-related benefits more clearly during contract and salary negotiations.
The Discuss command palette has been improved for AI App and WhatsApp-related conversations, making actions easier to find and use. This should create a smoother messaging experience for users who rely on these channels in Odoo.
Original PR description
part of task-5867464 community: https://github.com/odoo/odoo/pull/258588
Belgian payroll DMFA reporting now uses the ONSS social security amounts already calculated on payslips, reducing the risk of differences between payroll and reporting. The report also flags mismatches when payslip amounts do not align with expected DMFA calculations, helping payroll teams spot issues before submission.
Original PR description
For the DMFA, directly use the ONSS amounts from the payslips. This commit also adds a list of alert on the DMFA report and adds an alert if the amount from payslips does not match the expected amount computed in the DMFA. task-5976407
Progress bars in Gantt-style planning, project, manufacturing, and scheduling views have been redesigned to be easier to read and less cluttered. The update improves hover behavior, row spacing, and mobile layout so users can more clearly understand progress at a glance.
Original PR description
Before this PR, the progress bar was not easy to read due to overlapping text and colors. The hover also changed from the whole row to only the header. The height of each row increased to allow…
Before this PR, the progress bar was not easy to read due to overlapping text and colors. The hover also changed from the whole row to only the header. The height of each row increased to allow better visibility of the progress bar. In mobile view, the display from the progress bar goes below the avatar name to allow clearer view. Some tests selectors doesn't exist anymore so they got adjusted. Com PR: https://github.com/odoo/odoo/pull/252295 **Dense Mode** | | Before | After | |--------|--------|--------| | Normal state | <img width="313" height="744" alt="Screenshot 2026-04-07 at 16 18 13" src="https://github.com/user-attachments/assets/74f3c8ad-5462-424f-a0de-a085e4600005" /> | <img width="313" height="744" alt="Screenshot 2026-04-07 at 16 16 26" src="https://github.com/user-attachments/assets/e73a9f69-0dd8-40b5-a347-98f76d7dbf13" /> | | Hover Red | <img width="313" height="744" alt="Screenshot 2026-04-07 at 16 18 18" src="https://github.com/user-attachments/assets/08671dc1-efd7-4823-8439-02ed5d066685" /> | <img width="313" height="744" alt="Screenshot 2026-04-07 at 16 16 36" src="https://github.com/user-attachments/assets/fe0e058a-a208-4457-a6aa-9b92ecd41ee3" /> | | Hover Green | <img width="313" height="744" alt="Screenshot 2026-04-07 at 16 18 21" src="https://github.com/user-attachments/assets/d4d519d6-eefa-4a00-9ef5-998a7ba41045" /> | <img width="313" height="744" alt="Screenshot 2026-04-07 at 16 16 50" src="https://github.com/user-attachments/assets/55319df3-93d7-46db-beff-fd68f1b2cab1" /> | **Sparse Mode** | | Before | After | |--------|--------|--------| | Normal state | <img width="313" height="744" alt="Screenshot 2026-04-07 at 16 18 32" src="https://github.com/user-attachments/assets/844d3dcd-41fb-4a64-bfc2-df98656fbbb0" /> | <img width="313" height="744" alt="Screenshot 2026-04-07 at 16 17 06" src="https://github.com/user-attachments/assets/450e831f-d912-4a2c-b51a-00c00750dff4" /> | | Hover Red | <img width="313" height="744" alt="Screenshot 2026-04-07 at 16 18 37" src="https://github.com/user-attachments/assets/b54b63dc-8a50-4c1e-99fd-1d9145e03540" /> | <img width="313" height="744" alt="Screenshot 2026-04-07 at 16 17 12" src="https://github.com/user-attachments/assets/372c1311-d621-4b77-861f-83d676e1d14c" /> | | Hover Green | <img width="313" height="744" alt="Screenshot 2026-04-07 at 16 18 41" src="https://github.com/user-attachments/assets/313b22de-1c79-4fd5-babd-44bad66ed992" /> | <img width="313" height="744" alt="Screenshot 2026-04-07 at 16 17 19" src="https://github.com/user-attachments/assets/332b6c5a-9288-4762-bb3b-d07d88005e8f" /> | **Mobile View** | | Before | After | |--------|--------|--------| | Sparse Mode | <img width="405" height="705" alt="Screenshot 2026-04-07 at 16 22 01" src="https://github.com/user-attachments/assets/58209c32-d7ad-4e59-8226-15742cb7f46e" /> | <img width="405" height="705" alt="Screenshot 2026-04-07 at 16 22 22" src="https://github.com/user-attachments/assets/8bade56a-b48d-461e-8832-ac8b09fdd035" /> | | Dense Mode | <img width="405" height="705" alt="Screenshot 2026-04-07 at 16 22 06" src="https://github.com/user-attachments/assets/d9c461ac-f521-4a70-84f6-0d70d8240f97" /> | <img width="405" height="705" alt="Screenshot 2026-04-07 at 16 22 27" src="https://github.com/user-attachments/assets/1aba1990-b84f-46cf-aa8d-ea9ecc788162" /> | task-3630380
When companies trade with each other, vendor bills created automatically are now linked back to the original purchase order lines. This helps keep purchasing, billing, and reconciliation aligned without extra manual matching.
Original PR description
Conside the following flow: 1) Activate intercompany transactions between company A & company B for both SO and Bills 2) Create a PO in company A with vendor as company B 3) The SO is created in company B, Validate it 4) Create the invoice in company B, post it 5) The Vendor Bill is created in company A The flow is still missing one last step: the PO matching. This commit ensures that the lines of the vendor bill created in company A are matched with the lines of the original PO. task-6075588
Financial reports can now group aggregated results, enabling richer reporting views and supporting future reporting capabilities such as snapshots and tax closing improvements. Report line foldability was also standardized so reports behave more consistently when users expand or collapse sections.
Original PR description
### [IMP] account_reports: foldability as selection field * Adapt AccountReportLineData, _get_groupby, and tests to the new 'foldability' selection. * Apply upgrade_code script for removing the…
### [IMP] account_reports: foldability as selection field
* Adapt AccountReportLineData, _get_groupby, and tests to the new 'foldability' selection.
* Apply upgrade_code script for removing the unnecessary foldable field in reports data files if they
will be correctly computed.
* For inconsistencies reported by the script, manually set the foldable values on the reports and tests.
### [IMP] account_reports: Support groupby on aggregations
The aggregation engine didn't support groupby before due to limitations
existed from the beginning of Reportalypse.
With the removal of the 'load more'<sup>1</sup> feature, other engines don't run a SQL LIMIT anymore.
Resulting on the aggregation engine can obtain the full result, and
'groupby' calculation be done.
That support will help with incoming improvements: Snapshot feature<sup>2</sup> and
Tax closing computation refactoring
<sup>1</sup> : https://github.com/odoo/enterprise/commit/ff2895144ecfc66d2b23bb872b39f5b446ae0da6
<sup>2</sup> : https://github.com/odoo/enterprise/pull/113677
task-5891053The Barcode app now matches the standard inventory flow when validating incomplete transfers, letting users decide whether to create a backorder when the setting asks for confirmation. It also gives clearer warnings and quantity details for incomplete transfers, with a cleaner mobile popup to reduce mistakes and extra follow-up work.
Original PR description
- Currently, when the operation type was configured to `Ask` for creating backorders, the Barcode app always treated it as backorder would always be created, since it only showed `Validate` and `Stay…
- Currently, when the operation type was configured to `Ask` for creating backorders, the Barcode app always treated it as backorder would always be created, since it only showed `Validate` and `Stay on Transfer` options. This behavior was inconsistent with the backend flow and forced users who did not wish to create a backorder. Users had to manually cancel the backorder afterwards, adding unnecessary steps and extra effort. - Also, when the operation type is configured to `Always` or `Never` for creating backorders, users are not clearly warned that the transfer is incomplete and receive no visible indication of how many products have been processed or how many remain, leaving users without a clear indication that some products remain unprocessed during validation. - Additionally, the backorder popup on `mobile screens` appeared cluttered, as product rows and quantities were not clearly aligned on small screens, leading to a `poor user experience`. These changes ensure that when the operation type is set to `Ask`, users can choose whether to create a backorder or not during validation, avoiding unwanted backorders and manual cancellation. They also ensure that when set to `Always` or `Never`, users are clearly warned if the transfer is incomplete and shown how many products have been processed and how many remain. The mobile layout is improved to provide a cleaner and more `organized view`, and when set to Never, missing items are highlighted in red with a clear label, helping them to make more informed validation decisions. TaskID-4797752
The work order form has been reorganized to make key information and actions easier to find. Users now get a cleaner status selection, more accessible action buttons, larger work order names, visible quality checks, and a communication area for follow-up discussions.
Original PR description
This commit rearange the blocks of the workorder form view: - change the statusbar widget by the dropdown widget - move the buttons from the header to stat button - increase name size Task: 5936292
Planning materials can now be linked to a specific employee. When that employee is added to a planning slot, their assigned material is automatically added as a resource and scheduled with the shift, reducing manual setup and improving resource accuracy.
Original PR description
In this commit, we add a field "Assigned To" to materials. This allow users to assign one employee to the material. With that, when adding an employee to a planning slot, its assigned material will automatically added to the resources, and a shift will be assigned to it. task-5259038
Warehouse barcode scanning now better handles packages that include non-stored products during deliveries and receipts. This helps operators complete prepared package transfers without unnecessary backorder prompts or manual quantity updates.
Original PR description
When dealing with multi-step deliveries, it can happen to pack a non-stored good in an earlier step (e.g. PICK). This means that the package will be set as source & destination for the following transfers. However when scanning the package in those transfers, since we're only checking the quants of the package (i.e. so the effective stored content), the non-stored goods are never picked, and at transfer validation it would ask for backorders, which makes little sense. Now also selects all non-stored goods that have the scanned package as source. --- For receptions, if packages are already set through the back-end on the move lines, when processing the receipt in barcode, we can now simply scan the prepared package to automatically fill its content. Task-5266021
Resolved issues and error corrections
The Dutch ICP report now rounds amounts down to whole numbers, matching the rounding already used in exports. This reduces confusion and helps businesses compare report and export values consistently for Dutch tax reporting.
Original PR description
Description of the issue this commit addresses: The Dutch tax authority lets ICP amounts be rounded down which is the behavior of the exports but not of the report itself meaning the values to not match and is quite confusing. --- Desired habevior after this commit is merged: The integer rounding DOWN is added on the ICP report to restore matching values --- task-6065382 Forward-Port-Of: odoo/enterprise#114277 Forward-Port-Of: odoo/enterprise#112953
Payment reminder emails for subscriptions now avoid showing the exact automatic cancellation date until the final 24-hour reminder. This helps encourage earlier payment while also fixing cases where a zero-day grace period was incorrectly treated as the default delay.
Original PR description
- Hide close date until final 24h payment reminder: This commit updates the payment reminder logic to only expose the contract closing date precisely 24 hours before the subscription is automatically cancelled. By hiding the date during the earlier standard reminders, we create urgency without encouraging procrastination. It also fixes a native Python evaluation bug where an auto-close limit explicitly set to zero days would be treated as "falsy" and incorrectly default to a 15-day grace period. Both manual payments and tokenized payment failures have been updated to follow these new rules. task: 5902221
Payments dated in the future are now excluded from Mexico CFDI payment signing, preventing users from accidentally submitting documents that government rules do not allow. The invoice action to update payments will not appear when only future payments exist, and future payments are ignored when eligible payments are processed.
Original PR description
To sign a payment registered in the future is not allowed by the government. See http://omawww.sat.gob.mx/tramitesyservicios/Paginas/documentos/Guia_llenado_pagos.pdf Steps: - Create a PDD invoice (the due date should be at least 1 month later than the invoice date) - Send it to CFDI - Register a payment in the future -> We have the 'Update payments' button that appear on the invoice view, if you clik on it the payment will be signed With this commit, we filter out the payments with a future date, that way we don't have the 'Update Payments' button if there are only future payments, or the future payments won't be taken into account when clicking on the button. opw-5934753 Forward-Port-Of: odoo/enterprise#114074 Forward-Port-Of: odoo/enterprise#112320
A payroll employee field in Belgian localization was being checked too early, before the needed payslip data existed. This change prevents that premature check so holiday pay recovery values are calculated at the right time, improving reliability of payroll tests and results.
Original PR description
…ield The computed, non-stored field `l10n_be_holiday_pay_recovered_n1` had tracking enabled. When writing to any field on the employee, the `write` method calls `_track_prepare` for tracked fields if `mail_notrack` is not set in the context. `_track_prepare` reads the current value of tracked fields to store initial values. Because `l10n_be_holiday_pay_recovered_n1` is non-stored with no dependencies, this triggered a computation at the very beginning of the test, before payslips existed. Later, when payslips were created, the field was never recomputed, causing incorrect values and test failures. Previously, the `tracking_disable` context prevented early computation. The fix removes the tracking attribute entirely, so the field is only computed when accessed, avoiding premature reads and fixing the tests. task: 6095445 Forward-Port-Of: odoo/enterprise#114063 Forward-Port-Of: odoo/enterprise#113015
Subscription payments using a bank default account are now automatically matched with the related invoice. This prevents paid subscription invoices from incorrectly remaining marked as not paid, reducing manual follow-up for finance teams.
Original PR description
Currently, when a subscription payment is processed through a provider configured to use as outstanding account the bank default account, the resulting invoice may remain in an 'open' state even…
Currently, when a subscription payment is processed through a provider configured to use as outstanding account the bank default account, the resulting invoice may remain in an 'open' state even though the payment transaction is 'done'. This type of configuration is usually done when users want to skip the bank reconciliation process, and just create payments without the need to reconcile the payments with transactions. Steps to reproduce: - In Settings, under Sales > Invoicing, disable Automatic Invoice - Activate demo payment method - In the main Bank account add the default account as outstanding account for demo payment method. - Create a sales order with a subscription product - Open Preview - Pay - Go back to the sales order and open the created invoice Issue: The invoice is created and the payment is registered, but the invoice remains 'Not Paid'. Analysis: The invoice and the payment move lines are not automatically reconciled during the post-processing of the transaction, leaving the invoice unbalanced. opw-5869303 Forward-Port-Of: odoo/enterprise#110656
Asset creation eligibility for accounts is now based on whether an account is configured as accumulated depreciation on another account, rather than whether it was used by existing assets. This prevents legacy asset records from blocking valid new asset creation and keeps depreciation account choices clearer.
Original PR description
This commit fixes the `can_create_asset` flag on accounts to limit the creation of asset based on if account is used as an accumulated depreciation on another account, instead of used by an asset. This requirement came after users with old assets couldn't create assets using some accounts because they were used by the old assets with no possible way to change that. Better to limit on configuration data instead of business data. Also now, accounts that have models set do not show up in the accumulated depreciation dropdown. no-task Forward-Port-Of: odoo/enterprise#114096
This update fixes an error that could block upgrades of the Accounting Reports module. It ensures required report grouping data is correctly set, helping upgrades complete smoothly without manual intervention.
Original PR description
Bug introduced by odoo/enterprise#113124, when trying to upgrade the module `account_reports`, traceback error: > psycopg2.errors.NotNullViolation: null value in column "horizontal_group_id" > of relation "account_report_horizontal_group_rule" violates not-null constraint.
The Documents mobile search panel now opens folder sections correctly again, including company and other grouped values. This also restores missing section icons and improves styling and keyboard navigation for a smoother mobile experience.
Original PR description
Follows the changes made in community and fixup some styling introduced in commit[1] - remove unneccessary styling - rescope styling in right files - fixup the searchpanel inside the bottom sheet task-6090140 [1]: odoo/enterprise@c573cd168e2e01bb9390ef7aae714688100fb2ae Community PR: https://github.com/odoo/odoo/pull/257378
Database synchronization no longer fails with an error when a user loses access, receives a new remote document, or the remote database cannot be reached. This helps users complete synchronization cleanly and ensures removed access is reflected without a disruptive traceback.
Original PR description
The aim of this commit is to allow a db_user to synchronize a database without facing a Traceback. Context: - A new document has been received by a remote db and we try to synchronize it. - The current user access has been removed from the remote db. - The database is unreachable. Before this commit: In all 3 previous cases, an access error would be raised because a db_user can't write on a database. After this commit: The synchronization finish gracefully and the db_user should have lost his access if it was removed from the remote db. task-id: 6046087 Forward-Port-Of: odoo/enterprise#114204 Forward-Port-Of: odoo/enterprise#113826
Unpaid work entry types are now properly linked to the Belgium monthly employee pay structure. This prevents unpaid absences from being incorrectly included in payslip payments, improving payroll accuracy for Belgian employees.
Original PR description
Work entry types with "unpaid" in their name were not linked to the "Belgium: Employees Monthly Pay" structure, causing them to still be paid during payslip computation. task-6123817
The Time Off overview no longer crashes when a new company or localization has no time off records yet. This ensures users can open the dashboard normally even before any time off data has been created.
Original PR description
Steps to reproduce: 1. Create a new company or install a localization (resulting in 0 time off records). 2. Open the Time Off overview (defaults to the Dashboard Gantt view). -> OwlError: Cannot…
Steps to reproduce: 1. Create a new company or install a localization (resulting in 0 time off records). 2. Open the Time Off overview (defaults to the Dashboard Gantt view). -> OwlError: Cannot destructure property 'type' of 'fields[fieldName]' as it is undefined. Cause: Following the recent work entries refactoring, the JS function `_fetchUserFavoritesWorkEntries` was added to the base `HrHolidaysGanttModel` to fetch data from the `hr.leave` model. When the Dashboard (`hr.leave.report.calendar`) has 0 records, the frontend `SampleServer` is activated to generate fake background data. It builds its schema based on the Dashboard view. When the JS unconditionally fires the cross-model RPC call to `hr.leave` (grouping by `work_entry_type_id`), the `SampleServer` intercepts it. Because it doesn't have `work_entry_type_id` in its Dashboard schema, it fails to evaluate the field type and crashes the Owl lifecycle. Solution: Restrict the `_fetchUserFavoritesWorkEntries` call in `_fetchData` so it only runs when not using sample data (`!this.useSampleModel`). This prevents the `SampleServer` from intercepting unsupported cross-model queries to `hr.leave` when loading empty views on fresh databases. task-5969290 Forward-Port-Of: odoo/enterprise#108618
The rental duration test has been adjusted to avoid occasional failures caused by timezone differences around midnight. This helps keep automated validation stable without changing the customer-facing rental experience.
Original PR description
The rental test intermittently fails on Runbot due to timezone offsets. Near midnight, the start time can appear after the end time, causing the datepicker to auto-shift the end date by 24h. This commit uses `getFutureDate` to set full future datetimes, bypassing browser timezone and midnight crossover issues. Runbot Error: https://runbot.odoo.com/odoo/runbot.build.error/242000
Customers booking appointments can use quick checkout by default, avoiding repeated requests for full billing address details. This improves the booking and payment experience where taxes are typically based on the event or appointment location rather than the customer address.
Original PR description
Forward-Port-Of: odoo/enterprise#114205 Forward-Port-Of: odoo/enterprise#113575
Odoo now handles LinkedIn organization image data more safely when connecting an account. If LinkedIn omits an optional image link, the setup process skips that image instead of failing, helping users complete the connection reliably.
Original PR description
When importing a LinkedIn account, Odoo fetches the image metadata of the organization page and expects each returned image to contain `downloadUrl`. For some LinkedIn accounts this key is missing from the image response, which makes the callback crash with `KeyError: 'downloadUrl'` and prevents the account from being connected. LinkedIn's current Images API documentation describes `downloadUrl` as an optional field, so the import flow should not assume it is always present. This patch skips image entries without `downloadUrl` instead of crashing. opw-6099244 Forward-Port-Of: odoo/enterprise#113812
Australian payroll no longer crashes when an employee contract has a wage but no schedule pay selected. This keeps employee payroll records usable even when pay schedule information is temporarily missing or removed.
Original PR description
This error occurs when the schedule pay is removed from an employee contract with a defined wage. Steps to reproduce: - Install `l10n_au_hr_payroll` module with demo data - Switch to `My Australian…
This error occurs when the schedule pay is removed from an employee contract with a defined wage.
Steps to reproduce:
- Install `l10n_au_hr_payroll` module with demo data
- Switch to `My Australian Company`
- Open any Employee > Payroll > `Wage` remove `schedule pay`
Traceback:
```py
File "/home/odoo/src/enterprise/saas-19.2/l10n_au_hr_payroll/models/hr_version.py", line 549, in _compute_wage
version.wage = Payslip._l10n_au_convert_amount(daily_wage, "daily", version.schedule_pay)
File "/home/odoo/src/enterprise/saas-19.2/l10n_au_hr_payroll/models/hr_payslip.py", line 511, in _l10n_au_convert_amount
coefficient = PERIODS_PER_YEAR[period_from] / PERIODS_PER_YEAR[period_to]
KeyError: False
```
We are encountering this error because the `schedule pay` is removed, causing the field to become `False`. This False value is then passed to the `_l10n_au_convert_amount` [method], resulting in a `KeyError`.
[method]: https://github.com/odoo/enterprise/blob/92c584cc1426ac70f6f77aa8216c17004fa42d35/l10n_au_hr_payroll/models/hr_payslip.py#L500-L509
sentry-7401189447
Forward-Port-Of: odoo/enterprise#113623Studio-created models with Chatter enabled now get the activity filters needed for the activity menu. This means users clicking Late, Today, or Future activities see the correct records instead of all records.
Original PR description
Steps to reproduce
==================
- Install studio
- Create a new app
- Create a new model
- Keep the Chatter toggled (use_mail)
- Exit studio
- Create three records, one with an activity in the past, one today and one in the future
- Click on the clock status icon in the top right
- There should be a section with the new model
- Click on 1 Late => every records is displayed
- Same for Today and Future
Cause of the issue
==================
https://github.com/odoo/odoo/blob/b6434b91a7f94075e1372ec827787504ef7aa4f0/addons/mail/static/src/core/web/activity_menu.js#L39-L77
For this feature to work, the activities_{overdue,today,upcoming_all} filter should be present
Solution
========
We add them to the search view. They are all pretty much implemented the same way in every model.
opw-6069150
Forward-Port-Of: odoo/enterprise#114217
Forward-Port-Of: odoo/enterprise#113011Users can now clear the scope on an ESG emission source without triggering an error. The change keeps related activity flow fields safely empty when no scope is selected, improving reliability while editing ESG records.
Original PR description
Currently, an error occurs when the user removes the scope of the emission source. **Steps to Reproduce:** - Install the `esg` module. - Create an `emission source` record or open an `existing one`.…
Currently, an error occurs when the user removes the scope of the emission source. **Steps to Reproduce:** - Install the `esg` module. - Create an `emission source` record or open an `existing one`. - Remove the `scope` value and click anywhere. `ValueError: Compute method failed to assign esg.emission.source(<NewId origin=1>,).activity_flow_direct_indirect` **Cause:** Error started occurring in 19.0 due to a change in selection field behavior. Since from [commit](https://github.com/odoo/odoo/pull/214422/commits/8d2a42ac419fdf7943a0c11beb8c5de6c6f85bef), selection fields no longer display an “empty” value. To remove a value from a selection field, the user must clear the field, similar to a many2one field. when the user removes the scope value, The system attempts to compute the activity flow, but since the scope is False, it does not match any case [1]. As a result, the method fails to assign a value to activity_flow_direct_indirect, raising an error. This commit ensures that the activity flow and activity flow direct indirect are initialized to False. If no condition matches, the field remains False, preventing the assignment failure. [1]: https://github.com/odoo/enterprise/blob/eaf4b7559b8eb6c538820d6e54f583a41077ac3d/esg/models/esg_emission_source.py#L79-L89 Forward-Port-Of: odoo/enterprise#114079
Code cleanup and technical improvements
This change updates internal screen templates across several Odoo apps so they are ready for the next version of Odoo's web interface technology. It should not change day-to-day behavior, but helps reduce upgrade risk and keeps affected features compatible with upcoming framework requirements.
Original PR description
In preparation for OWL3, where template variables will need to use .this to target component variables, we add .this to template variables that are targetting the component. Script PR: https://github.com/odoo/odoo/pull/247965 Community PR: odoo/odoo#259313 IF THIS SCRIPT ADDED A BAD MIGRATION REPORT TO (JESC), WE MIGHT NEED TO WHITELIST THE BUG task: OWL3 prep - add this. to template variables
This update removes obsolete instructions that suppressed change tracking in several business flows and test/demo data. It helps Odoo rely on its standard tracking behavior, reducing hidden side effects and making future changes easier to maintain without altering core user workflows.
Original PR description
Helpdesk: useless usage in demo data Sale connectors: action_lock writes on lock field, if people don't want to see any tracking of that field, better remove the tracking on the field. Otherwise let Odoo track changes. Sale_subscription: remove notrack around payment_exception update. That field is not tracked, and that could prevent any tracking at the next flush time.
6 changes
Resolved issues and error corrections
This update prevents an error when saving an appointment that has no organizer assigned but includes a Google Meet link. It also stops template previews from failing in the same situation, improving reliability for users who manage appointments without a linked user.
Original PR description
Currently an error is generated when the user tries to save an appointment as follows: - Install the appointment_google_calendar module without demo data - Create a new appointment as below: - Remove…
Currently an error is generated when the user tries to save an
appointment as follows:
- Install the appointment_google_calendar module without demo data
- Create a new appointment as below:
- Remove Organizer (user_id)
- Set the Google Meet link inside VideocallURL, e.g., https://meet.google.com/aaa-aaa-aaa
- An error occurs in the log and a message is shown to the user when save the record
- Also, an error occurs when trying to preview `Appointment: Attendee Invitation`
after creating appointment as follows:
- Set the Google Meet link inside Videocall URL > save
- Remove Organizer (user_id)
Error:
```
test odoo.addons.mail.models.mail_render_mixin: Failed to render QWeb template for Mail Template: 'Appointment: Appointment Booked' (ID: 12) - Context language:en_US
Target Model: calendar.event
Error: Error while render the template
ValueError: Expected singleton: res.users()
```
This is because the method `is_google_calendar_synced` expected a single
record, but since we removed `user_id` from the event (appointment),
it will generate a singleton error.
This commit will fix the above issue by not calling `is_google_calendar_synced`
when the event does not have `user_id`.
sentry-7393595716
Forward-Port-Of: odoo/enterprise#113966This update ensures that salary payments split across multiple bank accounts receive unique identifiers in the SEPA export. It prevents invalid payment files and helps payroll exports process correctly without affecting employees who use only one bank account.
Original PR description
### Issue: If a payslip is split into multiple bank accounts (Salary Allocation), the generated SEPA file contains duplicate <InstrId> tags ### Cause: The `_get_payments_vals` method, `InstrId` is…
### Issue: If a payslip is split into multiple bank accounts (Salary Allocation), the generated SEPA file contains duplicate <InstrId> tags ### Cause: The `_get_payments_vals` method, `InstrId` is based on the payslip ID When a single payslip generates multiple transaction blocks, this ID is duplicated, violating the ISO 20022 requirement for unique instruction identifiers https://knowledge.xmldation.com/support/iso20022/general_rules/instrid This commit adds a unique suffix (e.g., -1, -2) to the `InstrId` for each transaction generated from the same payslip to ensure technical uniqueness Nothing change when you only have one account This is the part of the code that use the payment name: https://github.com/odoo/enterprise/blob/194a8d35ef3e9b47ff566479b0c35c0f963fb42d/account_iso20022/models/account_journal.py#L294-L299 ### Steps to reproduce: - Install `hr_payroll_account_iso20022` with demo data - On the Bank Journal, set a valid IBAN (e.g. BE04957751619131) for `Bank Account Number` - Open the Employee page for Abigail Peterson - In the Personal tab, add 2 Bank Accounts (Send Money: True, Account Number: any) - Click on Salary Allocation and Save (You'll have a 50/50 ratio) - Create a new Pay Run (for Abigail Peterson) - Open the last PaySlip and Validate - Create Payment Report (Export Format: SEPA) - Download the Payment Report and check the <InstrId> tags opw-6069670
This update prevents a crash when users compare a tax report against one past period, including cases where the report contains text values. It makes the comparison view more reliable and avoids an error when Odoo calculates percentage columns.
Original PR description
To reproduce: - Create a company in LU - Open the annual tax report for LU - Click on the comparison filter, compare with 1 period in the past ==> Traceback. This happens because that report contains a string value (an editable one, but it's not important here). Since there are only 2 comparison periods, we try creating the "%" column, comparing their amounts. The condition checking whether or not to display "N/A" was wrong, as it considered the values could only be int/float or None. Here, they are strings, so we don't enter that condition and crash when trying to evaluate float_is_zero on a string. Forward-Port-Of: odoo/enterprise#113330 Forward-Port-Of: odoo/enterprise#112619
This change prevents an error that could appear when a user removes the scope from an emission source. It keeps the ESG form working smoothly and avoids interruption while editing records.
Original PR description
Currently, an error occurs when the user removes the scope of the emission source. **Steps to Reproduce:** - Install the `esg` module. - Create an `emission source` record or open an `existing one`.…
Currently, an error occurs when the user removes the scope of the emission source. **Steps to Reproduce:** - Install the `esg` module. - Create an `emission source` record or open an `existing one`. - Remove the `scope` value and click anywhere. `ValueError: Compute method failed to assign esg.emission.source(<NewId origin=1>,).activity_flow_direct_indirect` **Cause:** Error started occurring in 19.0 due to a change in selection field behavior. Since from [commit](https://github.com/odoo/odoo/pull/214422/commits/8d2a42ac419fdf7943a0c11beb8c5de6c6f85bef), selection fields no longer display an “empty” value. To remove a value from a selection field, the user must clear the field, similar to a many2one field. when the user removes the scope value, The system attempts to compute the activity flow, but since the scope is False, it does not match any case [1]. As a result, the method fails to assign a value to activity_flow_direct_indirect, raising an error. This commit ensures that the activity flow and activity flow direct indirect are initialized to False. If no condition matches, the field remains False, preventing the assignment failure. [1]: https://github.com/odoo/enterprise/blob/eaf4b7559b8eb6c538820d6e54f583a41077ac3d/esg/models/esg_emission_source.py#L79-L89
There were some translation overrides for `fr_BE` and `fr_CA` that were incorrect or unnecessary. We are deleting these files so they use the correct translations in `fr` instead. In the `nl_BE` translation, we are fixing a menu item so it is shorter, but still correct. task-5921458 Forward-Port-Of: odoo/enterprise#114069 Forward-Port-Of: odoo/enterprise#106998
Original PR description
There were some translation overrides for `fr_BE` and `fr_CA` that were incorrect or unnecessary. We are deleting these files so they use the correct translations in `fr` instead. In the `nl_BE` translation, we are fixing a menu item so it is shorter, but still correct. task-5921458 Forward-Port-Of: odoo/enterprise#114069 Forward-Port-Of: odoo/enterprise#106998
This change removes automatic tracking from a payroll field that should only be calculated when needed. It prevents the value from being read too early, which was causing incorrect holiday pay results and failed payroll tests.
Original PR description
…ield The computed, non-stored field `l10n_be_holiday_pay_recovered_n1` had tracking enabled. When writing to any field on the employee, the `write` method calls `_track_prepare` for tracked fields if `mail_notrack` is not set in the context. `_track_prepare` reads the current value of tracked fields to store initial values. Because `l10n_be_holiday_pay_recovered_n1` is non-stored with no dependencies, this triggered a computation at the very beginning of the test, before payslips existed. Later, when payslips were created, the field was never recomputed, causing incorrect values and test failures. Previously, the `tracking_disable` context prevented early computation. The fix removes the tracking attribute entirely, so the field is only computed when accessed, avoiding premature reads and fixing the tests. task: 6095445 Forward-Port-Of: odoo/enterprise#114063 Forward-Port-Of: odoo/enterprise#113015
11 changes
Enhancements to existing features
The French chart of accounts now separates account 649 into two new accounts, 6491 and 6492. This helps produce a more accurate Profit and Loss report by distinguishing social security charges from salaries.
Original PR description
Splitting account 649 into two new accounts (6491 and 6492) is necessary to handle the Profit and Loss report properly. This ensures we can accurately separate social security charges from salaries in the report. Reference: ANC PCG 2026, page 445, note (h) https://www.anc.gouv.fr/files/anc/files/1_Normes_fran%C3%A7aises/recueil/RECEUIL-PCG-2026-AVEC-COUVERTURE.pdf task-6053784 Forward-Port-Of: odoo/odoo#255038
The French accounting report now separates account 649 into two new accounts, 6491 and 6492. This helps the Profit and Loss report distinguish social security charges from salaries more accurately, improving the quality of financial reporting.
Original PR description
Splitting account 649 into two new accounts (6491 and 6492) is necessary to handle the Profit and Loss report properly. This ensures we can accurately separate social security charges from salaries in the report. Reference: ANC PCG 2026, page 445, note (h) https://www.anc.gouv.fr/files/anc/files/1_Normes_fran%C3%A7aises/recueil/RECEUIL-PCG-2026-AVEC-COUVERTURE.pdf task-6053784 Forward-Port-Of: odoo/enterprise#111420
Resolved issues and error corrections
Mobile users can no longer select combo products directly on the sales order line form. This avoids creating incomplete zero-price lines without the required child items, which could cause errors or incorrect orders.
Original PR description
Combo products bypasses the configurator in mobile view, resulting in a 0-price line with no child lines. Exclude them via domain on the field. opw-5999935
This update fixes an error that could prevent users from generating a W2 CSV file when the End Date field was left blank. If no end date is provided, the system now uses the current year in the file name so the export completes successfully.
Original PR description
Currently, an error occurs when user tries to create a csv for w2 form with no end date defined. Steps to replicate: - Install `l10n_us_hr_payroll`. - Open Payroll > Reporting > W2 Report. - Click…
Currently, an error occurs when user tries to create a csv for w2 form with no end date defined.
Steps to replicate:
- Install `l10n_us_hr_payroll`.
- Open Payroll > Reporting > W2 Report.
- Click `New` > Remove value from `End Date` and click Generate.
Error:
```
File '/home/odoo/odoo19/enterprise/l10n_us_hr_payroll/models/l10n_us_w2.py', line 249, in action_generate_csv
self.csv_filename = f'form_w2_{self.date_end.year or date.today().year}.csv'
^^^^^^^^^^^^^^^^^^
AttributeError: 'bool' object has no attribute 'year'
```
Cause:
- As the user did not give any value for `End Date`, False was passed and when the execution flow reached [here] `self.end_date` is False and attempting to access `self.end_date.year` results in this error.
Solution:
- If we do not receive the `self.end_date` while generating the CSV, we will use the current year to generate the CSV file name.
[here]: https://github.com/odoo/enterprise/blob/01be8d6e9384bcb340559847d529b4887e073519/l10n_us_hr_payroll/models/l10n_us_w2.py#L248
No IDThis update prevents the Attendance kiosk from failing when users search for an employee after selecting a department. It improves reliability by skipping invalid search conditions that could previously cause the kiosk to crash.
Original PR description
**Steps to Reproduce:**
1. Install `hr_attendance` module with demo data.
2. Go to Attendances > Kiosk Mode > Identify Manually.
3. Select any department.
4. Try searching for an employee.
**Error:**
`ValueError - not enough values to unpack (expected 3, got 1)`
**Cause:**
The `employees_infos()` controller assumes that every item in the domain is a valid triplet (field, operator, value). However, the domain may also contain logical operators ('&'), which are not triplets. And then trying to unpack such entries leads to a ValueError.
**Fix:**
Add a validation to ensure the condition is a proper triplet before unpacking. Non-conforming entries (logical operators) are skipped.
sentry-7401444075
opw-6113268This update makes an unstable HR leave test run consistently by fixing the date it uses during execution. It prevents random failures caused by weekends or existing demo data, so automated checks are more reliable.
Original PR description
### Issue before this commit: The test test_manager_can_approve_from_leave_report_calendar is unstable and fails depending on the execution date or existing demo data. ### Cause of the issue: The test lacks temporal isolation. Odoo's constraint logic triggers a ValidationError when a leave is requested on a non-working day or overlaps with existing records: odoo.exceptions.ValidationError: The following employees are not supposed to work during that period: David Employee. Commit that caused the error: https://github.com/odoo/odoo/commit/83d5c84fa0ead1557fbb6eff6855f77ee4771dc4 ### Reason to introduce the fix: To ensure test determinism by using @freeze_time. Freezing the date to a known working weekday prevents intermittent failures caused by the real-time calendar and ensures the focus remains on validating the manager's approval flow. runbot-242574 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
We fixed an automated test in the salary package module so it no longer depends on demo-only sample data. This makes the test more reliable and helps avoid failures in environments where demo data is not available.
Original PR description
### Issue: - We were referring an existing XML ID in our test case, but that record is only created in demo data. ### Fix: - No need to use the demo record Id, instead, create a new record. Task: 6115762
This update preserves the green link styling in frozen shared spreadsheets while still preventing those links from being clicked. It matters because dashboard layouts keep their intended look without exposing internal navigation from public views.
Original PR description
Since https://github.com/odoo/odoo/pull/166843, we remove the odoo links entirely from the spreadsheet on `freeze and share`. While it is true that the link is not usable from a public page (and that…
Since https://github.com/odoo/odoo/pull/166843, we remove the odoo links entirely from the spreadsheet on `freeze and share`. While it is true that the link is not usable from a public page (and that we'd somehow leak internal views information in the links), cells with links benefit from a specific style that is not hardcoded on the cell but rather computed based on their content. By removing the links from teh cells altogether, the greenish link style is lost on those cells and we actually rely on that style for our dashboards layout. To preserve the intension of https://github.com/odoo/odoo/pull/166843, we introduce a new type of links `neutralized` which allows the cell to be recognized as a link (and benefit from the style) while disabling their behaviour (no click). Task-6063301 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#256357
This update fixes the Documents app so the browser back button returns users to the previous folder or list instead of reopening the same page. It improves navigation flow and helps users move around Documents more reliably without losing their place.
Original PR description
Bug === When going back in the kanban / list view of the documents module, it reload the same page. Technical ========= They are 2 bugs in reality, not one: - The web client pushes the state in the router when the controller is mounted. This is fine for most Odoo views, but for documents it mean that the kanban view will be restored without the access token in the URL. - When going back, the search model "toggle the category" of the current folder. But, that current folder is not the previous one, and so it re-open the same folder just after redirecting to the previous URL. Task-6050772
This update corrects an issue in the Mexico localization where invoices could end up off by one cent when certain included-tax rates were combined. It restores the expected rounding behavior so totals match the entered price, reducing billing discrepancies for users in Mexico.
Original PR description
**STEP TO REPRODUCE** 1. Install l10n_mx. 2. Change the included in price settings to 'Tax included' for a 16% tax and a 53% tax. 3. Create a invoice with a product with a unit price of 360, add the 53% tax and then the 16% tax. 4. Notice the total of the invoice is 360.01 instead of 360. The issue was discussed with (las), l10n_mx_edi should no longer require to override the rounding mode for taxes. opw-5963855
This change updates the Mexican e-invoicing test so it matches the restored rounding behavior. It helps prevent false test failures and keeps the validation aligned with how invoices are now calculated.
Original PR description
https://github.com/odoo/odoo/pull/255574 change the rounding mode back to mixed. This break the test modified in this PR. opw-5963855
4 changes
Enhancements to existing features
This update removes Odoo’s hard dependency on an outdated Python packaging helper that is being phased out. It helps the system stay compatible with newer Python setups and reduces the risk of installation or startup issues as those tools evolve.
Original PR description
pkg_resources is deprecated as a library. It's use becomes problematic as, for instance, since setuptools 71, importing pkg_resources makes all vendored dependencies of setuptools visible on sys.path. pkg_resources is even entirely removed since setuptools 81. This commit keeps pkg_resources as a primary approach for compatibility reason but provides a fallback when not present (like with an up-to-date setuptools) without changing the current requirements (i.e. no additional dependency on `packaging`). Note: while not a backport, this is inspired by odoo/odoo#181768
Resolved issues and error corrections
This change rolls back a previous update that altered how child contact names were shown in invoices and partner records. It helps restore the prior display behavior for customers and prevents unexpected name formatting changes in business documents.
Original PR description
This reverts commit 0ef4c1d06fdf999ad5cdad696069aec8f2f943c5. opw-5900567
The system now decides whether to add the co-contractant tax exemption note based on the invoice’s fiscal position instead of the customer’s. This avoids inconsistencies in exported invoice data and helps ensure the legal note matches the actual invoice setup.
Original PR description
The decision to add a tax exemption reason for co-contractant fiscal position was being decided by the FP of the customer which could cause inconsistencies, instead, it is now tied to the FP of the invoice related-task-id-5905176
Documentation and clarification updates
This pull request adds the corporate contributor agreement documentation for Vascular Wellness. It mainly serves the legal and compliance process for contributing to Odoo, rather than changing any product behavior.
Original PR description
Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr