Monday, November 24, 2025
26 changes · saas-18.3
Resolved issues and error corrections
This fix ensures that when a delivered subscription product is returned, the system updates the subscription’s delivered quantity correctly. This matters because billing and service tracking stay accurate after product returns.
Original PR description
**Steps to reproduce** - Create a new subscription using a subscription product. Confirm it. - Run the "Sale Subscription: generate recurring invoices and payments" scheduled action to generate the delivery. Validate the delivery. - Return the delivery and validate the return. - Issue: the delivered quantity of the sale order line is not updated. **Cause** Currently, we consider a move as related to a subscription period based on the `date_deadline` field (see _get_outgoing_incoming_moves). Since `_prepare_procurement_values` is not called when creating a return, the `date_deadline` is not set on the return moves. **Change** The returns linked to a move in a subcription period will be conisdered for the computation of the delivered quantities. opw-5136406 Forward-Port-Of: odoo/enterprise#99734 Forward-Port-Of: odoo/enterprise#98690
This update fixes an error that could appear when opening the Accounts Coverage Report for Spanish balance sheet reports. It ensures the report data is stored correctly and loaded in the right order, so users can view the report without encountering a traceback.
Original PR description
Step to reproduce: - for Spain localization, in developer mode: - Go to Balance sheet - Select either report 'Balance sheet - SMEs (ES) or Complete Balance Sheet (ES) - Click on the parameters button…
Step to reproduce:
- for Spain localization, in developer mode:
- Go to Balance sheet
- Select either report 'Balance sheet - SMEs (ES) or Complete Balance Sheet (ES)
- Click on the parameters button
- Click on the "Accounts Coverage Report"
Observation:
- we receive a traceback
```
psycopg2.errors.InvalidTextRepresentation: invalid input syntax for type integer: "%(balance_sheet_11700_account)d"
LINE 1: ...ccount_tag" WHERE ("account_account_tag"."id" IN ('%(balance...
```
Cause:
- few records used a wrong format style for values of `domain_formula`
- These faulty domains were not [evaluated](https://github.com/odoo/odoo/blob/2070e30c540a066fb80851527e5e54e97fb23c4b/addons/account/models/account_report.py#L450-L453), but inserted into database as is.
- when browsing account.tag record using these domain, record ids were expected,
instead we got its string representation , causing traceback
https://github.com/odoo/enterprise/blob/8fa6fb27d2a79ee299361b281dc82182feee5860/account_reports/models/account_report.py#L5679-L5680
Fix:
- we fix the data file, which is properly evaluated and stored in database.
- Manifest's data file order is changed, so that account tags is loaded first.
opw-5224114
Forward-Port-Of: odoo/enterprise#98745This update lets Canadian users choose a different start date for annual reporting when their fiscal year does not end on December 31. It helps ensure year-end filings and closings are calculated on the correct dates, aligning with allowed government rules.
Original PR description
If a user from CA has a fiscal year on something other than the 31/12 and needs to return annually, he can't do his closing on the right bounds. We now allow CA to show the field to be able to shift it, as government allow it. Later, we will change the heuristic to be smarter to show it as soon as it may cause issue. opw-5193999 Forward-Port-Of: odoo/enterprise#100006
This update restores the correct payment message setting for standard ISO 20022 payments, so non-SEPA transfers are handled as expected again. It ensures payments that need the NURG service level are marked correctly by default, helping avoid processing issues with international payments.
Original PR description
Since commit [[1]], the Service Level is set to NURG only when using the specific `iso20022_se` payment method. However, the previous expected behavior was to set the Service Level to NURG automatically whenever a payment was in a non-EUR currency or targeted a non-EU IBAN, regardless of the specific ISO20022 variant. This commit restores the logic to set the Service Level to NURG for all standard ISO20022 payments. This fix doesn't check anymore if a payment is in non-EUR currency or target a non-EU IBAN. Using iso_20022 activate it by default. opw-5095483 [1]: https://github.com/odoo/enterprise/commit/67593e5ff9b3a5187a1535bc8fc89590b4c9401e Forward-Port-Of: odoo/enterprise#100061
This update stops users from accidentally changing locked information when they drag and drop items in Gantt views. It is especially important in planning screens, where moving a task could previously alter a read-only field such as the product on a work order.
Original PR description
Issue ----- Gantt view's drag & drop allows the user to change the value of readonly fields if they are stored. E.G. in the Planning view of MRP, grouped by Work Center > Product, dragging & dropping…
Issue ----- Gantt view's drag & drop allows the user to change the value of readonly fields if they are stored. E.G. in the Planning view of MRP, grouped by Work Center > Product, dragging & dropping can change the product of the WO if the user is not careful and drops the WO on top of another product's WO. Steps to reproduce ----- - Have 2 products - Create a MO for product 1 with a WO at work center 1, plan it - Create a MO for product 2 with a WO at work center 2, plan it - Got to Manufacturing, Planning, Planning by Work Center - Add a custom group (by product) - Drag the WO of WC2 and drop it on top of the other WO > Both the WC and the product of the second WO change Cause ----- The example problem is only for versions 17.0 & 18.0 where the `product_id` field of `mrp.workorder` is both readonly and stored. https://github.com/odoo/odoo/blob/31e46a841b38de0f99beb1844f985bc670621486/addons/mrp/models/mrp_workorder.py#L34 While the user cannot change the field value manually, automatic actions such as a gantt view drag & drop can change its' value by passing it to `write` since the field is stored. This does not pose any problem for related fields that are not stored. More broadly, gantt views should not ignore the `readonly` attribute of fields. Solution ----- Add a new `o_gantt_readonly` class to all cells of rows grouped by a readonly field - and their "child" rows. For example, if the grouping is done by "Work Center > Product > Quality Check" and "Product" is readonly, rows grouped by either "Product" or "Quality Check" will be marked as readonly. When the user drags a pill, dynamically remove the class from cells of the same "child group". The class will then be added back upon pill drop. ----- Ticket: opw-4875366 Forward-Port-Of: odoo/enterprise#100088 Forward-Port-Of: odoo/enterprise#94166
This update makes the testing tool less disruptive when no tests are found by logging a message instead of raising an error. It also improves test run reporting in headless mode by logging root suite results at the end of each run, making automated test output easier to review.
Original PR description
[FIX] web: Hoot - remove error if no tests This commit replaces the error thrown if there is no test found by a log. --- [IMP] web: Hoot - log root suites at end of run This commit makes the unit test runner log all root suites results after each test run, only in headless mode. Forward-Port-Of: odoo/odoo#236647
This update fixes several issues in Uruguay’s vendor bill synchronization, including correctly handling multiple documents in one XML file and improving how imported bills are identified. It also keeps a copy of the uploaded XML with the bill and makes automatic processing more stable by running in smaller batches.
Original PR description
1) Update l10n_uy_edi translations. 2) When an uruguayan xml file is uploaded on a purchase journal it could contain the information of more than one CFE but before this commit only the first CFE was…
1) Update l10n_uy_edi translations. 2) When an uruguayan xml file is uploaded on a purchase journal it could contain the information of more than one CFE but before this commit only the first CFE was processed. Now all the CFEs are processed. 3) Add suffix '-manual' for new vendor edi documents uuid that are created by drag and drop xml file. 4) Create xml attachment in the edi document if it is created by drag and drop xml file. 5) Add suffix '-notification' for new vendor edi documents uuid that are created by 'UY: Create vendor bills (sync from Uruware)'. 6) Cron is run by batches (size=10). 7) Add tests. The suffixes -manual and -notification are used to differentiate between EDI documents generated manually and those generated automatically. This is useful to determine whether the document was created by a user or by an automated process, also helps users identify its origin more easily and also it is useful for debugging and tracking purposes. Task Adhoc side: 43467 Task latam side: 1355 Forward-Port-Of: odoo/enterprise#99308 Forward-Port-Of: odoo/enterprise#86829
Exchange rates imported from the Swiss Federal Tax Administration now use the correct publication date. This prevents rates from appearing to belong to the wrong day, improving the accuracy and reliability of currency conversions.
Original PR description
Steps to reproduce: - Select exchange service: [CH] Federal Tax Administration (FTA). - Add USD (or other currencies). - Fetch the new rates (click on the reload icon). Issue: Rates are returned for yesterday but stored with today’s date. Cause: The request fetches yesterday’s rates and we store the date using `gueltigkeit` (valid-until). FTA rates are typically valid until the next morning (around 7 AM) or until the next business day on weekends. Example (fetch on Fri 14.11.2025): <gueltigkeit>15.11.2025,16.11.2025,17.11.2025</gueltigkeit> For example, if we fetch on the 14th (Friday), we get this value: <gueltigkeit>15.11.2025,16.11.2025,17.11.2025</gueltigkeit> Solution: Query the FTA endpoint using today’s date and store the rate date from `datum` (publication date) instead of `gueltigkeit`. opw-5189127 Forward-Port-Of: odoo/enterprise#100046
This change updates the recorded state code for Odisha in India from "OR" to "OD". It helps ensure customer addresses and related documents, such as sales orders, use the correct official code.
Original PR description
**Steps to reproduce:** 1. Install the `Contacts` module. 2. Go to Contacts > Create a new contact. 3. Select country India, and state Odisha. 4. Create a sales order using the newly created contact. **Issue:** As per [Government of India](https://www.iso.org/obp/ui/#iso:code:3166:IN), the state code was officially changed from "OR" to "OD" in 2023. However, Odoo still uses the outdated code. <img width="407" height="163" alt="image" src="https://github.com/user-attachments/assets/1631a831-f455-4a51-886f-7e4ed691add0" /> **Solution:** Update the name of the state from "OR" to "OD" in state records. **opw-4935633** Forward-Port-Of: odoo/odoo#234697
This update brings the spreadsheet component to a newer version with several fixes to improve day-to-day use. It addresses issues like button sizing, accidental interaction in read-only spreadsheets, editing mode behavior, and side panel refresh behavior.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/57b11b85d [REL] 18.3.27 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/57b11b85d [REL] 18.3.27 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/6487f6d0e [FIX] spreadsheet: fix button height [Task: 5253888](https://www.odoo.com/odoo/2328/tasks/5253888) https://github.com/odoo/o-spreadsheet/commit/8ec4b1cd1 [FIX] headers_overlay: disable interaction in read-only mode [Task: 5182854](https://www.odoo.com/odoo/2328/tasks/5182854) https://github.com/odoo/o-spreadsheet/commit/e076525ba [FIX] composer: change mode to editing when composer cursor selection changes [Task: 5226615](https://www.odoo.com/odoo/2328/tasks/5226615) https://github.com/odoo/o-spreadsheet/commit/e8d8bcd9b [FIX] SidePanel: reset initial props on Model change [Task: 5059484](https://www.odoo.com/odoo/2328/tasks/5059484) Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> Co-authored-by: Anthony Hendrickx (anhe) <anhe@odoo.com> Co-authored-by: Alexis Lacroix (laa) <laa@odoo.com> Co-authored-by: Lucas Lefèvre (lul) <lul@odoo.com> Co-authored-by: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya (rmbh) <rmbh@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@odoo.com> Co-authored-by: Rémi Rahir (rar) <rar@odoo.com> Co-authored-by: Pierre Rousseau (pro) <pro@odoo.com> Co-authored-by: Vincent Schippefilt (vsc) <vsc@odoo.com> Co-authored-by: Marceline Thomas (matho) <matho@odoo.com>
The mobile Documents board now displays folders and documents more cleanly, removing awkward empty space when both appear together. It also improves the Recent folder so items use the available width properly and can be scrolled to view all documents. This makes browsing documents on phones smoother and easier to use.
Original PR description
This commit fix several issue in kanban mobile view: - When a folder has folders AND documents, there is a huge gap between the two because of the kanban ghost records. - In the 'Recent' folder, folders and documents doesn't take all width. - In the 'Recent' folder, we can't scroll to see all the documents. Task-4963198 Forward-Port-Of: odoo/enterprise#99810 Forward-Port-Of: odoo/enterprise#90647
This change fixes an issue where certain POS items, including gift cards and e-wallet products, could fail to appear on the product screen. By aligning the product category setup, the POS now loads the expected items correctly and avoids test failures in the runbot environment.
Original PR description
Before this commit: ======================= The `whiteboard_pen` product had no assigned category, while the main POS configuration was limited to specific categories. As a result, `whiteboard_pen` was not displayed on the product screen. When no products were loaded, special products like gift cards and e-wallets also not shown,showing the `Load Sample` button instead of products. This caused tour tests expecting gift cards on the screen to fail. After this commit: ====================== Assigned the same product category to whiteboard_pen as used in the POS configuration. This ensures that the product appears on the product screen and special products like gift cards also load properly, preventing the tour test from failing. Runbot Error: 233434, 233435
This change ensures the Italian "Libro Giornale" report only applies its custom layout to the correct country. As a result, the standard journal report keeps showing journal names properly for other companies and reports are no longer affected by the Italian customization.
Original PR description
The custom template for the report "Libro Giornale" was neither inheriting with primary neither using conditions on the country code. Therefore, the xpaths applied were for all the journal reports, whatever the company. For example, when exporting the regular journal report, the names of the journals no longer appeared once the module l10n_it_reports was installed on a database. opw-5217520 Forward-Port-Of: odoo/enterprise#100045
This fix prevents an error that could appear when a duplicated delivery is changed to a different product and then returned. It ensures stock cost calculations only use records for the same product, so users can validate deliveries and returns without unexpected failures.
Original PR description
When duplicating a delivery linked to a sale order and changing the product on the duplicated picking, validating the return could lead to an error when validating the original picking of the initial…
When duplicating a delivery linked to a sale order and changing the product on the duplicated picking, validating the return could lead to an error when validating the original picking of the initial product. The issue occurred because the average price computation was mixing stock moves of different products when consuming valuation layers, leading to a UoM singleton error. Steps to reproduce: - Create storable products P1 and P2: - Category: AVCO - P1 UoM: Unit - P2 UoM: Dozen - Create a sale order with 1 unit of P1 - Confirm the SO - Open the generated picking - Duplicate it → a new picking is created and still linked to the same SO - Change the product on the duplicated picking to P2 - Confirm and validate it - Create a return on this picking and validate it - Go back to the original picking of P1 and try to validate it Problem: A UserError is raised due to mixed products in the average price computation, resulting in a “Expected singleton: uom.uom(...)” This fix ensures that average price is computed only using stock moves belonging to the same product. opw-5027089 Forward-Port-Of: odoo/odoo#236706
This fix updates several Philippine custom tax tags so they are properly treated as negative amounts in tax reporting. It prevents tax reports from showing incorrect totals for affected transactions.
Original PR description
This commit sets tax_negate to true to (-QAPA, -QAPB, -SAWTA, -SAWTB). They were missing and impacted a tax report falsely. opw-5157090 Forward-Port-Of: odoo/odoo#236725
This change fixes an issue that could cause the system to run out of memory when registering payments for many invoices at once. It makes the payment validation step more efficient so large batches can be processed more reliably.
Original PR description
### Description: When trying to register a payment for multiple invoices, it is possible to trigger an Out Of Memory error. This is caused by the constraint `_validate_taxes_country`, calling the compute `_compute_tax_country_id` on all of the moves. To avoid that, we just retrieve the field we need rather than fetching everything. ### Reference: opw-5152687 Forward-Port-Of: odoo/odoo#235749
This change prevents Point of Sale from getting stuck in a repeated update when both the default preset and the available presets are empty. It makes the system handle this empty-state case safely, avoiding a freeze during configuration updates.
Original PR description
The condition `config.default_preset_id.id not in config.available_preset_ids.ids` is equivalent to True when both default_preset_id and available_preset_ids are empty. This triggers an infinite loop as assigning with `|=` triggers a nested write. 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#231378
This update corrects how periodic values are chosen in reports that contain sections, such as the Luxembourg tax return. It ensures the report uses the right source period so submitted amounts reflect the intended period instead of the current month.
Original PR description
We have some reports with sections, like l10n_lu generic tax return.
Since account.return are born, when submitting the lu tax return, the periodicity is wrongly
computed, because of the self in `_init_options_return_periodicity` is the section report, not the main,
but the account.return.type is set with report_id = main report
Step to reproduce:
With a LU company:
1. Create a journal entry for a previous period
2. Submit the tax return for the same period
3. The amount shown is the amount of the current month
Solution: use options['sections_source_id'] to fetch the return_type instead of self.return_type_ids
opw-5163352This change corrects how the warning filter works on records with activities. It now shows the expected items with warnings, instead of hiding some valid records or displaying records that should not match the filter.
Original PR description
Steps To Reproduce ------------------ 1- To purchase orders 2- Create random purchase orders (with activity and without and with warning) 3- Select the Warning Filter Issue ----- 1- Only POs with no…
Steps To Reproduce
------------------
1- To purchase orders
2- Create random purchase orders (with activity and without and with warning)
3- Select the Warning Filter
Issue
-----
1- Only POs with no activities show on the list.
2- The behavior in versions previous to 18.3 works perfectly fine, showing only POs with warnings.
Cause
-----
The issue is caused by this commit: 92301a5b300dec1ddfca44dc35318b83d67c56fa.
The search logic for the activity_exception_decoration field was changed to refuse negative operators (`!=`):
https://github.com/odoo/odoo/blob/92301a5b300dec1ddfca44dc35318b83d67c56fa/addons/mail/models/mail_activity_mixin.py#L118-L121
This forces the ORM to invert the filter:
https://github.com/odoo/odoo/blob/9a8350cb476af73d6bf4eea75344963eac1c7831/odoo/orm/domains.py#L873-L880
For this case, this transforms the intended query:
`Exists(activity_exception_decoration != False)` ("Has Warning")
Into the inverted query:
`NOT Exists(activity_exception_decoration == False)` ("Does NOT have a Normal activity")
This incorrectly hides records that have both warning and normal activities, and incorrectly shows records with no activities at all.
opw-5177277
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prSearching for UNSPSC categories now works when users type only part of a numerical code. This makes it easier to find the right product category in the Accounting tab and avoids empty search results for existing codes.
Original PR description
**Steps to reproduce:** * Install the **Accounting** and **l10n_mx** modules. * Open any product form view. * Navigate to the **Accounting** tab. * In the *UNSPSC Category* field, start typing a numerical code such as **'10101500'**. **Observed behavior:** * No results are returned, even though the corresponding UNSPSC code exists in the database. **Cause:** * The `_search_display_name` method used an exact match (`=`) on the `code` field, preventing any partial or prefix-based lookup during user input. **Fix:** * Replace the exact-match domain on `code` with a partial match using `ilike`, allowing users to find UNSPSC codes by typing any part of the numerical sequence. opw-5244705
This change ensures that when a filter is enabled on a combined report, it is also enabled on the related sections that depend on it. As a result, the filter will appear properly in the user interface and behave consistently across all report parts.
Original PR description
When using a composite report whose sections aren't used independently, enabling that filter on the composite report needs to enable it on their sections as well, else it won't show in the UI. This is the standard behavior for all report filters. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#236893
This fix ensures that when a filter is enabled on a composite cash basis report, the same filter is also enabled on its sections. As a result, the filter shows up properly in the user interface and behaves consistently with other report filters.
Original PR description
When using a composite report whose sections aren't used independently, enabling that filter on the composite report needs to enable it on their sections as well, else it won't show in the UI. This is the standard behavior for all report filters. Forward-Port-Of: odoo/enterprise#100148
Fixed an issue where enabling the analytic grouping filter on a combined report did not always make it available in the report sections. This brings the behavior in line with other report filters and ensures users can see and use the option where expected.
Original PR description
When using a composite report whose sections aren't used independently, enabling that filter on the composite report needs to enable it on their sections as well, else it won't show in the UI. This is the standard behavior for all report filters. Forward-Port-Of: odoo/enterprise#100135
This update ensures that the status of a sale order is correctly updated to 'Sales Order' in the Sales module after a payment is processed through the Point of Sale (PoS) system. Previously, the system didn't update the order status, leading to inaccurate tracking. This fix resolves a discrepancy in order status updates, ensuring data consistency across both PoS and Sales modules.
Original PR description
**Steps to reproduce:** - Make a quotation in the Sales module - Go to PoS, click Quotation/Order and select your quotation - Select Settle the order - Go through with the payment - Go back to the…
**Steps to reproduce:** - Make a quotation in the Sales module - Go to PoS, click Quotation/Order and select your quotation - Select Settle the order - Go through with the payment - Go back to the Quotation in the Sales module The Status widget still shows Quotation instead of Sales Order **Why the fix:** Since 18.3, the sale_order.state was not updated anymore when the state changed through the PoS. This happened because we would only change the sale_order state if there was a downpayment involved. In 18.2, we always recomputed the sale_order that was linked to the order we are currently settling. The way it is done now is part of the same way it was done in 18.2 and before, meaning we add the linked sale_order regardless of downpayments. In 18.2, we did an action_confirm on the selected sale_orders, but doing that in 18.3 will create another picking for this sale_order. This is not what we want as the picking is now handled and created by the PoS. This fix will just put the related sale orders in the "sale" state, so that users can no longer confirm it in the sales modules, which would create a second picking and create duplicates. opw-5033979
This update resolves an issue where the HTML editor was creating unnecessary empty elements after font size adjustments. The fix ensures that leftover empty text nodes are properly removed, improving the editor's stability and preventing potential display problems. This enhances the overall user experience.
Original PR description
Steps to Reproduce: - Create a link in the editor (e.g., "abc"). - Select all and change the font size from 14 to 80. - Two empty tags are created before and after the formatted <span><a></a></span> with only FEFF Characters. - Change the font size again (e.g., back to 14). - Multiple empty tags remain in the DOM. Description of the issue this PR addresses: - In the removeFeffs method, FEFF characters are replaced with empty text nodes, which can lead to unwanted empty elements and empty text nodes being left in the DOM. Desired behavior after PR is merged: - Empty text nodes resulting from FEFF replacement are now properly removed, preventing leftover empty elements in the DOM. task-5097770 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an issue where CFDI invoices generated in the Mexico localization were producing incorrect rounding values. The fix involves a refined process for calculating tax amounts and aggregating line items, ensuring accurate CFDI invoice generation and compliance.
Original PR description
- Refactor the CFDI generation using the EDI tax helpers to prevent rounding issues by spreading the amounts according a tolerance of 0.000001. - Aggregate lines before computing the global invoice CFDI. That way, we avoid creating new rounding issues by post-processing the created CFDI. task_id: 5096249