Daily updates from Odoo
Friday, July 11, 2025
19 changes · 18.0
Enhancements to existing features
Saudi Arabia invoicing now prevents valid posted invoice PDFs from being deleted after they have been generated and sent to ZATCA, supporting auditability and compliance requirements. If a PDF was created while an invoice was rejected and the invoice is later accepted, the system can distinguish that older attachment and allow appropriate cleanup without resetting finalized records unnecessarily.
Original PR description
Task ID: 4730762 Description of the issue/feature this PR addresses: - As per ZATCA's auditability principles (clause 3 sub-heading C, paragraph 2): The Compliant E-Invoice solution must be able to…
Task ID: 4730762 Description of the issue/feature this PR addresses: - As per ZATCA's auditability principles (clause 3 sub-heading C, paragraph 2): The Compliant E-Invoice solution must be able to protect the generated Electronic Invoices and Electronic Notes from alteration or deletion. - This PR aims to restrict the deletion of valid invoice PDFs once the invoice has been generated & sent to ZATCA. Current Behavior before PR: - Invoice PDF attachments were allowed to be deleted in l10n_sa, even when the invoice is posted. - For l10n_sa_edi, if and invoice PDF is generated during a rejected state, it is kept there unless you reset to draft. Desired behavior after PR is merged: - in l10n_sa, deleting an attached invoice PDF raises a user error (reset to draft is required to detach the invoice first) - For l10n_sa_edi, if the invoice PDF is generated during a rejected state, but the invoice is resubmtited to ZATCA and accepted. The creation & write dates of the attachment linked & edi_documents respectively are compared and the deletion of the pdf attachment is allowed to be deleted in the case where the creation date was less than the write date. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Peppol invoice retrieval jobs now handle large invoice volumes by processing documents in smaller batches and automatically continuing when more work remains. This reduces the risk of scheduled jobs timing out, helping businesses with high transaction volumes keep electronic document processing running smoothly.
Original PR description
For database with big invoice volume, it is necessary to be able to retrieve documents in smaller batches otherwise crons will timeout due to the 15 minutes limit. Add a retrigger mechanic to the possibly heavy crons. opw-4925532 Forward-Port-Of: odoo/odoo#218383
Improves Profit and Loss report loading by avoiding unnecessary duplicate analytic accounting rows when no analytic plan is present. This reduces report processing time significantly, with benchmarks showing roughly twice as fast loading for grouped analytic account reports.
Original PR description
Description ----------- For the P&L report, a view of the `account_analytic_line` is created to mascarade as `account_move_line` for the reporting engine. The `analytic_distribution` is takens from…
Description ----------- For the P&L report, a view of the `account_analytic_line` is created to mascarade as `account_move_line` for the reporting engine. The `analytic_distribution` is takens from the plans of the analytic lines. This is done by collecting all potential plans a line can be associated with and *unnesting* them into the main table. Unnesting creates a duplicate of the row for each possible value of the analytic plans. This can quickly balloon the row count of the view, depending on how many plans are present. This also creates a duplicate row when the line isn't associated with a specific plan, adding the value `NULL` for the `analytic_distribution`. This commits filters out the `NULL` values of the array of plans before unnesting into the main table. Since on average an analytic line is associated with a few plans, this prevents the significant growth of the view, leading to more reasonable performance. Benchmark --------- On a database with ~700k AAL and ~600k AML for 2025, opening the P&L report with a grouping by analytic accounts, took: | Accounts count | Before | After | |----------------|----------|----------| | 1 | 10.3 sec | 4.76 sec | | 5 | 51 sec | 20.8 sec | | 10 | 96 sec | 41.7 sec | | 15 | 2:26 min | 1:04 min | | 20 | 3:15 min | 1:25 min | So roughly a ~2x improvement on average. Reference --------- opw-4845164
The manufacturing planning screen now reloads only the schedules currently visible to the user instead of processing all affected schedules in the background. This makes updates much faster for large, complex production plans, reducing a benchmarked reload from 31.6 seconds to 3.5 seconds.
Original PR description
Description ----------- Only fetch forecasts for MPS schedules visible in the view rather than all impacted schedules. Schedules not visible due to pagination are skipped when reloading the MPS state. Benchmark --------- Adjusting a quantity for a product, which will impact around 1k+ other schedules (hierarchy is deep with boms), `get_production_schedule_view_state` takes: | Before | After | Speed-up | |--------|-------|----------| | 31.6s | 3.5s | 9x | Reference --------- opw-4778588
Resolved issues and error corrections
Marketing cards now display date and time fields using the timezone most relevant to the record, such as an event's local timezone, instead of defaulting to UTC. This makes shared event and marketing information clearer and less likely to confuse recipients in different regions.
Original PR description
When possible we want to fetch a date field in its relevant timezone not in UTC. As that is generally what you want people to share. task-4936298
This fixes an accounting issue that allowed users to create invoices containing a line without an item identifier. After the change, empty invoice items are blocked, helping keep invoice data complete and reducing billing errors.
Original PR description
Description of the issue/feature this PR addresses: Creating an invoice with an empty item is possible. Current behavior before PR: Creating an invoice with an empty item is possible. Desired behavior after PR is merged: A line with empty item identifier should not be possible. opw-217383 I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr 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
This update brings the spreadsheet component up to its latest version, fixing several issues around pivot tables, date handling, row sizing for links, and demo actions. It also improves performance when importing Excel files and when working with pivot table caches, making spreadsheet workflows more reliable and responsive.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/bc6f00d82 [REL] 18.0.37 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/bc6f00d82 [REL] 18.0.37 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/816a13960 [PERF] pivot: don't invalidate cache needlessly [Task: 4933971](https://www.odoo.com/odoo/2328/tasks/4933971) https://github.com/odoo/o-spreadsheet/commit/05feba730 [FIX] pivot: don't aggregate calculated missing value [Task: 4933818](https://www.odoo.com/odoo/2328/tasks/4933818) https://github.com/odoo/o-spreadsheet/commit/c8b32d783 [FIX] Cells: newline is not a valid date separator [Task: 4910327](https://www.odoo.com/odoo/2328/tasks/4910327) https://github.com/odoo/o-spreadsheet/commit/edc7cab1e [PERF] import xlsx: avoid reading all cells multiple times during table_conversion [Task: 4699860](https://www.odoo.com/odoo/2328/tasks/4699860) https://github.com/odoo/o-spreadsheet/commit/c4eeba37e [FIX] Config: remove eslint [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/f77fe7015 [IMP] config: ignore .DS_Store file from mac os [](https://www.odoo.com/odoo/2328/tasks/) https://github.com/odoo/o-spreadsheet/commit/39f760127 [FIX] header_size: resize row based on link label instead of full link [Task: 4886598](https://www.odoo.com/odoo/2328/tasks/4886598) https://github.com/odoo/o-spreadsheet/commit/d4eca5564 [FIX] pivot: allow to group by error [Task: 4886041](https://www.odoo.com/odoo/2328/tasks/4886041) https://github.com/odoo/o-spreadsheet/commit/c799ddb6d [FIX] demo: fix `clear` action again [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/54ec6d405 [FIX] demo: Fix new `clear` action [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) 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: Dhrutik Patel (dhrp) <dhrp@odoo.com> Co-authored-by: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Mehdi Rachico (mera) <mera@odoo.com> Co-authored-by: Florian Damhaut (flda) <flda@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>
This fix restores an optimized database lookup for attachment relationships used by the HTML editor. It helps large Odoo databases delete attachments much faster, reducing delays for users and administrators managing high volumes of files.
Original PR description
On a DB with 15M+ attachments, deleting a single attachment takes several seconds. Most of the time is spent on the circular `original_id` foreign key.
We add back the index which was removed in [1]
```
Delete on ir_attachment (cost=0.43..8.45 rows=0 width=0) (actual time=0.274..0.274 rows=0 loops=1)
-> Index Scan using ir_attachment_pkey on ir_attachment (cost=0.43..8.45 rows=1 width=6) (actual time=0.252..0.253 rows=1 loops=1)
Index Cond: (id = 82807)
Planning Time: 0.049 ms
Trigger for constraint ir_attachment_original_id_fkey: time=2330.796 calls=1
```
[1] https://github.com/odoo/odoo/commit/eedf37d6e286b995c47b946be1a6b66817094eff
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-prIndustry apps now show a clearer “Reset” action instead of a misleading “Upgrade” label. Users are also warned when a major version change could affect existing records, helping them avoid unexpected data issues.
Original PR description
### Before this commit: Activated industry apps had an "Upgrade" button with was slightly misleading, since the button was actually reseting the module regardless if there is a new version or not. ### After this commit: The "Upgrade" button has been named "Reset" for better clarity. Additionally in case of a major change in module version a warning will be raised to signal to users potential record breakage in case of upgrade. - Lines flagged by ci/security should be safe because it only reads zip imported file paths and extracts module names if they exist. task-4752273
Customers will no longer see delivery as free when the final shipping cost is only known after delivery. The checkout now shows a clear notice that the delivery charge will be calculated later, reducing confusion and incorrect expectations.
Original PR description
Issue: If the delivery invoice policy was set to "real" (meaning that we'll invoice the real delivery cost, after delivery), the delivery was shown as being free on eCommerce (since we don't know the cost yet). Fix: Show a disclaimer indicating that the cost will be computed after delivery. opw-4779059
This fix corrects how outgoing product quantities are calculated in Manufacturing. It helps ensure users see more accurate stock availability and demand information when planning or managing production.
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
The Colombian electronic invoicing integration now formats invoice type codes with the two characters required by DIAN. This helps prevent invoice submissions from being rejected due to incorrectly formatted document types.
Original PR description
The DIAN endpoint only accepts Electronic Invoice types with a length of 2 characters. This fix adds zero-padding to the problematic edi types. task: 4882683
Rental combo products now correctly show available booking dates when stock limits are enabled. This prevents customers from seeing all rental dates as unavailable and helps preserve online rental sales.
Original PR description
Issue: - Create a rental product (with a rental pricing), - Make it storable and don't allow out-of-stock orders, - Now make it a combo product, - Add a rental combo choice (to be able to save it), - Go to the product's page on eCommerce, - Issue: all dates are unavailable. Cause: The date range picker only relies on `allow_out_of_stock_order` to know whether to compute rental availabilities (but not on `is_storable`). Fix: Also rely on `is_storable` to know whether to compute rental availabilities. opw-4846084
The Peru stock reporting module now uses the correct product category reference when generating Stock Move PLE valuation reports. This prevents an error that could block users from opening PLE 13.1 reports after creating inventory receipts.
Original PR description
Currently, an error occurs during the valuation of the Stock Move PLE reports. Steps to Reproduce: - Install the `l10n_pe_reports_stock` module. - Create a `new company` with the country set to…
Currently, an error occurs during the valuation of the Stock Move PLE reports. Steps to Reproduce: - Install the `l10n_pe_reports_stock` module. - Create a `new company` with the country set to `Peru`, and switch to this company. - Go to `Receipts` in `Inventory`, create a `new receipt`, and `validate` it. - Go to `Valuation` and click on `PLE Reports`. - Select the `start date` as the day after today, and click on `PLE 13.1`. `KeyError: 'category'` This error occurs during the valuation of the Stock Move PLE reports. In the query, we retrieve product_template.categ_id as category_id [1], but later category [2] is used to access category_id. Since the category key is not present in the line, this causes the error. [1] https://github.com/odoo/enterprise/blob/95d20fca13efa0977018b0dc260efd410891fce6/l10n_pe_reports_stock/wizard/stock_move_ple_report.py#L241 [2] https://github.com/odoo/enterprise/blob/95d20fca13efa0977018b0dc260efd410891fce6/l10n_pe_reports_stock/wizard/stock_move_ple_report.py#L303 This commit ensures that category_id is used in place of category for safe evaluation. sentry-6723761615 Forward-Port-Of: odoo/enterprise#89379
This fixes a rental checkout issue where manually entered rental dates were not properly confirmed unless the full input flow was simulated. Customers can now save rental date selections more reliably, reducing checkout friction for rental products.
Original PR description
## Version 18.0 saas-18.1 Non existing test from saas-18.2 ## Issue Commit a16a25b6023d2d48ad5c00853728c1498509b5a5 introduced a bug while not simulating the entire flow allowing to save a rental date input. runbot-229659 runbot-229660
This fixes an issue where failing part of a quality check during a receipt could incorrectly mark related product movements as picked. Warehouse teams now get more accurate receipt statuses after quality inspections, reducing confusion and preventing premature processing.
Original PR description
Steps to reproduce the bug:
- Create two storable products: "P1" and "P2"
- create a quality control point:
- operation: receipt
- products: “P1” and “P2”
- Failure location: any one
- Create a receipt for 1 unit of P1 and 2 units of P2
- Pass the quality check for P1
- For P2, pass 1 unit and fail the other
Problem:
A new move for P2 is created to the failure location, but as a result, both moves for P2 are marked as picked, whereas the move for P1 is not. Solution:
We shouldn’t mark any move as picked during the quality check.
Partial backport of: https://github.com/odoo/enterprise/pull/77985/commits/48bfc8a860fa4b5b5e9ea153932f34b47bdcec6c
opw-4902059Fixed an error that could block users from failing a quality check on manufacturing orders for multiple serial-number-tracked products. This lets production and quality teams continue processing affected orders without an unexpected system crash.
Original PR description
Steps to reproduce the bug: - Create a storable product: - Tracking: By Serial Number - BoM: - component: C1 - Create a Quality Point: - Measure by: Quantity - Operation: Manufacture - Failure…
Steps to reproduce the bug:
- Create a storable product:
- Tracking: By Serial Number
- BoM:
- component: C1
- Create a Quality Point:
- Measure by: Quantity
- Operation: Manufacture
- Failure Location: Any (e.g., WH/Input/Order Processing)
- Create a Manufacturing Order for 2 units of P1
- Confirm
- Assign serial numbers
- Try to fail the quality check
Problem:
A traceback is triggered:
```
raise ValueError("Expected singleton: %s" % record)
ValueError: Expected singleton: stock.move.line(234, 235)
```
When validating a manufacturing order for a serial-number-tracked
product in multiple units, the order must be processed unit by unit.
However, when failing the quality check, the code tries to access and
assign all finished move lines to the quality check, which causes an
error because multiple records are returned
(and a singleton is expected).
At this stage, since the serial numbers are not yet assigned,
the finished move lines are still indistinguishable. Therefore, we can
safely use the first record to proceed with the quality check.
opw-4874199
Forward-Port-Of: odoo/enterprise#89430This fixes a company consistency error that could block Inventory installation after generating Belgian 281.50 tax forms. Businesses using Belgian accounting reports can now complete the workflow without unexpected setup failures.
Original PR description
### Steps to reproduce: - Install l10n_be_reports & account_accountant. - Switch to "BE Company CoA" company. - Add "281.50" tag to "YourCompany" contact. - Accounting > Configuration > Accounting >…
### Steps to reproduce: - Install l10n_be_reports & account_accountant. - Switch to "BE Company CoA" company. - Add "281.50" tag to "YourCompany" contact. - Accounting > Configuration > Accounting > Chart of Accounts > Add "281.50 - Commissions" tag to 600000 account in CoA. - Create a Vendor Bill for partner "YourCompany" selling "[E-COM11]". Date it sometime in 2024 and confirm. - Go to Accounting > Reporting > Open 325 Forms. - Create a new form for 2024. - Verify that there is a line for "YourCompany" in the form and generate the XML. - Try to install Inventory. #### > Traceback due to a company inconsistencies. ### Cause of the issue: When creating the new `l10n_be.form.281.50` form for 2024, we create a record for "BE Company CoA" and which `partner_id` is the `res.partner` "YourCompany" which does not belong to any company (and hence is accessible from any). However, on the `forms_281_50` related field of the `res.partner` model is `check_company=True`: https://github.com/odoo/enterprise/blob/bc36a68b68c3d0296ee18c3a121b029dd418f430/l10n_be_reports/models/res_partner.py#L15-L23 Currently, this did not matter because we did no call of the `_check_company`. But if we where to launch a call of the `_check_company` on "YourCompany" `res.partner` we would raise a company error. Now, when you install stock 2 things happen and provoke this call: 1) The `res.partner` model becomes `_check_company_auto`: https://github.com/odoo/odoo/blob/b7dbf15aa8116e51708bd51b8dda9bd12bba0a9e/addons/stock/models/res_partner.py#L8-L10 2) We create a warehouse for "Your company and update the `partner_data` https://github.com/odoo/odoo/blob/b7dbf15aa8116e51708bd51b8dda9bd12bba0a9e/addons/stock/models/stock_warehouse.py#L143-L145 https://github.com/odoo/odoo/blob/b7dbf15aa8116e51708bd51b8dda9bd12bba0a9e/addons/stock/models/stock_warehouse.py#L315 However, the `property_stock_customer` and `property_stock_supplier` are `check_company` related fields: https://github.com/odoo/odoo/blob/b7dbf15aa8116e51708bd51b8dda9bd12bba0a9e/addons/stock/models/res_partner.py#L12-L17 Therefore, writing on them for a `_check_company_auto` record will launch a call of the `check_company` for all the fields of the record (including the already inconsistent `forms_281_50`): https://github.com/odoo/odoo/blob/b7dbf15aa8116e51708bd51b8dda9bd12bba0a9e/odoo/models.py#L3780-L3781 https://github.com/odoo/odoo/blob/b7dbf15aa8116e51708bd51b8dda9bd12bba0a9e/odoo/models.py#L3867-L3868 ### Fix: We loosen the company check on the `forms_281_50` to not rely on the `_check_company` since the current workflow lead functionally to valid record data's that will always be considered invalid by this method. opw-4845434
This update aligns Belgian payroll reporting with the 2025/2 DmfA requirements. It helps ensure payroll declarations remain compliant with the latest Belgian social security reporting rules.