Friday, October 3, 2025
18 changes · 18.0
Resolved issues and error corrections
Fixes a checkout issue where customers could see an error after going back from payment and trying to pay again from an emptied cart. This helps keep the online shopping flow stable and avoids a confusing failure during payment retry.
Original PR description
This error occurs when trying to make a payment again from the cart. Steps to reproduce: --- - Install the **website_sale** module (with demo) - Activate **Demo** payment provider - Go to Website > Shop > Add a **Warranty** product to Cart > View cart - Pay with Demo > Pay - Click the back button(chrome navbar)(Instantly) - Now again Pay with Demo > Pay Traceback: --- `ValueError: Expected singleton: sale.order()` At [1], this error occurs because **order_sudo** is empty. This happens when there is no product 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/125fc3028debb311e9f6ad25d8c46699b77525f0/addons/website_sale/controllers/main.py#L1307-L1312 sentry-5682671428 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Manufacturing orders now correctly block a component serial number from being reused after it has already been consumed in another order. This helps preserve inventory traceability and prevents duplicate serial-number usage during production.
Original PR description
**Issue** A Manufacturing Order in *in progress* state can reuse a component with a serial number that was already consumed in another MO. **Steps to reproduce** - Create two products A and B, both…
**Issue** A Manufacturing Order in *in progress* state can reuse a component with a serial number that was already consumed in another MO. **Steps to reproduce** - Create two products A and B, both tracked by serial number. - Create a BoM for product A: 1 A requires 1 B. - Manufacture two units of product B with SNs 001 and 002. - Manufacture one unit of product A using product B with SN 001. - Create a new MO for product A: - Start the MO to set it *in progress*. - Assign product B with SN 001 again. - Click on *Produce All* and observe that no error is raised. **Cause** The method `_check_sn_uniqueness` ignores raw moves that are not yet picked ([see code](https://github.com/odoo/odoo/blob/73af26879b353cc17b2bed6ae5f0823a67f668ab/addons/mrp/models/mrp_production.py#L2634)). In this flow, the component is still unpicked when the uniqueness check runs, so the error is never triggered. The move will only be marked as picked later in `_set_qty_producing` ([here](https://github.com/odoo-dev/odoo/blob/c96ae2ffd6c8064f783e57ac157defd351e4acfb/addons/mrp/models/mrp_production.py#L1301)), triggered by [`_set_quantities`](https://github.com/odoo-dev/odoo/blob/c96ae2ffd6c8064f783e57ac157defd351e4acfb/addons/mrp/models/mrp_production.py#L2198). **Solution** Remove the restriction on picked moves when checking for SN uniqueness. This makes the behavior consistent and avoids relying on the timing of the `picked` flag. The first alternative considered was to always set `picked = True` before `_check_sn_uniqueness`, but that introduces complications since some logic still depends on the `picked` flag ([here](https://github.com/odoo-dev/odoo/blob/c96ae2ffd6c8064f783e57ac157defd351e4acfb/addons/mrp/models/mrp_production.py#L2189)). Moreover `_check_sn_uniqueness` is only called from `_button_mark_done_sanity_checks`, which in turn is only used in `pre_button_mark_done` where `_set_quantities` is called. So, if the approach is to always set `picked = True` before calling `_check_sn_uniqueness` to avoid ignoring the move, then it is clearer and more efficient to simply remove the `picked` condition altogether.
The Trial Balance PDF export now respects filters that match account group names when hierarchy and subtotals are enabled. This ensures exported reports show the expected lines when users filter by a visible group name, reducing confusion and manual workarounds.
Original PR description
Step to reproduce: - Create an account group (e.g. Group_101 from 101 to 101) - Create some AML in an account related to the previously created group (e.g. in 101501 Cash) - Go to the Trial Balance -…
Step to reproduce: - Create an account group (e.g. Group_101 from 101 to 101) - Create some AML in an account related to the previously created group (e.g. in 101501 Cash) - Go to the Trial Balance - In the Options, select "Hierarchy and subtotals" - Add a filter including your group name (e.g. Group_101) - Export to PDF Current behaviour: - no lines are displayed in the PDF as the backend uses only the account name to apply the filter Expected behaviour: - lines are displayed using group and account name to filter Cause: Filter was applied only on account name Solution: If hierarchy is enabled, display accounts where filter matches either account or group. Group_id was a stored field until 18.0 and is now computed. The compute method use a SQL query. To avoid a second quite similar query, this commit creates a method called in both places which compute and execute the query. This method is called at several time, including: - the creation of a record, before it is saved to DB. This implies the method should be able to compute groups for code of account not in DB. - the search of an account based on his group. Which requires looking at all accounts. Those constraints imply the needs to compute a query depending on parameters. In order to compute groups from account code of account not in DB, using `unnest` or `VALUES` is mandatory. However, a `Query` object couldn't be used here because the use of `unnest` (or `VALUES`) requires a composed alias with () which is "not a valid identifier". This led to the use of several SQL objects. opw-4906593 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The partner ledger now includes reconciled accounting entries that have no partner when calculating opening balances. This prevents mismatches between opening balances and totals when users review reports across different financial years.
Original PR description
### Issue: The partner ledger does consider lines without partners when calculating the initial balance. ### Steps to reproduce: - Create an invoice in 2025 - Create an entry in 2025 without partner…
### Issue: The partner ledger does consider lines without partners when calculating the initial balance. ### Steps to reproduce: - Create an invoice in 2025 - Create an entry in 2025 without partner for the same amount - Reconcile the two - Open the partner ledger for 2025, everything is correct - Change the dates to 2026, the amount of the initial balance ignores the entry but not the totals ### Cause: The method `_get_sums_without_partner` is called for the totals, but not for the initial balance. Its purpose is to add the amounts of the lines without partners that were reconciled with lines with a partner. ### Solution: Call `_get_sums_without_partner()` in `_get_initial_balance_values()` add the results before returning the initial balances. As this is the same logic as `_query_partners()` we create a new method. This method needs to be called with the dates of the initial balance in the options. So we create a duplicate of the options and input the new dates options. opw-5068790 Forward-Port-Of: odoo/enterprise#95881
DHL delivery insurance settings are now reflected in shipping price estimates and shipment creation. This helps businesses avoid uninsured shipments when insurance was configured and gives users a clear error if insurance is unavailable for a route.
Original PR description
**PROBLEM** Insuring a delivery using the dhl carrier don't work. It doesn't affect the estimated rate of the delivery, and the shipment created when validating the delivery order isn't insured.…
**PROBLEM** Insuring a delivery using the dhl carrier don't work. It doesn't affect the estimated rate of the delivery, and the shipment created when validating the delivery order isn't insured. **STEP TO REPRODUCE** 1. Install the `delivery_dhl_rest` and the `l10n_be` modules (we will use the be demo company). 2. Set the insurance percentage of the dhl be delivery method to 100%, and set the region to Europe (the demo data is incorrect), and activate the debug (click the "No Debug" smart button to activate the log of requests). 3. Switch to the be company. 5. Create a sale order, with a customer located in Belgium, and add shipping using the dhl method. 6. Go to the delivery order, and validate it. 7. Go to settings/Technical/Logging and look at the rating_request and shipment_request, notice there is no information about insurance. **CAUSE** We don't send any info about insurance in the api requests. **FIX** Computing and sending the insured amount, only if the insurance percentage is not null. If the package can't be insured between the origin and the destination, a error message will be displayed when updating the delivery price. **TESTS PROBLEM/FIX** The localization of `your_company` was not recognized by DHL, leading to the DHL api returning a 0 delivery price. Switching the localization to Eghezee, Rue du Laid Burniat 5 fixes this. Assertion regarding the delivery price were restored. The picking date could sometimes be refused by DHL (stop working after arround 4/5 PM). Changing the picking date to, two day after, at noon works. `test_01_dhl_basic_be_domestic_flow` was modified to also test domestic shipment insurance in addition of the basic flow. Some code in it was refactor into inner function to avoid boilerplate. Adding `INSURED_RATE_MOCK_RESPONSE` to mock response in test_01. opw-4989281 Forward-Port-Of: odoo/enterprise#93105
Event registration emails, such as badge or QR code messages, will no longer be scheduled once an event has finished. This prevents attendees from receiving outdated operational communications after the event, while still allowing appropriate post-event messages to be sent.
Romanian SAF-T reporting now keeps partners with a zero balance so each partner can still be identified correctly as a customer or supplier. This helps avoid validation errors in Romanian tax reporting while also improving report query performance and excluding irrelevant zero-value ledger lines where appropriate.
Original PR description
We need to know for each partner if it is a customer or a supplier, even more for Romania[^1] where it is enfored and validated. > 1. If the element SD.P.22 CustomerID is reported with value ”0”…
We need to know for each partner if it is a customer or a supplier, even more for Romania[^1] where it is enfored and validated. > 1. If the element SD.P.22 CustomerID is reported with value ”0” (zero), then the element SD.P.23 SupplierID must be different from ”0” (zero), meaning the identity of the partner from which the purchase was made (conventionally considered ”supplier”) is reported. Else if SD.P.22 CustomerID AND SD.P.23 SupplierID are concomitantly equal to ”0” (zero), then is return a semantic validation error. (CustomerID and SupplierID can not be concomitantly 0 (zero)) In order to fix this, we don't use the Partner Ledger anymore to query the balance per partner because it is removing the partners with 0 balance automatically. To keep it simple, we query manually and locally, allowing to reduce the number of queries from 3 to 1 for that part. For the performance, the `|=` operator done in a loop has also been removed, keeping the time complexity in `O(n)` instead of `O(n²)`. opw-5122910 [^1]: https://www.anaf.ro/anaf/internet/ANAF/despre_anaf/strategii_anaf/proiecte_digitalizare/saf_t
This fix prevents cancelled manufacturing work orders created during backorders from being assigned an expected duration as if work had been performed. This helps keep manufacturing cost calculations and production records accurate when partial quantities are split into backorders.
Original PR description
### Issue: In this bug, the workorder duration being set to duration_expected is causing issues in backorder. To reproduce: 1- Create a Bill of Materials with at least two operations at two work…
### Issue: In this bug, the workorder duration being set to duration_expected is causing issues in backorder. To reproduce: 1- Create a Bill of Materials with at least two operations at two work centers 2- Create a manufacturing order and confirm it. 3- Complete the first operation and edit the quantity on the second operation so there is a backorder for the remaining quantity. 4- In the second work order, the first operation is cancelled, Finish the 2nd operation 5- As you can see, the cancelled operation duration is set to expected duration which is wrong. ### Cause: This issue is caused because of: https://github.com/odoo/odoo/blob/8f0e40286da7b144bfa17880a257406dd8585e57/addons/mrp/models/mrp_production.py#L1774-L1779 Which if work.order.state is `cancel`, the duration will set to `duration_expected`. This will eventually cause issue here: https://github.com/odoo/odoo/pull/222075/commits/8f0e40286da7b144bfa17880a257406dd8585e57#diff-fac872ffb03b811c4976eb2e52991ec544265332df814d92cfda658a5b917423L348 which is fixed by not making the state into `progres` if the state is `cancel`. But that doesn't fix the fact that the cancelled workorder has duration set and it might cause inconsistencies in manufacturing costs. related: #222075 opw-4931653
Customers who quickly used the browser back button after starting an express checkout could hit an error when trying to pay again from an emptied cart. This fix prevents that broken navigation path, making repeat payment attempts from the cart behave more reliably.
Original PR description
This error occurs when trying to make a payment again from the cart. Steps to reproduce: --- - Install the **website_sale** module (with demo) - Activate **Demo** payment provider - Go to Website > Shop > Add a **Warranty** product to Cart > View cart - Pay with Demo > Pay - Click the back button(chrome navbar)(Instantly) - Now again Pay with Demo > Pay Traceback: --- `ValueError: Expected singleton: sale.order()` At [1], this error occurs because **order_sudo** is empty. This happens when there is no product 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/125fc3028debb311e9f6ad25d8c46699b77525f0/addons/website_sale/controllers/main.py#L1307-L1312 sentry-5682671428
Manufacturing orders without a linked bill of materials can now open their overview without triggering an error. This helps users review completed manufacturing work even when the order was created manually or without a formal BoM.
Original PR description
Steps to reproduce: - Create a storable product “P1” - Create a manufacturing order to produce one unit of P1: - add any component - Mark the MO as done - Try to open the MO overview Issue: An error is raised because the MO has no BoM. But in the function we try to compute the missing quantity in the BoM's UoM, but since no BoM is linked, there is no UoM available. Error message: "The unit of measure Unit defined on the order line doesn't belong to the same category as the unit of measure %(product_unit)s defined on the product. Please correct the unit of measure defined on the order line or on the product. They should belong to the same category." Fix: Skip the computation of missing BoM quantities when no BoM is linked, allowing the MO overview to be opened without error. opw-5112132 Opw-5105544 Opw-5119897
Dutch e-invoices now include only one customer identifier, using the Peppol endpoint instead of adding both the endpoint and customer reference. This prevents validation errors when sending Netherlands NLCIUS invoices and refunds, improving reliability for compliant electronic invoicing.
Original PR description
**Steps to reproduce:** - Install Accounting and Contacts - Use a company based in Netherlands - In Contacts, configure the company: * eInvoice format: Netherlands (NLCIUS) * Peppol endpoint:…
**Steps to reproduce:**
- Install Accounting and Contacts
- Use a company based in Netherlands
- In Contacts, configure the company:
* eInvoice format: Netherlands (NLCIUS)
* Peppol endpoint: [anything]
* Reference ("Sales & Purchase" tab): [anything]
- Create a Dutch contact with a peppol endpoint and a reference
- Create an invoice for the Dutch contact
- Confirm the invoice
- Send the invoice
- Check the generated NLCIUS xml
**Issue:**
In the XML there are 2 "<cac:PartyIdentification>" for each party.
One with the peppol endpoint and one with the partner reference.
For "<cac:AccountingCustomerParty>", only one Party Identification is allowed, triggering the following validation error:
[UBL-SR-16] Buyer identifier shall occur maximum once
**Cause:**
By default (UBL 2.0), the partner reference is used as Party Identification.
But in the case of a Dutch partner, the peppol endpoint is also added in BIS3.
**Solution:**
Only use the peppol endpoint for Dutch partners.
opw-5059667
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis fixes an issue where changing inventory value for FIFO products could update the product cost using an outdated manual cost instead of the actual inventory valuation. Businesses will now see product costs stay aligned with stock value after revaluation, improving inventory and accounting accuracy.
Original PR description
**Steps to reproduce:** - create a storable product with fifo category - update the cost to 200 - click on the on hand smart button and add a quant of 1 quantity - update the cost to 300 - click on…
**Steps to reproduce:** - create a storable product with fifo category - update the cost to 200 - click on the on hand smart button and add a quant of 1 quantity - update the cost to 300 - click on the on hand smart button and update the quantity to 2 - the value should be 500, which makes a 250 value per product - open Inventory/valuation and search your product - group by product, select your product and click on "+" icon to open the revaluation widget - add 200 (so +100 per unit) - go back to the product form **Current behavior:** the cost is now at 400 **Expected behavior:** the cost should be at 350 (250 + 100) If we change the standard_price we should change it in accordance with the valuation **Cause of the issue:** In action_validate_revaluation, during the update of the standard_price, the current standard_price (set by the user and disconnected from the valuation) is used in the computation. https://github.com/odoo/odoo/blob/5118f7cb80744f901d7028dc75c29aba9591b83b/addons/stock_account/wizard/stock_valuation_layer_revaluation.py#L127 opw-5028848
This fix prevents a branch company's default tax from being automatically added back to products when a different tax was intentionally selected under the parent company. It helps ensure product tax settings stay accurate for businesses using company branches.
Original PR description
**Issue description:** The logic introduced in #127196 adds default taxes from "other" companies to products created without a specific company. However, because child companies (branches) share…
**Issue description:** The logic introduced in #127196 adds default taxes from "other" companies to products created without a specific company. However, because child companies (branches) share taxes with their parent company, when creating a new product using the parent company and setting a specific tax (different from the default), the default tax was incorrectly added back to the product. This happened because the logic considered the branch an "other company" and applied its default tax. **FIX:** Exclude branch companies from the domain when we set the default tax of other companies on the product. **Steps to reproduce:** 1. Create a branch company. (It will automatically have the same default tax as its parent). 2. With the parent company selected, create a new product, leaving the 'Company' field empty, and change its sales tax to any tax other than the default, and save. 3. Notice that the default tax is set again on the product. opw-5094415 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229066
This fixes an issue where a manually adjusted delivery date on an invoice could be reset after changing product quantities and confirming the invoice. The change helps preserve user-entered delivery information and avoids unexpected invoice updates during normal sales workflows.
Original PR description
Versions -------- - 17.0+ Steps ----- 1. Have a sale order with deliverable products & no payment terms; 2. confirm order & validate delivery; 3. create an invoice; 4. modify the delivery date; 5.…
Versions -------- - 17.0+ Steps ----- 1. Have a sale order with deliverable products & no payment terms; 2. confirm order & validate delivery; 3. create an invoice; 4. modify the delivery date; 5. save changes; 6. change product quantity of a line & confirm invoice. Issue ----- The delivery date got reset. Cause ----- The `_compute_show_delivery_date` method gets called, which triggers the recomputation of the `_compute_delivery_date` due it the latter having `line_ids.sale_line_ids.order_id` as its `depends`. Due to the way how `depends` works, if any of the fields in the record chain gets modified, the compute gets triggered. In this case, because we modified a `line_ids` record by changing the quantity, it will therefore recompute the delivery date, overwriting the custom value. Solution -------- As we only want the delivery date to be recomputed when the `effective_date` on the order changes, we should add it to the `depends` to trigger the compute in that scenario. In other scenarios, e.g. modifying the move or one of its lines, we don't want to trigger a recompute, which we can achieve by always including `delivery_date` via `_get_protected_vals` on create/write. opw-4996654 Forward-Port-Of: odoo/odoo#223946
This fix ensures that when a valid incoming email is received from a contact after a prior bounce, their bounce status is properly cleared. This helps prevent users or contacts from being incorrectly treated as unreachable and avoids related mail channel access issues.
Original PR description
Incoming bounce email linked to a partner in the db is incrementing (in `message_receive_bounce`) the message_bounce value during the handling of the bounces (in `_routing_handle_bounce`) If later, an email linked to a partner existing in the db (and having a message_bounce > 0) is received (and not bounce). The `_routing_reset_bounce` is called to reset the message_bounce. However, prior to this fix, due to not normalizing the `email_from` contained in the `msg_dict`, well, the record having this value was never found and thus, not reset to 0. In 4935208, some of the user were unlinked for mail.discuss.channel when replying to one of the received email. opw-4935208 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#227273
This fix prevents an unreserve error that could block validation of delivery backorders in warehouses using 2-step delivery flows with lot-tracked products and packages. Businesses can complete affected deliveries more reliably without manual workarounds.
Original PR description
# Problem Unreserve issue preventing users from validating a delivery order with 2-step delivery warehouse configuration. Introduced in the following commit:…
# Problem Unreserve issue preventing users from validating a delivery order with 2-step delivery warehouse configuration. Introduced in the following commit: https://github.com/odoo/odoo/commit/13567aa27250f5798bbe42648eeac82241dbb780 # Steps to reproduce on the runbot: - Activate packages - Edit the warehouse to deliver in 2-steps - Create a product tracked by lot - Create two lots with 5 qty each - Create a sale order with 10 qty and confirm - Check the delivery order and assign: => 2 units to lot1 and create a pkg for it => 1 units to lot1 without pkg => 3 to lot2 without package - Validate the delivery and create a backorder - go to pick backorder and try to validate - Unreserve issue pops up - For further details, check: [#225948](https://github.com/odoo/odoo/issues/225948) # Solution: Conditional subtracting limited to new lines only. Task ID: opw-5086289 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229420
Trial Balance PDF exports now correctly show results when users filter by an account group name while hierarchy is enabled. This ensures exported reports match what users expect and prevents missing lines caused by filtering only on account names.
Original PR description
…xported pdf #### Issue In the Trial Balance when using a filter if hierarchy is enabled, the exported report filters only on the account name, not on the group name. #### Step to reproduce: - Create…
…xported pdf #### Issue In the Trial Balance when using a filter if hierarchy is enabled, the exported report filters only on the account name, not on the group name. #### Step to reproduce: - Create an account group (e.g Group_101 from 101 to 101) - Create some AML in an account related to the previously created group (e.g. in 101501 Cash) - Go to the Trial Balance ( Accounting > Reports > Audit Reports > Trial balance ) - In the Options select "Hierarchy and subtotals" - Add a filter including your group name (e.g. Group_101) - Export to pdf #### Current behavior: - No lines are displayed in the pdf as the backend uses only the account name to apply the filter #### Expected behavior: - Lines are displayed using account name and group name to filter #### Cause: - Filter was applied only on account name #### Solution: - If hierarchy is enabled, display accounts where filter appears on either account or group opw-4906593 Forward-Port-Of: odoo/enterprise#90403
SAF-T reports now include customers and suppliers even when their balance is zero, helping Romanian filings pass required partner identity checks. The change also streamlines how partner balances are gathered, reducing unnecessary processing during report generation.
Original PR description
We need to know for each partner if it is a customer or a supplier, even more for Romania[^1] where it is enfored and validated. > 1. If the element SD.P.22 CustomerID is reported with value ”0”…
We need to know for each partner if it is a customer or a supplier, even more for Romania[^1] where it is enfored and validated. > 1. If the element SD.P.22 CustomerID is reported with value ”0” (zero), then the element SD.P.23 SupplierID must be different from ”0” (zero), meaning the identity of the partner from which the purchase was made (conventionally considered ”supplier”) is reported. Else if SD.P.22 CustomerID AND SD.P.23 SupplierID are concomitantly equal to ”0” (zero), then is return a semantic validation error. (CustomerID and SupplierID can not be concomitantly 0 (zero)) In order to fix this, we don't use the Partner Ledger anymore to query the balance per partner because it is removing the partners with 0 balance automatically. To keep it simple, we query manually and locally, allowing to reduce the number of queries from 3 to 1 for that part. For the performance, the `|=` operator done in a loop has also been removed, keeping the time complexity in `O(n)` instead of `O(n²)`. opw-5122910 [^1]: https://www.anaf.ro/anaf/internet/ANAF/despre_anaf/strategii_anaf/proiecte_digitalizare/saf_t Forward-Port-Of: odoo/enterprise#95896