Wednesday, August 6, 2025
14 changes · saas-18.3
Enhancements to existing features
This update ensures Saudi e-invoicing registration files use the correct parent or branch company details required by ZATCA. It also prevents invoices from being posted with a mismatched journal company and improves test coverage for Saudi B2B invoicing flows.
Original PR description
…nches Description of the issue/feature this PR addresses: The current implementation of generating CSR files for EDI doesn't differnetiate between parent companies and branches. ZATCA, however,…
…nches Description of the issue/feature this PR addresses: The current implementation of generating CSR files for EDI doesn't differnetiate between parent companies and branches. ZATCA, however, expects slightly different information depending on whether the company is a branch or a parent. This also includes a refactor of the tests for l10n_sa_edi. Current behavior before PR: The Organization Name, Organization Unit Name, and Organization Identifier of whichever company on the journal were being sent to ZATCA. You could also Onboard/Re-Onboard a journal in different company. The unit tests for EDI document generation were primarily using a partner based in the US, which meant that the b2b invoicing main flow was not being properly tested Desired behavior after PR is merged: Parent/Standalone Company: - Organization Name: The name of the company - Organization Unit Name: First 10 characters of the VAT - Organization Identifier: The VAT of the company Branch: - Organization Name: The name of the parent - Organization Unit Name: The name of the branch - Organization Identifier: The VAT of the parent - Prevent users from posting invoices, credit notes, or debit notes whose invoice company doesn't match the journal company - The tests are easier to read and they test the b2b flow correctly opw-4794842 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#221109 Forward-Port-Of: odoo/odoo#213518
Bank reconciliation can now automatically create separate matching rules even when they use the same account. This helps accountants handle different recurring payment descriptions, such as rent and location charges, without manually setting up extra rules.
Original PR description
Backport of: https://github.com/odoo/enterprise/pull/89358 - Before this commit: The automatic creation of reco model is constrained by company, account and journal. So if the reco model with this…
Backport of: https://github.com/odoo/enterprise/pull/89358
- Before this commit: The automatic creation of reco model is constrained by company, account and journal. So if the reco model with this config exists then new reco model will not be created.
- After this commit: Now we have removed the constraint entirely. Because we want to have more than one reco model with the same account in it.
- Example: Suppose we have 3 statement lines with 'Rent' as a label in them, and 3 statement lines with 'Location' as a label in them.
So before this commit when user sets same account on the first two lines with 'Rent' label, will create a new reco model with
'{Common substring} - {account code}' as a model name and common substring from labels of both lines will be set as a
match_label_param of the model. And then user next set that same account on the first two lines with 'Location' label, will not
create a new reco model automatically, because for this config one reco model already exists.
But now after this commit when user sets same account for first two lines with 'Location' label will also create a new reco
model automatically with '{Common substring} - {account code}' as a model name and common substring from labels of both
lines will be set as a match_label_param of the reco model.
Task: 4876374Resolved issues and error corrections
Sales orders are now checked with the proper locking rule before being locked. This restores previously missing behavior so subscription-related and similar orders are not locked when they should remain editable.
Original PR description
The diff from this commit was introduced in the past up until saas-17.1, to prevent locking of subscription sales orders. https://github.com/odoo/odoo/pull/159863 However, the forward porting commits after saas-17.2 are missing this diff. https://github.com/odoo/odoo/pull/159993/files Few months after the commits were merged, someone mentioned about this diff being missing, but no actions were taken afterwards. This commit applies the missing diff. --- In another [bugfix](https://github.com/odoo/enterprise/pull/91339), which is dependent on this , we decided to not lock SOs from FSM tasks, taking similar approaches as how Subscription Orders process it, utilizing the `_should_be_locked()` function. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#221617 Forward-Port-Of: odoo/odoo#221281
Payment receipt PDFs now show the actual foreign-currency payment amount instead of the company-currency amount. This prevents confusing or misleading receipt totals when invoices are paid and reconciled in another currency.
Original PR description
**Steps to reproduce**: 1. Install the `accounting` module. 2. Activate a foreign currency form `Accounting -> Configuration -> Currencies` and fetch its exchange rate. <img width="599" height="267"…
**Steps to reproduce**: 1. Install the `accounting` module. 2. Activate a foreign currency form `Accounting -> Configuration -> Currencies` and fetch its exchange rate. <img width="599" height="267" alt="image" src="https://github.com/user-attachments/assets/34e7c719-20f7-4cd0-a1d6-0e94764461ba" /> 3. Create an invoice using the company’s default currency (e.g., USD). 4. Register a payment using the foreign currency (e.g., VES). 5. Reconcile the payment with the invoice. 6. Print the payment receipt PDF. **Observations**: In the printed PDF, under the `Amount In Currency` column, the amount is incorrectly displayed. For example, suppose `1 USD` = `100 VES`. - An invoice of `100 USD` is created. - A payment of `10,000 Bs` is registered (equivalent to 100 USD). - When the payment receipt is printed, the output appears as: ``` | Invoice Number | Reference | Amount In Currency | Amount | |--------------------|-------------------|--------------------|-------------| | INV/2025/00001 | | | 100.00 USD | | PBNK1/2025/00001 | INV/2025/00001 | -100.00 Bs | -100.00 USD | ``` Here, the `Amount In Currency` for the payment line shows **100 Bs** instead of the correct **10,000 Bs**. **Issue**: The payment receipt uses the `_get_reconciled_invoices_partials()` method to fetch details about reconciled invoices. However, the report incorrectly uses the `amount` field (in company currency) for the `Amount In Currency` column, leading to this mismatch. **Solution**: The report now uses `(debit/credit)_amount_currency` instead of `amount` to correctly reflect the foreign currency values in the `Amount In Currency` column. opw-4898706 Forward-Port-Of: odoo/odoo#221964 Forward-Port-Of: odoo/odoo#219439
Website visitors no longer lose selected event filters when moving to another results page or running a search. This keeps event browsing consistent and prevents users from having to reapply filters repeatedly.
Original PR description
**Issue**:
In the event page on the website, filters are lost when changing pages.
**Steps to reproduce**:
- Ensure enough events exist with multiple type for a category and sufficient quantity (e.g., 24 per type)
- Go to the website app > events:
- Filter events by a type
- Click "Next page" or perform a search
- The filter is lost
**Cause**:
Commit [7b188cf](https://github.com/odoo/odoo/commit/7b188cfedcdd14d2eef12da54084e46f81221350) introduced slug-based filtering. However, the implementation was not fully complete: the slug_tags were not retained in the `url_args` of the pager. As a result, when changing pages, the generated URLs lacked the necessary slug information, causing filters to be lost and search results to reset unexpectedly.
**Solution**:
Hardcode the slug_tags directly into the URL. This way, the slug_tags are preserved without modifying the XML files.
opw-4887189The invoicing dashboard now uses customer credit notes, rather than vendor credit notes, in key sales reports such as top countries, categories, products, and salespeople. It also excludes draft and cancelled entries when users open top invoices, improving the accuracy of dashboard figures and follow-up lists.
Original PR description
Problem:- In Invoicing Dashboard, in some parts we get wrong values because of wrongly set domain making dashboard consider Vendor Credit Note instead of Customer Credit Note. Before this commit:- - In Invoicing Dashboard, reports Top Countries, Top Categories, Top Products, and Top Salespeople considers Customer Invoice and Vendor Credit Note. - When clicked on Top Invoices, moves in draft and cancel state are also displayed. After this commit:- - In Invoicing Dashboard, reports Top Countries, Top Categories, Top Products, and Top Salespeople considers Customer Invoice and Customer Credit Note only. - When clicked on Top Invoices, moves in draft and cancel state are not displayed. task-4851920 Forward-Port-Of: odoo/odoo#221873 Forward-Port-Of: odoo/odoo#213723
Creating a sales order item from a project task now automatically fills the related company and product taxes. This prevents missing tax information in multi-company setups and helps keep billable project work correctly priced and invoiced.
Original PR description
## Short functional explanation of the error When clicking on "create and edit" on a Sales Order Item field in a task, the company field is left blank. As a result, the taxes linked to the product…
## Short functional explanation of the error When clicking on "create and edit" on a Sales Order Item field in a task, the company field is left blank. As a result, the taxes linked to the product don't appear. ## Reproduction Steps 1. Install the modules sales, timesheet and project. 2. Make sure that you have at least 2 different companies in the settings. 2. Click on the project app and create a new project. Check the Billable and Timesheets boxes. 3. Create a task and click on it. Set a customer: the field "Sales Order Item" should appear. 4. Click on the "Sales Order Item" field. Type random letters and click on "create and edit". 5. Select a product that has at least one tax. ### Expected behavior The company field should be filled as soon as we click on the create and edit button, and the taxes field should be filled with the taxes of the product as soon as we select said product. ### Unexpected behavior The company and taxes field remain empty. ## Origin of the issue Some fields were set at "default_." __ opw-4904861 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#221342
Products received from purchase orders with a 100% discount are now valued at zero instead of using their default cost. This prevents overstated inventory values and keeps accounting accurate for fully discounted supplier receipts.
Original PR description
**Current behavior:** Receiving some real-time valuated, non-standard cost product from an order with 100% discount will value the product at its `standard_price`. **Expected behavior:** Valuated at 0. **Steps to reproduce:** 1 Create an average cost, real-time valuated product with non-zero `standard_price` 2. Create a purchase order for some of the avco product, confirm and receive 3. Create and post the bill -> check valuation from inventory **Cause of the issue:** Currently from 6ba1106ae we will ignore a 100% discount in calculating `_get_gross_unit_price()`. **Fix:** Return 0 in this method if we are in a 100% discount case. opw-4862883 Forward-Port-Of: odoo/odoo#220998 Forward-Port-Of: odoo/odoo#217726
Opening a payment link for an unpaid invoice could fail because the payment amount was handled incorrectly. This fix ensures the amount is converted properly, allowing customers to access payment links without an error.
Original PR description
Versions
--------
- 18.0+
Steps
-----
1. Go to Accounting/Invoicing;
2. open an unpaid invoice;
3. generate payment link;
4. open payment link.
Issue
-----
Traceback on a `ValueError`.
Cause
-----
Commit 5697493e00915 added a `amount and float('amount')`, trying to convert a string into a float.
Solution
--------
Convert the variable into a float instead.
opw-4996783
Forward-Port-Of: odoo/odoo#221914This fixes an inventory issue where changing a product's on-hand quantity to zero did not save correctly after refreshing the page. Businesses can now accurately clear stock quantities for products, improving inventory reliability and avoiding misleading availability figures.
Original PR description
<b>Steps to reproduce:</b> 1) Install stocks 2) Create a product variant with storable true 3) Change the on-hand quantity to some positive value and save 4) Now update the on-hand quantity to 0 and…
<b>Steps to reproduce:</b> 1) Install stocks 2) Create a product variant with storable true 3) Change the on-hand quantity to some positive value and save 4) Now update the on-hand quantity to 0 and refresh the page <b>Issue:-</b> The on-hand quantity doesn't update to 0. <b>Cause:-</b> When the user manually changes the on-hand quantity, an inverse method `_inverse_qty_available` is triggered to create a new stock.quant, but because of this condition, no new quant is created. https://github.com/odoo/odoo/blob/b2e845c46a0b152899ee630770abc15751493069/addons/stock/models/product.py#L236-L238 As a result, the qty_available value will remain same because it will be updated based on the stock.quant's record from the below line. https://github.com/odoo/odoo/blob/b2e845c46a0b152899ee630770abc15751493069/addons/stock/models/product.py#L185 https://github.com/odoo/odoo/blob/b2e845c46a0b152899ee630770abc15751493069/addons/stock/models/product.py#L217 <b>Solution:-</b> We can resolve this issue by modifying the condition in the inverse method to create a new stock.quant if the on-hand qty is 0 or more. Also skip creating a SM with 0 quantity when applying inventory from `_inverse_qty` opw-4761491 Forward-Port-Of: odoo/odoo#208739
Changing the journal on a payment no longer overwrites the selected partner with the journal company's partner. This prevents unwanted data changes and lets users manually choose the correct partner when preparing payments.
Original PR description
Reproducing steps: - Create a payment and select a journal. - Partner is set to the journal's company partner. - Try to change the journal manually. Before this PR: - Partner is reset to the journal's company partner. - Cannot assign a different journal for the journal's company partner. After this PR: - Removed unwanted compute dependency. - Partner is no longer reset and can be changed manually. opw-4769153 Forward-Port-Of: odoo/odoo#221867
Employees can now access the relevant subtasks in private projects when they should have permission. The update also strengthens the related test coverage so this access rule is checked more reliably in future releases.
Original PR description
same as https://github.com/odoo/odoo/commit/0d75ce1d3912bbd94c5ce3bc199b40134dfab69f but different field `has_template_ancestor`. the test was fragile and didn't cover the case correctly, it was improved in this commit. opw-4980443 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The website rental shop now keeps original list prices hidden for zero-priced products that are unavailable for sale. This prevents customers and search engines from seeing prices that should only be visible while editing the website.
Original PR description
Versions
--------
- 17.0+
Steps
-----
1. Create a pricelist setting product prices to zero;
2. configure website to make zero-priced products unavailable for sale;
3. go to /shop as a public user;
4. open the product page of a zero-priced product;
5. open the browser console;
6. use `document.querySelector('.css_non_editable_mode_hidden .oe_currency_value')`
Issue
-----
The query returns an element with the product's original list price.
Cause
-----
In `website_sale`, this element is part of a `t-if` that only gets rendered when `editable` is `True`. A `website_sale_renting` override changes the conditional to `not combination_info.get('is_rental')`.
Solution
--------
Instead of replacing the `t-if` attribute in the override, add `and not combination_info.get('is_rental')` to it, ensuring it remains hidden outside of editable mode.
opw-4865141
Forward-Port-Of: odoo/enterprise#91728
Forward-Port-Of: odoo/enterprise#91112Rejecting an UrbanPiper order in Point of Sale now completes without triggering an unexpected error. This improves reliability for staff handling online orders and keeps the POS order flow stable after a rejection.
Original PR description
Steps to reproduce: --- - Configure UrbanPiper in any POS configuration. - Open this POS and place a test order. - Attempt to reject the order. Issue: --- - A traceback occurs when rejecting the order. Cause: --- - The `removeOrder` function was being called unnecessarily, even though it is already handled by `deleteOrders`. Fix: --- - Removed the redundant call to `removeOrder`. - Additionally, called `afterOrderValidation` and `setSelectedOrder` to properly reset the state after rejection. task-4965076 Forward-Port-Of: odoo/enterprise#91116