Friday, July 4, 2025
20 changes · master
Resolved issues and error corrections
Point of Sale orders using the Ship Later option now keep the selected delivery date correctly in all time zones. This prevents customers and staff from seeing deliveries scheduled one day earlier than intended.
Original PR description
This is a fix to the bug when a shipping date in picked in specific timezones, the previous day is set. The steps to reproduce: 1- Setup a database with point_of_sale app installed 2- In configuration -> Setting, check Allow Ship Later option for a pos shop. 3- Change the browser timezone to a US timezone. In chrome it can be in Console -> Sensors -> Location. 4- Open POS register, select a product, choose payment and use Ship Later, to pick a date. 5- The previous day is picked which is the bug. The reason is that the shippingDate is parsed into shipping_date which is an object. We now manually deserialize and serialize the date to avoid automatic timezone handling. opw-4853757 Forward-Port-Of: odoo/odoo#217133 Forward-Port-Of: odoo/odoo#215140
This fix prevents Odoo screens from crashing when a file-related field contains unexpected non-text data or appears unintentionally in an automatically generated form. It improves reliability for users by safely handling these edge cases and avoiding display of technical binary fields that are not meant for regular forms.
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 Forward-Port-Of: odoo/odoo#217086 Forward-Port-Of: odoo/odoo#213967
This fix makes the data loading process consistent between Point of Sale and self-ordering, reducing cases where information is missing in one experience but available in the other. It helps prevent issues such as receipt printing failures when required system details are not loaded for self-ordering sessions.
This fix ensures manufacturing orders created in batches use the expected work order duration for each individual order. It prevents incorrect finished dates, especially in custom or automated batch creation flows.
Original PR description
If you create mrp.production in batch, date_finished is wrong. Note: it probably works as is in standard flow because always used on a single record (ex: form view) but it might break custom code. opw-4629270 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#216550
This fix prevents errors when creating mail-related records for companies that do not have an email domain configured. It ensures Odoo correctly treats a missing domain as empty, avoiding conflicts with another company’s domain during app installation or setup.
Original PR description
Before this commit, creating a mail alias mixin (typically a project) with an unspecified domain in a multi-company setup could lead to access errors "We could not create alias Inactive Alias because domain <client domain> belongs to company <company 1> while the owner document belongs to company <company 2>" Steps to reproduce: 1. Start with a clean DB 2. install an app that uses mail (e.g. CRM or Project) 3. Create a second company 4. Set a domain for the 1st company (the one created by default) 5. Erase the domain of the second company (the one created at step 3) 6. Try to install the Field Service app After this commit, not specifying the domain gets correctly interpreted and a default None value is used. opw-4051655 Forward-Port-Of: odoo/odoo#173999
Creating invoices from multiple point-of-sale orders for the same customer no longer fails when the orders belong to different salespeople. This keeps back-office invoice creation reliable for teams where several users process orders in the same POS workflow.
Original PR description
The error occurred because multiple POS orders with different `user_id` were grouped together for invoice creation, and the code attempted to access `self.user_id.id`, which expects a single record…
The error occurred because multiple POS orders with different `user_id` were grouped together for invoice creation, and the code attempted to access `self.user_id.id`, which expects a single record but received multiple (`res.users(1, 2)`). Steps to Replicate: - Open any POS shop (Ex: Furniture Shop) and select a Customer. - Add any item to the order and complete the order. - Close the session, go to Backend and open POS orders. - Make sure the states of the orders are all in `to invoice` state, and check that salesperson should not be all the same (atleast one salesperson should be different and the customer should be same). - Select all the Orders, click `Create Invoices` and click Create and see the error. Error: `ValueError: Expected singleton: res.users(1, 2)` Solution: - Solved the error by grouping the POS orders by both `user_id` and `fiscal_position_id`, ensuring each group contains orders from only one user, which prevents the singleton error when accessing `user_id.id` during invoice creation. sentry-6590469396 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#217238 Forward-Port-Of: odoo/odoo#208833
This fix ensures that deferred accounting entries protected by the audit trail are cancelled as intended when an invoice is reset to draft. It prevents posted deferred entries from being incorrectly reversed, helping accounting records stay consistent with audit trail rules.
Original PR description
**Steps to reproduce:** - Install accountant - In Accounting settings, activate "Audit Trail" - Create an invoice: * Customer: [any] * Invoice Lines: - Product: [any] - Start Date: [2 months ago] -…
**Steps to reproduce:**
- Install accountant
- In Accounting settings, activate "Audit Trail"
- Create an invoice:
* Customer: [any]
* Invoice Lines:
- Product: [any]
- Start Date: [2 months ago]
- End Date: [2 months later]
- Confirm the invoice
=> Deferred Entries are created. Posted for the previous months and in draft for the future ones.
- Reset the invoice to draft
**Issue:**
The draft entires are correctly unlinked, but the posted ones are reversed instead of being cancelled.
**Cause:**
This fix https://github.com/odoo/odoo/commit/cc448bf77aa3d11e634e6bab6da1690a1b67a723 is supposed to cancel the deferred entries when the move is protected by the audi trail.
However we never get into the `elif move._is_protected_by_audit_trail():` branch because its condition is also included in the previous `if not move._can_be_unlinked():` branch.
Linked enterprise PR (test): https://github.com/odoo/enterprise/pull/88992
opw-4891975
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#217300
Forward-Port-Of: odoo/odoo#216628Fixed an issue in Point of Sale where entering extra digits after quick amount buttons could produce the wrong payment amount. This helps cashiers record intended payments accurately and avoids checkout errors.
Original PR description
Steps to reproduce: =================== - Add a product to the orderline from the product screen - Click payment - Select any payment method - Enter the amount manually - Press `+20`, then press `2`, OR press `+20`, then press `6` Issue: ====== - In the case of `+20` and `2`, the expected result is `202`, but we get `20` - In the case of `+20` and `6`, the expected result is `206`, but we get `20.01` Cause: ====== - `formatCurrency` is used for the buffer, but the buffer should not depend on the currency Fix: ==== - Remove the usage of `formatCurrency` and treat the buffer as a string Task: 4850543 Forward-Port-Of: odoo/odoo#217108 Forward-Port-Of: odoo/odoo#213294
Payments made with existing third-party checks now automatically use the currency of the selected check. This prevents incorrect exchange-rate calculations and blocks mixing checks in different currencies, reducing payment errors for Argentinian localization users.
Original PR description
**Steps to reproduce:** - Install accountant, l10n_ar and l10n_latam_check - Switch to an Argentinian company (e.g. (AR) Responsable Inscripto) - Make sure that USD currency has a rate different than…
**Steps to reproduce:**
- Install accountant, l10n_ar and l10n_latam_check
- Switch to an Argentinian company (e.g. (AR) Responsable Inscripto)
- Make sure that USD currency has a rate different than 1
- Create a journal:
* Journal Name: Checks journal
* Type: Cash
- Save the journal
=> a Cash Account should be automatically created
- In "Incoming Payments" tab of the journal, set:
* "New Third Party Checks" with the Cash Account
* "Existing Third Party Checks" with the Cash Account
- In "Outgoing Payments" tab of the journal, set:
* "Existing Third Party Checks" with the Cash Account
- Create an invoice:
* Customer: [an Argentinian customer] (e.g. ADHOC SA)
* Currency: ARS
* Invoice Lines:
- Quantity: 1
- Price: 150000.00
- Taxes: VAT 21%
- Confirm the invoice
- Pay the invoice:
* Journal: [the created Checks journal]
* Currency: ARS
* Checks: [add a line with the amount of the invoice]
- Create a bill:
* Vendor: [an Argentinian customer] (e.g. ADHOC SA)
* Currency: USD
* Invoice Lines:
- Quantity: 1
- Price: 500.00
- Taxes: VAT 21%
- Pay the bill:
* Journal: [the created Checks journal]
* Payment Method: Existing Third Party Checks
* Checks: [add a line and select the check used to pay the invoice]
**Issue:**
When the check (from the invoice) is selected to pay the bill, the original amount (in ARS) is used but the currency stays in USD, which is not correct.
If the currency is changed to ARS, the currency rate is applied on the amount that is already the amount in ARS, which generates a higher incorrect amount.
**Solution:**
Use the currency set on the existing check by default.
Also prevent adding several checks with different currencies.
opw-4741607
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#215435This fixes an issue where manually adjusted extra hours on an employee attendance could be overwritten when a new attendance was created for the same employee. The change helps preserve user-entered overtime values in automatic approval workflows, reducing the risk of payroll or time-tracking corrections being lost.
Original PR description
**Steps to reproduce** - Set "Extra Hours Validation" to "Automatically approved" - Create an attendance for an employee - Change the "Extra Hours" to a different value - Create another attendance…
**Steps to reproduce** - Set "Extra Hours Validation" to "Automatically approved" - Create an attendance for an employee - Change the "Extra Hours" to a different value - Create another attendance for this employee (not necessarily on the same day) - See that the "Extra hours" of the previous attendance has been recomputed, resetting the value entered by the user. **Cause** When creating an attendance for an employee, we recompute the `validated_overtime_hours` for the other attendances of this employee https://github.com/odoo/odoo/blob/cac96f5d3c391ea0d52da2e3433e7eabe07e8fb0/addons/hr_attendance/models/hr_attendance.py#L426 In case of attendances with no validation, this field is synced with the `overtime_hours` https://github.com/odoo/odoo/blob/cac96f5d3c391ea0d52da2e3433e7eabe07e8fb0/addons/hr_attendance/models/hr_attendance.py#L156 **Solution** We may still want to recompute the `validated_overtime_hours` of automatically approved attendances, since it is their default state, unlike manually approved attendances. If the `validated_overtime_hours` field is different from `overtime_hours`, it means it has been modified. In that case, we avoid recomputing it. This doesn't guarantee a manually set value will never be overriden by a change in its dependencies, but it reduces the likelihood. opw-4639230 Forward-Port-Of: odoo/odoo#207806
This fix prevents checkout errors when a website has delivery methods linked to different companies or no company. Customers can select eligible delivery options consistently, reducing failed orders caused by company assignment mismatches.
Original PR description
Description of the issue/feature this PR addresses: Error during checkout when using delivery methods with mixed company assignments. Current behavior before PR: If you create a delivery method assigned to company X, and then create another without a company (i.e., assigned to the website company or left empty), the checkout process fails when trying to select a delivery method. Steps to reproduce: 1. Create a delivery method and assign it to company X. 2. Create another delivery method with no company or assign it to the website's company. 3. Go to the website and try to place an order. 4. The checkout will fail when selecting the delivery method. Desired behavior after PR is merged: Checkout handles delivery methods consistently, even when companies are mixed or missing. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#217194 Forward-Port-Of: odoo/odoo#216515
The livechat widget page now adapts properly to mobile screens. This prevents text and layout overflow, making it easier for customers to use live chat from phones and small devices.
Original PR description
**Before this PR:** the livechat widget page was not responsive on mobile devices. This PR fixes the issue by adding the missing meta tag and adjusting font sizing and word wrapping to prevent content overflow on small screens. task-3499603 Forward-Port-Of: odoo/odoo#217127
Sales orders now calculate product unit prices correctly when a branch company uses taxes defined on its parent company. This prevents incorrect prices from appearing when fiscal positions convert price-included taxes to price-excluded B2B taxes.
Original PR description
Versions -------- - 17.0+ Steps ----- 1. Set up 10% price-included tax; 2. copy the tax to a B2B version that's price-excluded; 3. create a B2B fiscal position mapping the first tax to the second; 4.…
Versions -------- - 17.0+ Steps ----- 1. Set up 10% price-included tax; 2. copy the tax to a B2B version that's price-excluded; 3. create a B2B fiscal position mapping the first tax to the second; 4. create a $10 product using the first tax; 5. create a branch for the current company; 6. switch to the branch company; 7. set up a sale order with the fiscal position; 8. add the product to the order. Issue ----- While the line displays the correct B2B tax, the unit price displays $10, as if it was computed without any taxes, instead of a price-excluded tax. Cause ----- In the `_compute_price_unit` method, it filters out all tax records linked to the product that don't have the same company as the order line, so the parent company's tax does not get factored in. Solution -------- Rather than requiring strict equality between companies, also allow taxes that belong to a parent company of the line's company. opw-4853042 Forward-Port-Of: odoo/odoo#217012 Forward-Port-Of: odoo/odoo#216124
Landed costs are now allocated based on the quantity still available in each lot or serial number, rather than the original received quantity. This prevents overstated inventory values after some tracked items have already been sold, improving cost accuracy in stock valuation reports.
Original PR description
**Problem:** the split of the landed cost between lots doesn't take into account if a lot has no quantity left or if it has less than it's initial quantity **Steps to reproduce:** - enable the "lot &…
**Problem:** the split of the landed cost between lots doesn't take into account if a lot has no quantity left or if it has less than it's initial quantity **Steps to reproduce:** - enable the "lot & Serial Numbers" and "landed costs" settings - create a storable product, tracked by lot - in general information activate "valuation by Lot/Serial Number" - select FIFO as the category - create a request for quotation for this product for a quantity of 5 and a unit price of 10.000 - confirm and click on the receipt smart button - on the move line click on the Lots/serial number widget on the right - create 4 lots (L1 with 1 units, L2 with 2 units, L3 and L4 with 1) - save and validate the picking - create a sale order for a quantity of 2 of this product, confirm it and validate the picking - create a new service product, in "purchase" check "is a landed cost" - open accounting/vendors/bills, create a new one for the same vendor as the purhase order - add a line with the landed cost and a price of 5000 (quantity of 1) - set a bill date and save - clik on "create landed costs" - in the "transfers" field write the refernce of the receipt of the PO - open inventory/reporting/valuation and type your product in the search bar **Current behavior:** 4 lines were created : a line of 600 for L1 a line of 1200 for L2 a line of 600 for L3 a line of 600 for L4 an additional issue, is that if we now sell the 3 remaining quantity and search our product in inventory/reporting/valuation the quantity will be zero but total value will be 600 **Expected behavior:** the spliting should adapt to the remaining quantities like it does when lots are not involved (for instance when there is a landed cost linked to a PO with a quantity of 5 but only 4 of those products are still in stock the value of the landed cost valuation line linked to this product is 4/5 of the landed cost) So here it should be : no line for L1 (no remaining quantity in L1) a line of 1000 for L2 (only 1 remaining, so a third of the 3000 (3/5 * 5000)) a line of 1000 for L3 a line of 1000 for l4 **Cause of the issue:** the quantity used is the one of the initial stock move line so it doesn't take into account the current number of product in the lot opw-4828963 Forward-Port-Of: odoo/odoo#216857 Forward-Port-Of: odoo/odoo#215521
This fix prevents website editor blocks from accidentally disabling related parent interactions when content is edited or added. It helps ensure dynamic website elements, such as blog blocks and floating cards, continue working correctly after editing actions.
Original PR description
Since [1] interactions are stopped when a child element is edited. This causes issues such as not being restarted (e.g. a blog posts block is stopped right after drop when its content gets added to the DOM) - never to be restarted. This commit adapts the condition to make interactions opt-in for that feature, by implementing `isImpactedBy` in addition to `shouldStop`, and restricting this behavior to the restarting of interactions (not plain stop). Additionally, this commit also fixes the floating block's Add Card action missing id, and puts some renders into `start` rather that `setup`. [1]: https://github.com/odoo/odoo/commit/7240e2dccc441d61937bd5cebfa559dd2eb529d2 task-4367641 Forward-Port-Of: odoo/odoo#217071
Invoice emails sent in batches now use the correct language for each customer's invoice button. This prevents customers from seeing buttons translated in another customer's language when invoices are sent and printed together.
Original PR description
**Issue**: When multiple invoices with different customer languages are sent and printed together, the invoice email button may appear with an incorrect translation for some of them. **Steps to…
**Issue**: When multiple invoices with different customer languages are sent and printed together, the invoice email button may appear with an incorrect translation for some of them. **Steps to reproduce**: - Open the Accounting app - Go to Customers > invoices - Create a new invoice with a customer with its language set to German - Create a new invoice with a customer with its language set to English - Go back to Customers > invoices - Select the two invoices just created and click on action > Sent & Print and then click on the Sent & Print button - Go to Settings > Technical > Email > Emails and check the two last emails. One of them should have the invoice email button wrongly translated **Cause**: Before sending an email, it retrieve the `type_name` using the lang of the customer https://github.com/odoo/odoo/blob/28c3b9cf10488536dce5a4927fdbe8fcd6e5a839/addons/account/wizard/account_move_send.py#L596C1-L605C14 This will trigger that compute method https://github.com/odoo/odoo/blob/a6368e8a5787f3067d09d79516a2924b3f1207f0/addons/account/models/account_move.py#L841C1-L850C67 which set the `type_name` of all the records. Since the compute method only depends on move_type, it does not recompute type_name per record. As a result, all records may share the same type_name, regardless of language context. Please notice that `type_name` is used to display the invoice email button in the right language. **Solution**: Make the compute method `_compute_type_name` depending to the lang parameter, thus it will use the right `type_name` for each email to send. opw-4748741 Forward-Port-Of: odoo/odoo#216811
The Mexican electronic invoicing flow now saves the invoice sending time before contacting the external certification provider. This helps prevent duplicate CFDI documents with slightly different timestamps when a connection is interrupted and Odoo retries the send.
Original PR description
### Background In https://github.com/odoo/enterprise/pull/85026 we changed the behaviour of `l10n_mx_edi_post_time` so that it gets set during the CFDI sending process, rather than when the invoice…
### Background In https://github.com/odoo/enterprise/pull/85026 we changed the behaviour of `l10n_mx_edi_post_time` so that it gets set during the CFDI sending process, rather than when the invoice is posted. This was needed to ensure that the post time both reflects the sending time and is re-used if the invoice needs to be re-sent. ### Bug description Since then, several Mexican customers have reported that some CFDIs are sent duplicated, with a difference of a few seconds in the CFDI's Fecha. ### Analysis A disconnection might occur during sending of the CFDI. In that case, the PAC will process the CFDI, but in Odoo the transaction will be rolled back, and the `l10n_mx_edi_post_time` will be lost. When Odoo re-sends the CFDI, it will take a new `l10n_mx_edi_post_time`. ### Solution Commit before performing the API call so that the `l10n_mx_edi_post_time` gets committed to DB. opw-4780096 Forward-Port-Of: odoo/enterprise#89263 Forward-Port-Of: odoo/enterprise#89117
This fix prevents the invoice OCR process from creating duplicate supplier records when multiple documents from the same supplier are processed at the same time. It improves data quality and reduces manual cleanup for accounting teams using automated invoice extraction.
Original PR description
When the OCR parses documents from the same supplier concurrently, it can happen that it creates duplicated `res.partner` entry for it. This typically happen when the update of the documents is done…
When the OCR parses documents from the same supplier concurrently, it can happen that it creates duplicated `res.partner` entry for it. This typically happen when the update of the documents is done through the webhook. In that case, the different SQL transactions overlap each other and can't "see" the partner created by another request. In order to prevent this, a new field `is_created_by_ocr` and a unique index are introduced to be able to detect duplicated partners created by the OCR. This solution is quite costly as it requires introducing a new field and an index on `res.partner`... Other alternatives were considered: - Updating the documents through a cron instead -> introduces latency, especially on the SaaS where we can't force a cron to run immediately, even with a cron trigger. - Introducing a new model on which we could add the uniqueness model -> also costly, requires a new model just to fix the issue, and we need a way to frequently clean the records, so probably a cron on top of it (or using autovacuum, but its frequency might be too low). - Adding random delay on OCR side before calling the webhook -> introduces latency and no guarantee, it only reduces the chances of duplicated partners. - Using explicit SQL locks -> no guarantee, we only know what should be locked late in the SQL transaction (after fetching the results from the OCR), it wouldn't be very effective. Locking the whole `res_partner` table from the start of the transaction would be too restrictive and equivalent to serializing the transactions. An attempt was made in #88830, but it was deemed too complicated. task-[4904333](https://www.odoo.com/odoo/project/2068/tasks/4904333)
Fixes an issue where GSTR-2B JSON files were attached to messages but not properly linked to newly created vendor bills. Bookkeepers can now open these attachments without seeing a 404 error, improving reliability during GSTR-2B matching.
Original PR description
**Before this PR:** - The GSTR-2B JSON was attached to the message but not linked to the newly created bills (`res_id` was not set). - As a result, when a Bookkeeper user created a new GSTR-2B bill and tried to open the attachment, it raised a 404 error: `"The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again."` **After this PR:** - The issue is resolved. - During GSTR-2B matching, unattached message attachments are now properly linked to the newly created bills by updating their res_model and res_id fields. Task ID : 4831758 Forward-Port-Of: odoo/enterprise#89250 Forward-Port-Of: odoo/enterprise#86785
This fixes inconsistent data loading between the standard Point of Sale and self-ordering flows. Businesses should see fewer errors when shared POS information is needed, including receipt printing in self-ordering scenarios where session data may not always be available.
Original PR description
*: l10n_ar_pos, l10n_be_pos_sale, l10n_es_edi_tbai_pos, l10n_in_pos, l10n_pe_pos, pos_discount, pos_event, pos_hr, pos_loyalty, pos_online_payment_self_order, pos_restaurant, pos_sale, pos_self_order…
*: l10n_ar_pos, l10n_be_pos_sale, l10n_es_edi_tbai_pos, l10n_in_pos, l10n_pe_pos, pos_discount, pos_event, pos_hr, pos_loyalty, pos_online_payment_self_order, pos_restaurant, pos_sale, pos_self_order Before this commit, the loading data behavior between self-ordering and PoS was merged but not consistent. This led to issues when we try to add some data to load for both self-ordering and PoS. At the moment, we need to create two separate method to handle both cases. Now with this commit, we have consistent methods which will load data for both self-ordering and PoS. This will allow us to have a more consistent behavior and avoid issues when adding data to load. An explicit example is about `_server_version` object which is added to the `pos.session` model and used when printing the receipt. Since the session isn't always available in self-ordering, sometimes that object isn't available, leading to issues when printing the receipt. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Original PR description
*: l10n_br_edi_pos, l10n_cl_edi_pos, l10n_ec_edi_pos, l10n_ke_edi_oscu_pos, l10n_mx_edi_pos, l10n_pe_edi_pos, pos_blackbox_be, pos_iot, pos_mobile, pos_preparation_display, pos_restaurant_appointment, pos_self_order_iot, pos_settle_due Before this commit, the loading data behavior between self-ordering and PoS was merged but not consistent. This led to issues when we try to add some data to load for both self-ordering and PoS. At the moment, we need to create two separate method to handle both cases. Now with this commit, we have consistent methods which will load data for both self-ordering and PoS. This will allow us to have a more consistent behavior and avoid issues when adding data to load. An explicit example is about `_server_version` object which is added to the `pos.session` model and used when printing the receipt. Since the session isn't always available in self-ordering, sometimes that object isn't available, leading to issues when printing the receipt.