Wednesday, September 24, 2025
14 changes · saas-18.3
Enhancements to existing features
This update improves how accounting tax calculations handle global discounts and down payments, helping keep document totals consistent after recalculations. It also prepares the tax logic for future product changes by making shared calculation helpers more reliable and reusable.
Original PR description
--- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Resolved issues and error corrections
Fixed an issue in Accounting reports where the Follow-Up Report could crash when users loaded additional invoice lines for customers with many invoices. This ensures users can review large follow-up reports without interruption.
Original PR description
**Steps to reproduce:** 1. Install the Accounting module. 2. For partner X, create minimum 90 invoices for `See more/Load more` option into page. 3. In the partner form view, click the Customer…
**Steps to reproduce:**
1. Install the Accounting module.
2. For partner X, create minimum 90 invoices for `See more/Load more` option into page.
3. In the partner form view, click the Customer Statement smart button.
4. Change the Report Type from Customer Statement to Follow-Up Report.
5. In the report, click `See more` in the dropdown → traceback occurs.
**NOTE**
- You can easily create invoices using this cron job to generate 90 invoices.
```py
for i in range(90):
invoice = env['account.move'].create({
'move_type': 'out_invoice',
'partner_id': 10,
'company_id': env.company.id,
'invoice_line_ids': [(0, 0, {
'product_id': 16,
'quantity': 1,
'price_unit': 100.0,
})],
})
invoice.action_post()
```
**Issue:**
`UncaughtPromiseError > OwlError
Uncaught Promise > Got duplicate key in t-foreach: ~account.report~17|~res.partner~42|Due~~
Occured`
- A traceback occurs due to a duplicate key error.
**Cause:** https://github.com/odoo/enterprise/blob/459e8ddaf6f67a556d35bf00e0fbb68eb1500a94/account_reports/static/src/components/account_report/account_report.xml#L72-L73
- In account_report.xml component uses line.id as a key.
<img width="781" height="176" alt="image" src="https://github.com/user-attachments/assets/57bf36ea-6890-45ef-8414-5522d71ece7b" />
- When expanding `See more` headings like `Overdue` are rendered again with the same ID causing a duplicate key error.
<img width="754" height="194" alt="image" src="https://github.com/user-attachments/assets/0eba65e0-0bf2-4f64-a997-27a25e5de5fe" />
**Solution:**
- Use the `line_index` instead of `line.id` as the key, ensuring a unique key for every line and preventing the traceback.
**opw - 5083894**
Forward-Port-Of: odoo/enterprise#95103The spreadsheet component was updated to the latest version for this Odoo release. This fixes an issue where sorting could fail for certain array formulas, helping users work more reliably with spreadsheet data.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/fb227d71f [REL] 18.3.22 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/220054c18 [FIX] Sort: Allow to sort array formula that do not spread [Task: 5033192](https://www.odoo.com/odoo/2328/tasks/5033192) 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: Ronak Mukeshbhai Bharadiya <rmbh@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>
Customers using in-store pickup will now have the default pickup location properly saved at checkout, even if they did not choose it before adding an item to the cart. This prevents a confusing checkout error that blocked customers from continuing to payment when the page appeared to show a valid pickup location.
Original PR description
Description of the issue/feature this PR addresses: This commit fixes the issue where the pickup location does not get set even though it is present on the checkout page. This happens when the user…
Description of the issue/feature this PR addresses: This commit fixes the issue where the pickup location does not get set even though it is present on the checkout page. This happens when the user directly adds an item to cart without specifying the pick up location before adding to cart. This results in the location not being set but at the checkout page, the default pick up location appears as one of the warehouses given the way the default pickup location is set when loading the checkout page values. This makes the user think that the pickup location is set, but when they try to go to the pay page, an error is thrown saying the pick up location was not specified. This commit sets the pickup location data in such a case. [This commit] refactored the way in which the default location would be set on the checkout page but did not take into account the possbility that the customer might not select the pickup location when they are adding to cart, thus only rendering the value at the checkout page but not actually setting it. Refactored the test cases to avoid the redundancy in the setup process. Steps to reproduce on runbot: 1. Set the pick up in store as the default delivery method by updating the sequence 2. Go the shop on the website and add any item to cart which has stock in the specified pickup location, but don't select the pickup location here 3. Go to the cart and click checkout 4. The default pickup location will be set here 5. Click on Confirm 6. An error will appear saying the location was not set opw-4954187 [This commit]: https://github.com/odoo/odoo/commit/1d3942c75e59ac9538d112df43b4e39f2462fee4 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Public holiday timesheets now reflect an employee’s flexible working schedule instead of defaulting to the company’s standard 8-hour day. This prevents incorrect time-off entries for employees whose average daily hours differ from the company default.
Original PR description
## Issue: For employees with flexible working hours, when a Public Holiday is added, the timesheet was filled with 8h based on the company’s default calendar instead of the employee’s flexible…
## Issue: For employees with flexible working hours, when a Public Holiday is added, the timesheet was filled with 8h based on the company’s default calendar instead of the employee’s flexible schedule ## Cause: When creating `resource.calendar.leaves`, timesheets call `_work_time_per_day()` This method uses `work_hours_data` containing half-day intervals (tmp_start/tmp_end) These data come from `_attendance_intervals_batch()`, but we were passing an empty resource, so the check for `flexible_hours` failed: https://github.com/odoo/odoo/blob/bd7d5fdf8df3a4d544de3e2493cd4b3966fa7d0b/addons/resource/models/resource_calendar.py#L382-L393 We want to use the calendar itself as the calendar resource to get the `work_hours_data` ## Steps to reproduce: - On an employee, in Work Information, set the Working Hours to Flexible 40 hours/week - Modify Flexible 40 hours/week (Hours per Week: 30, Average Hour per Day: 6) - In Time Off > Configuration > Public Holidays, add a New holiday (You can leave default values) - Go in Timesheets > All Timesheets, before the fix, the flexible employee have 8h in internal for Time Off opw-4881758 Forward-Port-Of: odoo/odoo#225876
Italian vendor invoice XML imports now keep the correct TD01 document type instead of being changed to TD05. This helps businesses using Italian e-invoicing avoid incorrect invoice classification and related accounting or compliance confusion.
Original PR description
**Issue** When importing an XML invoice of document type TD01, it is incorrectly assigned type TD05 after processing. **Steps to Reproduce** 1. Install Accounting, l10n_it and l10n_it_edi 2. Go to…
**Issue**
When importing an XML invoice of document type TD01, it is incorrectly assigned type TD05 after processing.
**Steps to Reproduce**
1. Install Accounting, l10n_it and l10n_it_edi
2. Go to Accounting > Vendors > Vendor Bills
3. Upload an XML invoice with TD01 as the document type
4. Upon confirming the bill, observe that the document type is incorrectly set to TD05
**Root Cause**
The document type matching logic fails to assign TD01 because the uploaded invoice has move_type = in_invoice, while TD01 was only configured to match out_invoice. https://github.com/odoo-dev/odoo/blob/7436e8cee2f605c6d5d559cb410e7a3dc8f372b9/addons/l10n_it_edi/models/account_move.py#L886-L891
**Fix**
According to Italian e-invoicing specifications, TD01 applies to both sales and purchase invoices ("Fatture di vendita" and "Fatture d’acquisto"). To reflect this, in_invoice is now added to the list of supported move_types for TD01, allowing correct detection during XML import.
opw-4931438
Forward-Port-Of: odoo/odoo#219310This fixes an issue where users could not add custom fields from the optional columns menu in Knowledge article lists. The change ensures Studio correctly recognizes whether the current action can be edited, restoring the expected customization workflow.
Original PR description
Steps to reproduce ================== - Install knowledge, web_studio - Go to knowledge > Articles - Click on the optional columns dropdown - Click on "Add Custom Field" => This action is not editable by Studio Cause of the issue ================== Since https://github.com/odoo/odoo/pull/205129/commits/c18e93191c516f6e37093f068e8934cba8495891 the event ACTION_MANAGER:UI-UPDATED is triggered before the list renderer has a chance to register for it. Solution ======== We don't actually need to listen to that event to get the info we need. The action xml_id was missing, but it was added in the view subenv config. opw-5066488
Chile electronic invoice imports now correctly treat lines marked with exemption code 6 as negative amounts. This prevents supplier bills from being imported with overstated positive values, improving accounting accuracy for Chilean companies.
Original PR description
### Issue: When, in a DTE file, a line has the code 6 in `IndExe`. The amount of the line is supposed to be negative. (See the [doc](https://www.sii.cl/factura_electronica/formato_dte.pdf) page 31/32) ### Steps to reproduce: - Install 'l10n_cl_edi' and switrch to a Chilean company - Have a DTE file with a line having '6' in `IndExe`: - In Accounting > Vendor > Bills, click the button "Upload" and select the DTE file - The imported move has positive values on the every lines ### Cause: The values of `IndExe` are not considered. ### Solution: Add a condition changing the sign of `price_unit` when 6 is in `IndExe` opw-4954723 Forward-Port-Of: odoo/enterprise#93393
Chilean electronic delivery guide XML now shows the quantity actually delivered instead of the quantity originally ordered. This prevents customers and authorities from seeing inflated quantities when a partial delivery is completed without a backorder.
Original PR description
**Issue** When the delivered quantity of a product is less than the originally demanded quantity, the generated Delivery Guide XML shows the demand (product_uom_qty) instead of the actual delivered…
**Issue** When the delivered quantity of a product is less than the originally demanded quantity, the generated Delivery Guide XML shows the demand (product_uom_qty) instead of the actual delivered quantity (quantity). This results in an incorrect quantity being displayed in the DTE. **Steps to Reproduce** 1. Install the Accounting module, Chilean localization, Sales module, and l10n_cl_edi_stock. 2. Create and confirm a new Sale Order. 3. Click on the Delivery smart button. 4. Adjust the delivered quantity to a value lower than the demand, save, and validate with no backorder. 5. Generate the Delivery Guide. 6. Open the generated DTE XML and observe that the quantity is incorrect. **Root Cause** The quantity displayed in the DTE is taken from product_uom_qty, which represents the planned quantity to be moved, not the actual delivered quantity. The correct field to use is quantity, which reflects the real delivered amount. **Fix** Change the XML output to use quantity instead of product_uom_qty to accurately reflect the actual delivered quantity in the DTE. Opw-4892276 Forward-Port-Of: odoo/enterprise#89633
Point of Sale now applies the same fiscal position tax rules as accounting. This prevents receipts and backend orders from showing different tax totals when a fiscal position has no related taxes.
Original PR description
If a fiscal position is not related to any tax, when selecting said fiscal position in the pos, the tax from the product is kept. When looking at the paid order in the backend the tax is removed on…
If a fiscal position is not related to any tax, when selecting said fiscal position in the pos, the tax from the product is kept. When looking at the paid order in the backend the tax is removed on the order line and the price unit and price with taxes are different (although no tax recorder on the line). Steps to reproduce: ------------------- * Create a fiscal position and assign no tax to it * On the pos config, add this fiscal position and the domestic one to the available fiscal positions * Open pos session * Select a product that has a 15% tax * Change the fiscal position to the one just created > Observation: We still see that the tax is computed based on the 15% * Pay the order * Go see the order in backend > Observation: price unit: 100, no tax, price with taxes 115 Why the fix: ------------ A recent refactoring happened on the accounting side related to fiscal positions: https://github.com/odoo/odoo/commit/9a97157920c845120861dda49d81d3150e015974 https://github.com/odoo/odoo/blob/e284dfd80bde632e6446fc0b8d3276689da35200/addons/account/models/partner.py#L155-L163 The behavior after this refactoring is the following: When changing fiscal position: - If the original tax is available for the fiscal position, we use it - If the original tax is not available but the fiscal position has an available tax that is set to be replacement for the original one, we use the replacement tax - If the original tax is not available but the fiscal position has an available tax which is NOT a replacement for the original one, we keep the original one - If the fiscal position has no tax available, we remove the tax In this fix we apply the same logic inside the pos. Without the fix we would keep the original tax in the frontend but when passed in the backend the tax with fiscal position was recomputed with the logic from accounting. This explained the difference we observed. opw-4978056
Quality checks for serial-tracked products now correctly record failed units when no failure location is configured. This prevents failed checks from being incorrectly counted as passed, giving warehouse and quality teams more reliable inspection results.
Original PR description
Issue: --------------------------------- When a serial-tracked product has a quantity-type quality point and a check is failed, the system incorrectly marked it as passed. Steps to reproduce:…
Issue: --------------------------------- When a serial-tracked product has a quantity-type quality point and a check is failed, the system incorrectly marked it as passed. Steps to reproduce: --------------------------------- - Install the `quality_control` module. - Create a quantity-type quality point for a serial-tracked product and a receipt operation type. - Do not set a failure location on the quality point. - Create a receipt for the serial-tracked product with 3 units. - Assign serial numbers to the receipt. - Perform the quality checks: * Pass 2 checks * Fail 1 check - Result: all checks are marked as passed. Cause: --------------------------------- When a quantity-type quality check without a failure location is failed, the `do_fail` method directly calls `confirm_fail`. In this method, `qty_failed` was set to 0, which caused the system to treat the failed check as if all quantities had passed. Fix: --------------------------------- Ensure that `qty_failed` is correctly set in this case, so failed checks are properly recorded. This allows the quality control flow to behave as expected and gives users accurate results for passed and failed quantities.
Point of Sale now shows the optional product popup when an item is added by scanning its barcode, not just when it is selected manually. This gives cashiers a consistent checkout experience and helps ensure related add-on products are not missed.
Original PR description
Before this commit, the optional product popup was only displayed when adding a product by clicking on it. When the product was added through barcode scanning, the popup did not appear. This commit ensures that the optional product popup is consistently shown both when clicking on a product and when scanning its barcode. opw-5089175 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Czech VAT control statement entries without a customer VAT number are now placed in section A5 even when they exceed 10,000 CZK. Entries under special VAT regimes for travel services and margin schemes are also consistently reported in A5, helping businesses file more accurate VAT returns.
Original PR description
Before this commit, the l10n_cz VAT return report classified entries in section A4 if their total amount exceeded 10,000 CZK, and in section A5 if the amount was 10,000 CZK or less. - In l10n_cz, create an invoice with a cz partner without vat, over 10000. - In tax return the entry will be in section A4. With this commit: - Entries with no partner VAT number are now always classified under A5, regardless of the total amount. - Entries using a special VAT regime (l10n_cz_scheme_code), corresponding to Section 89 – travel services and Section 90 – margin scheme) are also always classified under A5, regardless of the amount. opw-4953787 Forward-Port-Of: odoo/enterprise#92833
Point of Sale now recalculates the amount due when an order that was already partially refunded is refunded again. This prevents customers or staff from being charged the original order total instead of the correct remaining balance.
Original PR description
Before this commit, refunding a partially refunded order did not update the total price based on the remaining lines. As a result, it was possible to pay the original total amount instead of the correct remaining amount. opw-5100790 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#228186