Monday, November 24, 2025
23 changes · saas-18.4
Enhancements to existing features
This update brings back the ability to mark specific invoice lines as "No Follow-Up," so they will not trigger payment reminders. It also improves follow-up reports and customer statements so excluded items are handled consistently in views, exports, and reminder emails, while overdue status is not changed when only excluded items remain.
Original PR description
During the rework of the follow-up report, we removed the "No Follow-Up" field from journal items, making it impossible to exclude individual journal items from triggering a follow-up. In this commit…
During the rework of the follow-up report, we removed the "No Follow-Up" field from journal items, making it impossible to exclude individual journal items from triggering a follow-up. In this commit we do the following: - Re-introduce a field for that, since it is a common requirement to be able to exclude individual items from the follow-up reports. The field is stored on the journal item, but can also be toggled from the journal entry. In case of multiple installments on the invoice, toggling the field on one installment will toggle it for all installments. - Adapt the Follow-Up Report and Customer Statement variants of the Partner Ledger to add a toggle for the "No Follow-Up" field on each report line, that toggles the field on the corresponding journal item(s). - Prevent the follow-up status on the partner to change when all of the overdue journal items are marked as "No Follow-Up". - Make sure users can toggle the "No Follow-Up" setting on the invoice level when opening the "Overdue Invoices" view from the partner's "Accounting" tab. - Make sure all receivable/payable lines without a due date (either from a manual miscellaneous entry or a PoS entry) are put under the "Due" section in the Follow-Up Report instead of the "Overdue" section. Since there is no due date, they can't be overdue. - Make sure the PDF and XLSX exports of the Follow-Up Report don't include the "No Follow-Up" lines, and the customer follow up email only includes the amount of the other lines. Backport of https://github.com/odoo/enterprise/commit/74b9d2ef17e4f9a217db8432d886de2eca4baef9 and https://github.com/odoo/odoo/commit/2789a0fbfa358c5c164e44380c2a4a10e5679615 Task: 5138378 Upgrade PR → https://github.com/odoo/upgrade/pull/8864 Forward-Port-Of: odoo/enterprise#99743 Forward-Port-Of: odoo/enterprise#96627
The customer subscription portal no longer relies on a fixed list of billing periods. It now reads the available billing options directly from the system, so custom periods like daily billing can be displayed without causing errors.
Original PR description
Problem -------- In v18.0, the day billing period was removed from the sale.subscription.plan model. For our use case, we require daily subscriptions, so we added this value back to the…
Problem -------- In v18.0, the day billing period was removed from the sale.subscription.plan model. For our use case, we require daily subscriptions, so we added this value back to the billing_period_unit selection field via inheritance. However, this customization causes an error (a KeyError) when accessing the customer portal at /my/subscriptions/<int:order_id>. This is because the controller logic relies on a hardcoded list of periods and does not account for the new custom "day" value. - Screenshot Order with plan Daily: <img width="1246" height="483" alt="image" src="https://github.com/user-attachments/assets/5dc5ca0d-a2f2-434d-8183-15a0424d9f34" /> - Screenshot when trying to get in order on the website: <img width="1250" height="776" alt="image" src="https://github.com/user-attachments/assets/5b10504e-71e2-4c13-8611-39e8a41e05d1" /> Proposed Solution -------- This PR improves the subscription portal by dynamically retrieving billing periods instead of using a hardcoded list. The portal now reads the available options directly from the billing_period_unit field's selection (i.e., self.env['sale.subscription.plan']._fields['billing_period_unit'].selection). This improves maintainability, as future changes to the field's selection will be automatically reflected without requiring code modifications. This makes the portal robust and automatically compatible with any custom periods added via inheritance. - <img width="1331" height="752" alt="image" src="https://github.com/user-attachments/assets/4f7be6c3-d96b-4525-8e23-6e1323adabde" /> Forward-Port-Of: odoo/enterprise#100084 Forward-Port-Of: odoo/enterprise#99207
This update lets Point of Sale and self-ordering connect to local devices like Epson printers and the black box over regular HTTP in modern Chrome browsers. As a result, businesses no longer need to install certificates just to keep these local connections working.
Original PR description
*: pos_self_order, pos_epson_printer Feature: https://chromestatus.com/feature/5152728072060928 Since Chrome 142, a new feature called “Local Network Access” has been added, allowing local IPs to be contacted via HTTP without mixed content errors. This means that certificates are no longer required to contact Epson printers or the black box. Forward-Port-Of: odoo/odoo#236916 Forward-Port-Of: odoo/odoo#235702
This update improves how GSTR-2B processing handles certain errors and avoids retrying records that are already in an invalid state. As a result, background jobs run more reliably and waste less time on records that cannot be processed successfully.
Original PR description
Before this commit: - `RET2B1017` error code was not handled. - Cron methods `_cron_get_gstr2b_data` and `_cron_gstr2b_match_data` processed all records with status: - `"waiting_reception"` - `"being_processed"` - Records with blocking level `"error"` were still being processed by cron. After this commit: - Added handling for `RET2B1017` and mapped it to `"warning"` level. - Updated cron domain filters to exclude records where `gstr2b_blocking_level = "error"`. - Cron jobs now skip invalid/error-state return periods, preventing unnecessary processing. Forward-Port-Of: odoo/enterprise#100150 Forward-Port-Of: odoo/enterprise#99378
Resolved issues and error corrections
This fix ensures subscription deliveries are properly counted even when a product is returned. As a result, the delivered quantity on the sales order stays accurate, which improves billing and subscription tracking.
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 stops Gantt rows grouped by read-only fields from being moved in a way that would change those protected values. It reduces the risk of users accidentally modifying important data while dragging items in planning views.
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 fixes how Swiss Federal Tax Administration exchange rates are dated when imported. Rates will now be stored with the correct publication date, which prevents them from appearing a day off and keeps exchange rate records more accurate for users.
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 fix restores the expected payment instruction used for standard ISO 20022 payments. As a result, non-SEPA transfers will again be processed with the correct service level by default, reducing the risk of rejected or mishandled 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 prevents an error that could appear when opening a partner record after uninstalling certain e-invoicing modules. It now safely clears the related e-invoice format so users can continue working without encountering a traceback.
Original PR description
Before this fix, if you uninstalled this module and navigated to any partner that had a e-invoice format defined by this module, you'd have a traceback. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr @moduon MT-12168 OPW-5172861 Forward-Port-Of: odoo/odoo#235301 Forward-Port-Of: odoo/odoo#232297
This fixes an error that could appear when opening the Accounts Coverage Report for Spain balance sheet reports. The report data is now loaded correctly, preventing the traceback and allowing users to view the report without interruption.
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#99865
Forward-Port-Of: odoo/enterprise#98745This update brings the spreadsheet component to a newer version and includes several fixes that improve everyday use. It addresses issues like scrolling on iOS, editing behavior, button sizing, and better handling of read-only views and sheet names with spaces.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/4f8366721 [REL] 18.4.18 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/4f8366721 [REL] 18.4.18 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/83c393f62 [FIX] Spreadsheet: fix scroll on ios [Task: 5270869](https://www.odoo.com/odoo/2328/tasks/5270869) https://github.com/odoo/o-spreadsheet/commit/948c51e86 [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/3ce3152f7 [FIX] spreadsheet: fix button height [Task: 5253888](https://www.odoo.com/odoo/2328/tasks/5253888) https://github.com/odoo/o-spreadsheet/commit/16b2e4115 [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/e4b3ebef8 [FIX] SidePanel: reset initial props on Model change [Task: 5059484](https://www.odoo.com/odoo/2328/tasks/5059484) https://github.com/odoo/o-spreadsheet/commit/62dfe8a88 [FIX] composer: Enter/Tab confirm when assistant is force-closed [Task: 5153666](https://www.odoo.com/odoo/2328/tasks/5153666) https://github.com/odoo/o-spreadsheet/commit/2a23dddf4 [FIX] reference_type: add single quotes for sheet names with spaces [Task: 5244798](https://www.odoo.com/odoo/2328/tasks/5244798) Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> Co-authored-by: Anthony Hendrickx (anhe) <anhe@odoo.com> Co-authored-by: Alexis Lacroix (laa) <laa@odoo.com> Co-authored-by: Lucas Lefèvre (lul) <lul@odoo.com> Co-authored-by: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya (rmbh) <rmbh@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@odoo.com> Co-authored-by: Rémi Rahir (rar) <rar@odoo.com> Co-authored-by: Pierre Rousseau (pro) <pro@odoo.com> Co-authored-by: Vincent Schippefilt (vsc) <vsc@odoo.com> Co-authored-by: Marceline Thomas (matho) <matho@odoo.com>
This update prevents the Italian "Libro Giornale" template from affecting all journal reports. As a result, regular journal exports keep their journal names and other companies’ reports are no longer altered by this local 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 update fixes an error that could appear when users changed the website header to the Search Bar template and then selected Center or Right alignment. It removes incorrect view references so the alignment options work normally again in the Website Editor.
Original PR description
Problem: When setting Center or Right alignment while using the Search Bar Header Template, an error message will occur due to an invalid xpath in the respective views. Purpose: Remove the invalid xpaths. Steps to Reproduce on Runbot: 1. Enter the Website Editor. 2. Select the Header and change the Template to Search Bar. 3. Attempt to change the Alignment to Center or Right. opw-5150348
This fix prevents date placeholders from appearing to the wrong signer in multi-signer documents. It helps each person see only the fields that are meant for them, reducing confusion during the signing process.
Original PR description
Version: - saas-18.3 Steps to reproduce: - Add date fields for multiple signers. - When the first signer signs, the date placeholder for the next signer becomes visible to the first signer. Issue: - Date fields for next signers were showing placeholders to the current signer. Fix: - Added a condition to only set the placeholder when it has a valid value. Impact: - Ensures date placeholders are visible only to the correct signer. task-5218970 Forward-Port-Of: odoo/enterprise#98256
This change prevents validation errors when a duplicated delivery is edited to use a different product. It ensures pricing is calculated only from stock movements of the same product, so returns and subsequent validations work correctly.
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 change fixes an issue where registering payments for many invoices at once could run out of memory. It reduces the amount of data loaded during tax checks, making batch payment processing more reliable and less likely to fail.
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 update fixes missing settings on several Philippine custom tax tags so they are treated correctly in tax calculations. As a result, tax reports should now reflect the right amounts instead of showing false values.
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 fix prevents partner names from being recalculated unnecessarily when editing or deleting lines in a bank statement reconciliation. It helps keep previously corrected entries stable and avoids unexpected changes on related lines.
Original PR description
Before this commit, when having multiple lines in a statement line. By default, all the lines have a partner since we compute the partner depending of other lines. But in the case of an edit or a delete we don't want to recompute. What was happening is that the partner keep getting recomputed on the other lines even the one that was previously edited. This commit will add a context key when using the reconcile button to recompute the partners. opw-5179670 Forward-Port-Of: odoo/enterprise#99999
The Profit and Loss report has been corrected to include a newly introduced expense category called Other Expenses. This ensures financial reports show all relevant expenses for companies using that account type, preventing missing amounts in the report.
Original PR description
In saas-18.3 a new account type was added: "Other Expenses" These accounts are excluded from the account many2one field to make it easier to find relevant expense accounts for vendor bills. Issue: This account type is not included in the Profit & Loss Report. Since l10n_be is the only CoA which uses this account type, the issue was not uncovered until OXP testing days. Forward-Port-Of: odoo/enterprise#94219
This update fixes an issue where the French balance sheet could become unbalanced when using the 2024 chart of accounts. It ensures missing income and expense amounts are correctly included so retained earnings are calculated properly and reports stay consistent.
Original PR description
[FIX] l10n_fr_reports: unbalanced Balance Sheet when coming from the 2024 CoA https://github.com/odoo/odoo/commit/8f3a86925e0301c15ca93b64d6237b69a534d71a introduced a new version of the French CoA,…
[FIX] l10n_fr_reports: unbalanced Balance Sheet when coming from the 2024 CoA https://github.com/odoo/odoo/commit/8f3a86925e0301c15ca93b64d6237b69a534d71a introduced a new version of the French CoA, legally mandatory starting in 2025. Doing so, it also adapted the P&L and BS reports accordingly. However, it did not take into account the fact that some deprecated account codes would disappear from the P&L, causing the BS to be unbalanced when computing the retained earnings (by calling the P&L with a forced date_scope to run it on the full history). We fix that by reinjecting the balance of the missing Income and Expense accounts in the computation of the BS's Retained Earnings line. opw-5212801 =============================================================== [FIX] l10n_fr_reports : add new accounts in P&L Backport from https://github.com/odoo/enterprise/commit/eb35916f4f5a45e0c11919e0ee1a16e0caee010f , which was done in master for 18.2, but should have targetted older versions as well. Forward-Port-Of: odoo/enterprise#100116 Forward-Port-Of: odoo/enterprise#100077
This update improves how file blobs and object URLs are handled in automated tests, making them behave more like the real application. It also fixes mock route handling for full URLs and updates attachment upload behavior to use the correct response format, which helps keep tests reliable and reduces false failures.
Original PR description
See commit messages for details --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#236121 Forward-Port-Of: odoo/odoo#234558
This update fixes a website builder issue where canceling certain dialogs could leave the save button stuck in a loading state. It also cleans up a test listener so unrelated tests are not affected, making automated testing more reliable.
Original PR description
### [FIX] mail: clean the "beforeunload" listener in tests Some tests trigger a call to the function `Rtc.joinCall` which adds a listener on `beforeunload` event that cancels the event. Some of these…
### [FIX] mail: clean the "beforeunload" listener in tests Some tests trigger a call to the function `Rtc.joinCall` which adds a listener on `beforeunload` event that cancels the event. Some of these tests do not trigger a later call to `Rpc.clear`, thus the listener stays registered. This could mess with other unrelated tests that check their own handlers of `beforeunload` are correct. This commit adds a cleanup on the helper used by the problematic tests. task-5138313 ### [FIX] website, html_builder: run after-save handlers if aborted Usually, running the after save handlers is not needed after the save because we are about to close or reload the builder. Thus they are not run as an optimization. But there are a few cases where they are needed: - The saving of the page failed. This case was correctly handled only when clicking on the save button or adding a module - When adding a language, but cancelling the dialog to choose the language This commit changes the save function of the save plugin, to take a async callback to determine whether the after-save handlers should run. The callback is async to be able to wait for the language choice dialog. If the callback returns `true`, then the after-save handlers are run. Steps to reproduce: - Open website builder - Open "Theme" tab - Click "Add Language" - Confirm the first dialog (about save) - Cancel the second dialog (language choice) - Bug: the save button stays disabled with the spinning wheel next to it task-5138313
This update significantly speeds up the process of finding deliveries associated with stock lots. By optimizing a key calculation, the system now responds much faster, especially when dealing with a large number of lots. This improves overall system responsiveness and efficiency.
Original PR description
### Description: This refactoring replaces the recursive calculation in `_find_delivery_ids_by_lot` with an iterative process. This change significantly reduces the amount of database queries by prefetching and batching all required lines in a single pass, and it also eliminates the overhead caused by repeated recursive function calls. ### Benchmark: | Total Lots | Before | After | |------------|--------|--------| | 69 | 1 sec | 106 ms | | 1152 | 1 min | 5 sec | ### Reference: opw-5096599 Forward-Port-Of: odoo/odoo#236773 Forward-Port-Of: odoo/odoo#233478