Monday, November 3, 2025
14 changes · saas-18.3
Enhancements to existing features
Estonia VAT report XML exports now process large sets of accounting data in batches instead of repeating the same work line by line. This prevents timeout errors on high-volume months and helps businesses complete tax reporting reliably and faster.
Original PR description
Behavior before: When exporting the VAT report to XML, each newly added line triggered a fresh _compute_expression_totals_for_each_column_group call. With large volumes of journal items, this…
Behavior before: When exporting the VAT report to XML, each newly added line triggered a fresh _compute_expression_totals_for_each_column_group call. With large volumes of journal items, this resulted in excessive repeated queries and, for big datasets, timeout errors. Behavior after: Introduced _custom_unfold_all_batch_data_generator, which batches the computation of expression totals for all lines. Now, journal items are resolved in bulk and mapped back to their respective moves, significantly reducing redundant queries. The VAT XML export completes successfully, even on months with very large datasets. Root cause: The Estonia VAT report was missing a batch unfold method (_custom_unfold_all_batch_data_generator). Without it, the system executed totals computation for each line individually instead of in batch, causing major performance degradation. Benchmark: | Period size (journal items) | Before patch | After patch | |----------------------------------------|----------------------|--------------------| | ~15k | 7s | 5s | | ~200k+ | Timeout error| 21s | opw-5046077 Forward-Port-Of: odoo/enterprise#97660 Forward-Port-Of: odoo/enterprise#95047
The booking screen in Point of Sale no longer automatically focuses the search bar on phones and tablets. This prevents the on-screen keyboard from opening right away, making the experience smoother and less distracting on touch devices.
Original PR description
Task: [#5016943](https://www.odoo.com/odoo/project/1737/tasks/5016943) --- On tablets and phones, the search bar was autofocus when opening the booking screen in the POS frontend. This was causing the keyboard to open automatically, which was not a good user experience. Now the search bar is not autofocus on touch devices for the booking screen by creating a new controller to manage this. Forward-Port-Of: odoo/enterprise#96873
This update keeps Raspberry Pi and IoT device setup working with newer Python versions by replacing a removed system library. It also fixes file location handling and Wi‑Fi configuration saving so device setup and network settings continue to work correctly on newer system versions.
Original PR description
To ensure compatibility with python 3.13+, we updated the method to generate the rpi's password to avoid using the removed `crypt` lib. We also ensure that files moved between `point_of_sale/tools/posbox/`, `addons/iot_box_image/` and `setup/iot_box_builder` can still be found by system processes using symlinks. Forward-Port-Of: odoo/odoo#233813 Forward-Port-Of: odoo/odoo#233423
Resolved issues and error corrections
Product forms now show the correct tax information when a branch company uses taxes inherited from its parent company. This helps users see accurate sale prices on products, matching the taxes applied later on sales orders and invoices.
Original PR description
Steps: - Install account app. - Create a branch company under the main company. - Create a tax for the branch company. - Add a main company tax on a product. - Switch to branch company. Issue: - Tax…
Steps: - Install account app. - Create a branch company under the main company. - Create a tax for the branch company. - Add a main company tax on a product. - Switch to branch company. Issue: - Tax string is not displaying on the product form even though its setting tax from parent company on invoice line and SO line so its displaying wrong sale price on product form. Cause: - After [PR] taxes are only consider from current company even though company is branch company but in [17.0 PR] we share taxed and other accounting related data b/w main and branch company so if branch does not it's specific tax applied on product then it should take tax from its parent company. Fix: - Compute tax_string in product the way we compute tax on invoice line, SOL etc using `_filter_taxes_by_company` method this way it'll give proper tax which will be applied on related documents. [PR]: https://github.com/odoo/odoo/pull/194881 [17.0 PR]: https://github.com/odoo/odoo/pull/125642 opw-5042833 Forward-Port-Of: odoo/odoo#233720
The Point of Sale settlement flow now checks that a customer still exists before calculating their outstanding balance. This prevents sessions from crashing when a customer was deleted while the session was still open, improving reliability for store staff.
Original PR description
Currently, a missing exception is triggered when reopening a PoS session after a partner is deleted. **To reproduce this issue:** 1) Install point_of_sale and pos_settle_due. 2) Open a PoS session 3)…
Currently, a missing exception is triggered when reopening a PoS session after a partner is deleted. **To reproduce this issue:** 1) Install point_of_sale and pos_settle_due. 2) Open a PoS session 3) Create a customer and place an order with payment. 4) Without closing the session, go to the backend. 5) Delete the customer from Contacts. 6) Reopen the previously opened PoS session. **Error:** A `missing record` exception is triggered. **Cause:** When the user reopens a PoS session after deleting a partner, the method `setAllTotalDueOfPartners` is triggered during setup. https://github.com/odoo/enterprise/blob/7c6ba26970698cb60121157c2cca0e414d5b62a0/pos_settle_due/static/src/app/services/pos_store.js#L7-L9 https://github.com/odoo/enterprise/blob/7c6ba26970698cb60121157c2cca0e414d5b62a0/pos_settle_due/static/src/app/services/pos_store.js#L44-L48 This method makes an RPC call to `get_all_total_due` to update all partners' due amounts. Since the partner was deleted, this causes a missing record exception. https://github.com/odoo/enterprise/blob/7c6ba26970698cb60121157c2cca0e414d5b62a0/pos_settle_due/models/res_partner.py#L28-L32 **Solution:** Before calling `get_total_due`, verify the partner still exists in the database. Related Community PR:- https://github.com/odoo/odoo/pull/219809 opw-4897814 Forward-Port-Of: odoo/enterprise#90596
Customers linked to Point of Sale orders can no longer be deleted while they are still needed by an open PoS session. This prevents reopening a session from failing with missing customer data and helps keep sales records consistent.
Original PR description
Currently, a partner can be deleted even if they have associated PoS orders. This causes inconsistent behavior, such as missing record tracebacks when reopening a PoS session. **To reproduce this…
Currently, a partner can be deleted even if they have associated PoS orders. This causes inconsistent behavior, such as missing record tracebacks when reopening a PoS session. **To reproduce this issue:** 1) Install point_of_sale and pos_settle_due. 2) Open a PoS session 3) Create a customer and place an order with payment. 4) Without closing the session, go to the backend. 5) Delete the customer from Contacts. 6) Reopen the previously opened PoS session. **Error:-** A `missing record` exception is triggered. **Cause:** - Starting from SaaS-18.1, PoS supports offline mode with limited functionality, due to this commit: https://github.com/odoo/odoo/pull/184417/commits/711e248efd54500f91acfb1b9a30f48177c34925 - Before this commit, data was reloaded whenever a session was opened or reopened, ensuring proper synchronization with the backend. - After this commit, IndexedDB is used to cache data and it is reused every time the session is reopened. - When the user reopens a PoS session after deleting a partner, the method `setAllTotalDueOfPartners` is triggered during setup. - This method makes an RPC call to `get_all_total_due` to update all partners due amounts. Since the partner was deleted, this causes a missing record exception. **Solution:** - Prevent users from deleting a partner who has PoS orders and an open session. - Before calling `get_total_due`, verify the partner still exists in the database. Related Enterprise PR:- https://github.com/odoo/enterprise/pull/90596 opw-4897814 Forward-Port-Of: odoo/odoo#219809
The Journal Report now updates its Global Tax Summary amounts when users change the rounding unit. This keeps tax summary figures consistent with the rest of the report and prevents confusion from mixed number formats.
Original PR description
Currently when users change the rounding unit filter in the Journal Report, the Global Tax Summary values remain in the old format instead of updating to reflect the new rounding setting. This…
Currently when users change the rounding unit filter in the Journal Report, the Global Tax Summary values remain in the old format instead of updating to reflect the new rounding setting. This creates inconsistency where main report values update correctly but tax summary values stay unchanged. Cause: - The issue occurs because `_format_column_values` method in `account_report.py` wasn't handling the special tax summary data structures (`tax_report_lines` and `tax_grid_summary_lines`) that store pre-formatted values. These structures need to be reformatted when rounding unit changes, but the formatting logic only covered standard report columns. Fix Applied: - Updated frontend (`filters.js`) to call `format_column_values_from_client` via `dispatch_report_action` instead of calling `format_column_values` directly. (this enables proper routing through the custom handler system) - Added `format_column_values_from_client` override in `JournalReportCustomHandler` that intercepts the formatting call and applies special handling for tax summary lines by adding logic to reformat `tax_report_lines` and `tax_grid_summary_lines` monetary fields using their `_no_format` counterparts. - The custom handler then delegates to the base method via `report.format_column_values_from_client()` to format standard columns. - Also added missing `_no_format` fields in `account_journal_report.py` for `base_amount` and `tax_amount` to enable proper reformatting. Forward-Port-Of: odoo/enterprise#98508 Forward-Port-Of: odoo/enterprise#94660
Fixed an issue where updating multiple combo products on an unsaved sales order could move combo items under the wrong combo. Sales teams can now adjust combo quantities with confidence that the order lines remain correctly grouped before saving.
Original PR description
Steps to Reproduce: - Create a Sale Order containing two combo products placed consecutively. - Change the quantity of the first combo → corresponding combo items update correctly. - Without saving,…
Steps to Reproduce: - Create a Sale Order containing two combo products placed consecutively. - Change the quantity of the first combo → corresponding combo items update correctly. - Without saving, change the quantity of the second combo. - Observe that the combo items now appear misplaced — items from the second combo are inserted before those of the first combo. Issue: - The order of combo items becomes incorrect when multiple combo products are updated consecutively in the same unsaved Sale Order. Cause: - During `onchange`, the `self.order_line` recordset reflects the *in-memory order of applied commands* rather than the database `sequence` field because they are not saved in the DB during the edition. - Each `onchange` rebuilds `order_line` using concatenated command lists (`delete + create + update`), So when multiple combos are modified without save, newly created combo items are appended according to command evaluation order — not by logical grouping. - This causes combo items to shift relative to their parent combo lines. Solution: - Restrict the recomputation of order lines to non-combo lines by filtering out combo item lines during the rebuild. As combo items will always be in their desired sequence. - This ensures that combo items always stay under their respective parent combos and their sequence is preserved, regardless of the order in which combos are updated. opw-5148770 Affected Version:18.0 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233740
Barcode scans are now ignored when a draft, cancelled, or completed batch transfer is opened in a context where scanning cannot be processed. This prevents confusing error messages and system tracebacks, giving warehouse users a smoother experience in the barcode app.
Original PR description
### Issue: Scans processed during picking batch creation in the barcode app are interpreted as scans related to the BarcodePickingBatchModel edition (that is product, lot, package,... scans) which…
### Issue: Scans processed during picking batch creation in the barcode app are interpreted as scans related to the BarcodePickingBatchModel edition (that is product, lot, package,... scans) which does not make sense and raises multiple errors. ### Steps to reproduce: - In the settings enable "Batch Transfers" - Inventory/Operations/Transfers/Batch Transfers - Create a new batch and do not confirm it - Go to the barcode app > Batch Transfers > Clear filters - Select your draft batch - Scan anything #### > Traceback #### Other issues: The same flow with a cancelled batch triggers the same tracebacks and, with a done batch triggers the message: "This picking is already done". ### Cause of the issue: Since `this.state.view === "barcodeLines"`, scans are processed as if we were processing an existing `BarcodePickingBatchModel` with lines: https://github.com/odoo/enterprise/blob/ce7460b27028d4133c4689afd2e8f303268494a0/stock_barcode/static/src/components/main.js#L204-L209 In particular, if the scan corresponds to a product, and error will be raised because the scan can not process a `createNewLine` for the scanned product in the current view and if the scan does not correspond to anything valid, it will raise an error because `this.picking` is undefined and `this.picking.use_existing_lots` raises an error: https://github.com/odoo/enterprise/blob/ce7460b27028d4133c4689afd2e8f303268494a0/stock_barcode/static/src/models/barcode_model.js#L1115 https://github.com/odoo/enterprise/blob/ce7460b27028d4133c4689afd2e8f303268494a0/stock_barcode_picking_batch/static/src/models/barcode_picking_batch_model.js#L177-L179 opw-5162164 Forward-Port-Of: odoo/enterprise#98022 Forward-Port-Of: odoo/enterprise#97526
This fixes Belgian payroll so public holidays during long-term sick leave are no longer paid after the legally required 30-day period. It helps ensure payslips follow Belgian rules and avoids overpaying employees in these specific absence cases.
Original PR description
Bug: In Belgium, after 30 calendar days of sick leave, all public holidays during the sick leaves are no longer paid. But here they were still being paid. Cause: The method that was checking what to do about public holidays was never seeing public holidays since they were already changed to their corresponding work entries at the work entry generation. Fix: Add the public holidays in the context and change the condition for checking if the current leave is actually from a public holiday or not. Task: 3864585 Forward-Port-Of: odoo/enterprise#98388 Forward-Port-Of: odoo/enterprise#95178
This fix stops the system from trying to create product feeds for websites that would immediately exceed the allowed product limit. It prevents a migration error and helps affected databases upgrade smoothly without hitting an unnecessary validation failure.
Original PR description
``` File /home/odoo/src/odoo/saas-18.4/addons/website_sale_product_feed/models/product_feed.py, line 105, in _check_product_limit raise ValidationError(feed.env._( odoo.exceptions.ValidationError: A…
```
File /home/odoo/src/odoo/saas-18.4/addons/website_sale_product_feed/models/product_feed.py, line 105, in _check_product_limit
raise ValidationError(feed.env._(
odoo.exceptions.ValidationError: A single feed cannot contain more than 5,000 products. Please separate products with Categories.
```
```
(Pdb) feed.env['product.product'].search_count(feed._get_feed_product_domain())
12433
```
During migration I am getting the traceback mentioned above, which is occurring because [here](https://github.com/odoo/odoo/blob/saas-18.3/addons/website_sale_product_feed/__init__.py#L14) we have populated feed records in _post_init_hook which will create feed records without any [category ID](https://github.com/odoo/odoo/blob/saas-18.3/addons/website_sale_product_feed/models/website.py#L21) because of which, [here](https://github.com/odoo/odoo/blob/saas-18.3/addons/website_sale_product_feed/models/product_feed.py#L101) we get all records without a category, which is of course higher than our soft limit of 5000, and a validation error occurs: the customer database does not have GMC enabled. Still, it calls _populate_product_feeds, which is why I have moved it to a condition.
opw-5180407
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThe product catalog now shows the right price when a product already on the order has a discount and the unit price is displayed separately. This fixes a mismatch that could make catalog prices appear higher than the actual order price, helping users review orders more accurately.
Original PR description
Catalog prices do not consider discounts when displayed separately from the unit price on the order line (if any for a given product). It was fixed for the /update_order_line_info route with 5d1837e47c20f04458472658c4f8ea71284fb6ca, but the issue still remained when fetching the original catalog data on opening, through the /order_lines_info route. This only happened when the product was already added to the order, because in this case we avoid recomputing the pricelist price and use the existing sale order line price. This commit makes sure that the sale order line discount field is correctly considered in that case, and also adds tests to cover the catalog more extensively. Fixes #232219 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233098
Scanning a barcode in the product search now reliably uses the entire barcode instead of sometimes stopping at a partial value. This prevents incorrect searches and helps users find the right product faster and more consistently.
Original PR description
Issue ----- When scanning a barcode in the product view, the search is made using only part of the barcode. Steps to reproduce ----- - Open the product view - Scan a barcode (eg 1234567890) > The search might only contain 12345678, 123456 or actually the full barcode Cause ----- When scanning a barcode, we receive all of the barcode characters followed by newline. When we receive the newline, we select the first item in the dropdown. The problem is that the search input changed but it hasn't been reflected yet in the items (a rendering is scheduled but hasn't been applied to the DOM yet). ----- Ticket: opw-4874425 Forward-Port-Of: odoo/odoo#232270
This fix ensures the currency and unit shown for emitted emissions refresh properly when the emission factor changes. It prevents outdated values from being displayed in ESG reports, improving accuracy and consistency for users.
Original PR description
The `currency` and `unit` fields on emitted emissions are supposed to be related fields on the emission factor. However, due to how the report combining accounting emissions and other emissions is implemented, they are not correctly updated when the factor is modified. This PR makes them computed fields and enable the "store" attribute en them. Despite there being no actual table to store data into, this allows us to do a round trip to the server to fetch the correct values.