Thursday, July 31, 2025
18 changes · saas-18.3
Resolved issues and error corrections
This change rolls back a recent tax calculation update because it caused incorrect handling when taxes are included in prices. Reverting it helps restore accurate tax bases for affected invoices, sales, discounts, down payments, and point-of-sale flows while a safer solution is prepared.
Original PR description
This reverts commit 9166e39bfa4c35a496ebfc3cdc4980c13846f93b which moved the handling of manual tax amounts from `_add_tax_details_in_base_line` to `_round_base_lines_tax_details`, in order to improve the tax computations for downpayments and global discounts. Unfortunately that commit didn't consider the case of price-included taxes where the manual tax amounts must modify the base of the tax. As a result, we are reverting it while we figure out an implementation that correctly handles price-included taxes. task-none
Free self-service point-of-sale orders now follow the same fulfillment step as paid orders, ensuring the required delivery or picking record is created. This prevents free items from being missed in preparation or stock handling workflows.
Original PR description
Steps to reproduce: ------------------- 1. Create a free product 2. Add it to self_order 3. Make a self order with only that product -> Free order Sicne it's a free order, you will not be asked to…
Steps to reproduce: ------------------- 1. Create a free product 2. Add it to self_order 3. Make a self order with only that product -> Free order Sicne it's a free order, you will not be asked to pay, which is normal. However, the issue is, no picking is created for that order!! Why the issue? -------------- For a non free self order, we create a picking for it by calling `_process_saved_order` [1] with `draft` argument set to `True`, either after paying using the online payment method [2], or after paying it from the payment wizard [3]. However, since for free orders, we're not asked at any point to pay, and hence, we're not calling `_process_saved_order` with `draft=True` at any point, and as consequence, we're also not calling `_create_order_picking`, no picking will be created for it. The fix ------- After, marking the free order as 'paid', we manually call `_process_saved_order(True)`. We only do it for the free orders, since the flow is working as expected for non-free order. [1]: https://github.com/odoo/odoo/blob/a7a29ed691db4f1607c0d12929c56845681164fa/addons/point_of_sale/models/pos_order.py#L153C19-L153C31 [2]: https://github.com/odoo/odoo/blob/a7a29ed691db4f1607c0d12929c56845681164fa/addons/pos_online_payment/models/payment_transaction.py#L64 [3]: https://github.com/odoo/odoo/blob/a7a29ed691db4f1607c0d12929c56845681164fa/addons/point_of_sale/wizard/pos_payment.py#L70 opw-4739523 Forward-Port-Of: odoo/odoo#221213 Forward-Port-Of: odoo/odoo#218118
Point of Sale now uses the latest sales order line details when settling an order, rather than relying on outdated cached data. This helps ensure staff charge the correct quantities and prices when a sales order was changed elsewhere before payment.
Original PR description
Steps to reproduce ------------------ 1. Create a Sales Order, add a product with QTY = X 2. Open PoS 3. Load this same Sales order (by clicking "Settle the order"-> QTX is X as expected 4. Return to…
Steps to reproduce ------------------ 1. Create a Sales Order, add a product with QTY = X 2. Open PoS 3. Load this same Sales order (by clicking "Settle the order"-> QTX is X as expected 4. Return to Sales order (in the sales app) 5. Edit QTY from X to Y and save 6. Go back to PoS 7. Delete the laoded Sales Order and load it again -> Notice that QTY is still X and not the updated Y!! Other Flow in frontend ---------------------- 1. Create a Sales Order, add a product with QTY = X 2. Open PoS 3. Load this same Sales order (by clicking "Settle the order"-> QTY is X as expected 4. Change the quantity manually, to pay for X - 1 5. Validate and pay for the order 6. Load the same Sales order again with "Settle the order" -> The quantity is still X and the price is the unit price times X!! Why the issue ------------- When settling the order, we get its value using _getSaleOrder which basically reads it from the cache. So it will read the old order lines having the old qty, and not the updated one. The fix ------- Instead of reading the lines from the cache, we read them direcly from the backend, to accomodate for cases where the data might have been changed on another device or has not been updated in the cache. opw-4819708 opw-4913397 Co-authored-by: Arthur Nanson <artn@odoo.com> Forward-Port-Of: odoo/odoo#220299 Forward-Port-Of: odoo/odoo#218331
Activities marked as done are now excluded from searches and views that show upcoming or overdue work. This prevents completed follow-ups from appearing as pending, improving activity reporting and reducing confusion for CRM and mail users.
Original PR description
The search for "my_activity_date_deadline" is used to find activities due before some set date. When keeping done activities for reporting purposes, we should never consider "done" activities for this search. Issue is introduced in CRM in [1] but it could happen anywhere task-4951716 [1]: https://github.com/odoo/odoo/commit/f9f0529c93614bb9f9deec1a5aaa1daccfe8b58c Forward-Port-Of: odoo/odoo#220428 Forward-Port-Of: odoo/odoo#219426
Chat calls now show video streams at a larger, more useful size when a video participant is present. This makes video conversations easier to follow and prevents streams from appearing as tiny avatar-sized tiles.
Original PR description
Before this commit, when in a discuss call in a chat window with at least 1 video, clicking on no main card had all cards sized for avatar, including the video stream. This is a problem because the…
Before this commit, when in a discuss call in a chat window with at least 1 video, clicking on no main card had all cards sized for avatar, including the video stream. This is a problem because the video stream are very small, barely visible, which is unfortunate because when there are video streams they are usually the most important thing that call participants want to see. This commit fixes by adding a new CSS rule in chat window with call: when user in a call with at least 1 video stream, the size of call view matches the size of a 16:9 video stream when focused. Part of task-4967123 Before / After <img width="381" height="634" alt="Screenshot 2025-07-28 at 17 57 37" src="https://github.com/user-attachments/assets/878bae9f-01e5-4f81-9d61-b43180d4f809" /> <img width="385" height="637" alt="Screenshot 2025-07-28 at 17 57 17" src="https://github.com/user-attachments/assets/0261d716-e52c-4a72-ad6a-007c8d01a362" /> Forward-Port-Of: odoo/odoo#220947 Forward-Port-Of: odoo/odoo#220873
Manufacturing orders with very small work center costs could fail during validation because accounting entries did not balance after rounding. The fix applies consistent rounding before totals are calculated, preventing validation errors and showing the correct cost in the order overview.
Original PR description
Steps to reproduce:
- Create two work centers with different expense accounts:
- First: hourly cost of 0.01
- Second: hourly cost of 0.01
- Create an MO for a product with real-time valuation and 2 work orders
(one per work center).
- Each work order has an expected duration of 30:02
- Attempt to click on "Produce All" button.
This leads to an unbalanced move error.
This fix rounds the values before summing them to prevent rounding issues
and unbalanced moves. It also corrects the displayed value in the
Manufacturing Order overview.
opw-4631409
Forward-Port-Of: odoo/odoo#211128When products valued by lot are revalued, the lot's standard price is now updated to match the new value. This keeps inventory valuation and lot-level product costs consistent after price increases or decreases.
Original PR description
### Steps to reproduce 1. Create a product with valuation by lot in AVCO 2. Purchase 10 quantity and validate the transfer 3. In the valuation report, group by product and revaluate the product ### Before this commit The lot is correctly revaluated, but its standard price is not updated ### After this commit The standard price is updated to reflect the value increase/decrease. opw-4890361 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#219648
Discuss calls now switch more quickly to the backup connection method when a direct peer-to-peer call is unlikely to recover. This reduces waiting time during connection problems and helps users rejoin stable calls sooner.
Original PR description
Before this commit, falling back to the SFU in case of p2p connection issue would take 2 recovery cycles (±10s), which can be a bit long. This commit makes the fallback happen faster if the client does not have TURN servers, which indicates that the connection is unlikely to be recoverable if it failed. Forward-Port-Of: odoo/odoo#206411
Fixes an issue where shoppers could see an error after starting payment, immediately going back to the cart, and changing product quantities. The cart now handles this empty-cart situation safely, helping prevent a broken checkout experience and support incidents.
Original PR description
This error occurs when attempting to update the quantity in the cart. Steps to Reproduce: --- - Install the `website_sale` module - Activate `Demo` payment provider - Go to Website > Shop > Add a product to Cart > View cart - Pay with Demo > Pay - Click the back button(chrome navbar)(Instantly) - Change the quantity for the product Traceback: --- ValueError: Expected singleton: sale.order() At [1], this error occurs because `order_sudo` is empty. This happens when there are no products in the cart — typically because, upon clicking`Pay`, a sale order is created for the product, and when the user navigates back, the cart is empty. [1]- https://github.com/odoo/odoo/blob/a8a7a26dbda046db6f679bc29940add510e34485/addons/website_sale/controllers/cart.py#L248 sentry-5682671428 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#206000
Fixes an issue where connected hardware devices were not reported correctly right after pairing with a database. The system now uses the current pairing token, helping newly paired devices become available without needing a restart.
Original PR description
Since the PR odoo/odoo#218109, the send_all_devices logic was refactored to always send whenever something changes. However, there was a bug introduced due to the fact the token is saved at start-up and never updated. This caused the devices to not get sent correctly immediately after pairing with a DB (in the time before checking out and restarting). --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#221250 Forward-Port-Of: odoo/odoo#221178
The barcode app now avoids saving invalid empty data when scanning lots during receipts with existing lots enabled. This prevents crashes when warehouse staff scan different lot numbers, keeping receipt processing reliable.
Original PR description
## How to reproduce: https://github.com/user-attachments/assets/bf44f9fd-0402-4d70-8b55-5baf192d42e8 - Enable Consignment - On Receipt operation type, enable 'Use existing lots' - Create product P,…
## How to reproduce:
https://github.com/user-attachments/assets/bf44f9fd-0402-4d70-8b55-5baf192d42e8
- Enable Consignment
- On Receipt operation type, enable 'Use existing lots'
- Create product P, tracked by lot
- Create lot SN-001 & SN-002
- Add 1 unit on hand with lot SN-001
- Create Receipt for 10 units of P -> Confirm
- Open receipt on Barcode App
- Scan "SN-002" => 'undefined' value added to 'dbQuantCache'
- Scan "SN-001" => Uncaught Promise > quantsByLocation is not iterable (cannot read property undefined)
---
## Test result without fix:
```
2025-07-18 09:30:33,801 20801 ERROR oes_test_18 odoo.addons.stock_barcode.tests.test_barcode_client_action_picking: FAIL: TestPickingBarcodeClientAction.test_barcode_lazy_cache_scan_two_lots
Traceback (most recent call last):
File "/home/odoo/projects/odoo-src/multiverse/src/18.0/enterprise/stock_barcode/tests/test_barcode_client_action_picking.py", line 3508, in test_barcode_lazy_cache_scan_two_lots
self.start_tour(url, 'test_barcode_lazy_cache_scan_two_lots', login='admin')
File "/home/odoo/projects/odoo-src/multiverse/src/18.0/odoo/odoo/tests/common.py", line 2264, in start_tour
return self.browser_js(url_path=url_path, code=code, ready=ready, timeout=timeout, success_signal="tour succeeded", **kwargs)
File "/home/odoo/projects/odoo-src/multiverse/src/18.0/odoo/odoo/tests/common.py", line 2235, in browser_js
self.fail('%s\n\n%s' % (message, error))
AssertionError: The test code "odoo.startTour('test_barcode_lazy_cache_scan_two_lots', {"stepDelay": 0, "keepWatchBrowser": false, "debug": false, "startUrl": "/odoo/147/action-stock_barcode.stock_barcode_picking_client_action", "delayToCheckUndeterminisms": 0})" failed
TypeError: quantsByLocation is not iterable (cannot read property undefined)
at LazyBarcodeCache.getQuants (http://127.0.0.1:8565/web/assets/3d6bda7/web.assets_web.min.js:21482:279)
at BarcodePickingModel._processBarcode (http://127.0.0.1:8565/web/assets/3d6bda7/web.assets_web.min.js:21748:631)
at async http://127.0.0.1:8565/web/assets/3d6bda7/web.assets_web.min.js:21661:75
```
OPW-4942192
Forward-Port-Of: odoo/enterprise#90828
Forward-Port-Of: odoo/enterprise#90492Kitchen printers connected through IoT are now correctly sent to the point of sale, even when they are not also set up as receipt printers. This ensures kitchen orders can be printed as expected and avoids service disruptions caused by missing printer connections.
Original PR description
As part of odoo/enterprise#91260, websocket now works with kitchen printers. However, due to an oversight this was only the case if the printer was also configured as a Receipt Printer for the POS. This commit fixes the issue by sending the IoT devices corresponding to any configured kitchen printers.
Vendor batch payments now use the correct payable account during bank reconciliation. This prevents payments from being posted against the wrong partner account, improving accounting accuracy and reducing manual corrections.
Original PR description
**Steps to reproduce:** - Install accountant - Go to "Accounting / Vendors / Payments" - Create a payment: * Payment Type: Send * Vendor: [any] * Amount: 1000 - Confirm the payment - From payments list, select the payment and create a batch - Validate the batch payment - From Accounting dashboard, go to Bank journal - Create a statement: * Partner: [None] * Amount: -1000 * Memo: [anything] - Reconcile the statement with the batch payment **Issue:** The receivable account of the partner is used for the batch line instead of his payable account. **Solution:** Select the type of the account to use depending on the type of the payment. opw-4952786 Forward-Port-Of: odoo/enterprise#91206
When a user sends a document and is also one of the signers, they are now taken directly to the signing page instead of seeing another send dialog. This removes a confusing extra step and makes the signing flow smoother for users preparing documents they also need to sign.
Original PR description
**Version:** - saas-18.3 **Steps to reproduce:** - Open a sign template. - Click "Send". - Add signers (include yourself). - Click "Send" to confirm. - The template is shown in preview mode. - Click "Sign Now". - A new "Send" dialog appears. - You have to add signers again. - Click "Send" again. **Issue:** - When the logged-in user is one of the signers, clicking the "Send" button shows a notification and not allows the user to sign. But clicking "Sign Now" again after that is confusing. **Solution:** - If the current user is a signer, clicking the "Send" button should directly open the sign view for that user to sign. task-4933608
Offer lists now show newly created salary offers when users return from the form, whether they start from an applicant or an employee. When creating an offer from an employee record, the employee field is filled in automatically, reducing manual entry and preventing missed links.
Original PR description
…ee field - = hr_contract_salary Steps: - Navigate to Recruitment > Job Positions > Applications> Offers - Now, create a New offer using the New button, and go back to offer list view - Navigate to Employee > Select an employee > Contract > Offers - Now, create a New offer using the New button, and go back to offer list view - Navigate to Employee > Select an employee > Contract > Offers - Now, click on New button to open offer form. Issues: - New offer is not included in list for applicants when returning via breadcrumb - New offer is not included in list for employees when returning via breadcrumb - Employee field is not pre-populated when creating a new offer for employee Fix: - Modified smart button action for applicants - Modified smart button action for employees - Computed the employee field to be autofilled Task - 4787302
The payment widget has been corrected so bank statement line details appear in the appropriate Accounting Enterprise area. This keeps payment and reconciliation information available where expected for users with the accountant features.
Original PR description
Removed the bank statement lines in the payment widget from communiy 'account' and added it to 'account_accountant' Community: https://github.com/odoo/odoo/pull/220981
Mexican point-of-sale global invoices now use the issuing address set on the sales journal when available, instead of defaulting to the company address. This ensures the place of issue shown in the tax XML uses the correct ZIP code for compliance and avoids incorrect invoice details.
Original PR description
Steps to reproduce: [l10n_edi_extended] - setup up a mexican company - create a journal in which you define an issued address (different from your company) - setup your pos with newly created journal - Open a pos session - add a product - pay in cash with no customer - in the backend go into the orders - select the newly created order in the list view and click on the action "create global invoice" - in the order > cfdi: download the created xml Issue: The "Lugar de expedicion" will have the zip code of the company and not from the issued address one Cause: We only check for issue adress in account_move but not from orders. Global invoice is not only for invoices but also to account for sale (orders) made with petty cash Solution: We don't want to create a bridge module only for that. We check if the field is defined on `account.journal` opw-4802389 Forward-Port-Of: odoo/enterprise#86545
This fix ensures Odoo Studio exports include important customization data that was previously left out by default. It helps make exported Studio customizations more complete and reliable when moving or backing them up.
Original PR description
If you create a **StudioExportModel** with a model that we always export (for studio customizations, i.e. ir.ui.view) then the excluded_fields field gets computed. Before this commit, the _compute_excluded_fields method of the StudioExportModel model could have excluded some fields we would like to export. This commit fixes that. **List of fields we should export but by default were excluded:** - "base.automation": "action_server_ids" - "ir.model.fields": "selection" - "studio.approval.rule": ["approver_ids", "can_validate"] - "ir.ui.view": "arch" - "ir.attachment": "datas" task-4866474 Forward-Port-Of: odoo/enterprise#91105 Forward-Port-Of: odoo/enterprise#88125