Friday, June 27, 2025
22 changes · 18.0
Enhancements to existing features
This update makes Odoo’s automated browser tests more predictable when a test action reloads or leaves a page. It reduces flaky test results across several business areas, helping teams validate changes with more confidence before release.
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
Automated test journeys across several Odoo apps now clearly mark the steps that intentionally reload or leave a page. This makes the test suite more reliable and easier to maintain, reducing the chance of false failures during quality checks.
Original PR description
Resolved issues and error corrections
A typo in a Belgian tax data value was corrected from an invalid-looking decimal format to the intended value. This helps ensure Belgian localization tax setup data is accurate and avoids confusion or potential configuration issues.
Miscellaneous changes
Current behavior before commit: The issue occurs when the product is a kit. The Procurement: run scheduler scheduled action updates some fields, triggering the _compute_purchase_price method. Within _compute_purchase_price, the method _compute_average_price is called with the company context of the sales order line (SOL). Company Context https://github.com/odoo/odoo/blob/a823c4ef6962672fe68726682e94ff82db211772/addons/sale_stock_margin/models/sale_order_line.py#L14 Method Call https://g
Original PR description
Current behavior before commit: The issue occurs when the product is a kit. The Procurement: run scheduler scheduled action updates some fields, triggering the _compute_purchase_price method. Within…
Current behavior before commit: The issue occurs when the product is a kit. The Procurement: run scheduler scheduled action updates some fields, triggering the _compute_purchase_price method. Within _compute_purchase_price, the method _compute_average_price is called with the company context of the sales order line (SOL). Company Context https://github.com/odoo/odoo/blob/a823c4ef6962672fe68726682e94ff82db211772/addons/sale_stock_margin/models/sale_order_line.py#L14 Method Call https://github.com/odoo/odoo/blob/a823c4ef6962672fe68726682e94ff82db211772/addons/sale_stock_margin/models/sale_order_line.py#L18 During recursion in `_compute_average_price`, the company context incorrectly reverts to the global company instead of preserving the original company context from the initial call. Recursive call https://github.com/odoo/odoo/blob/a823c4ef6962672fe68726682e94ff82db211772/addons/mrp_account/models/product.py#L77 Since the product is a kit, its cost is derived from its components. However, due to the incorrect company context switch, the purchase price is incorrectly set to 0 (because the product does not exist in the global company). This distorts sales margins in ongoing sales orders. Root Cause: The stock_moves passed into the method have env.company set to Company 1. At https://github.com/odoo/odoo/blob/a823c4ef6962672fe68726682e94ff82db211772/addons/mrp_account/models/product.py#L66 bom_lines are extracted, inheriting the environment from stock_moves. As a result, _compute_average_price is executed within the context of Company 1, which may lead to incorrect computations when the intended company context is different. Fix: Ensure that stock_moves is explicitly passed into the method with the correct company context. This guarantees that the company context remains consistent throughout the execution, preventing unintended company switching. opw-4222976 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#215785 Forward-Port-Of: odoo/odoo#192890
In this commit, we add expectUnloadPage to steps that require it to explicitly declare that the step will cause the page to be unloaded.
Exports now use the correct translated display value for selection fields whose options are generated by a function. This prevents users from receiving raw or incorrect values in exported files, improving data accuracy for multilingual exports.
Original PR description
Whenever selection field have the any function in selection value at that time while export it not export associated language ``value``. For Fixing this, according to [this](https://github.com/odoo/odoo/blob/a7a5470596b1d08311d87931c0ef24217087f729/odoo/fields.py#L2960) adding this condition to get the correct values. opw-4882812 upg-2985436 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Point of Sale receipts now show the cashier who completed the payment, even if the cashier was changed during checkout. This ensures receipts accurately reflect who served the customer and avoids confusion in cashier tracking.
Original PR description
**Problem:** When cashier A is assigned to an order, then changed during the payment screen process to cashier B, the receipt will display Served by cashier A. It should be Served by cashier B as this is the one that closed the order. This used to work until 18.0. **Steps to reproduce:** - Add some employees to your PoS, using pos_hr - Select one of them, then change to another one during the payment screen, before paying - Pay for it, the receipt screen still displays the first cashier **Why the fix:** The receipt should first display the current cashier, not the order's cashier. It was done the other way around before this commit. We now first display the session's cashier, then if not available we display the order's cashier. opw-4868038
Product units of measure are now hidden across inventory, manufacturing, sales, purchasing, and point of sale screens when the Units of Measure feature is turned off. This reduces unnecessary information and avoids confusion for users who do not use multiple units.
Original PR description
**Description of the issue/feature this PR addresses:** Should not show product uom when the feature "Units of Measure" is not activated  --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes an issue where empty text or chart fields in spreadsheet list formulas could appear as a false value instead of being blank. Business users will see cleaner and more accurate spreadsheet reports when list data contains empty fields.
Original PR description
Following the fix in d927a7b6, we broke the default behaviour of empty text/chart fields. While the server returns the value `false` when they're empty, we want to display an empty string in the `ODOO.LIST` formulas. Task-4897690 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
This fix prevents an unnecessary warning from interrupting setup or upgrades when purchase requisitions look for a receiving operation type that is inactive. It helps companies complete module installation or database upgrades more reliably without being incorrectly redirected to create a warehouse.
Original PR description
Fixed an issue in ```_default_picking_type_id``` where a missing picking type triggered a ```RedirectWarning``` due to an incorrect domain in the ```search``` Hence disabled `active_test` context to…
Fixed an issue in ```_default_picking_type_id``` where a missing picking type triggered a ```RedirectWarning``` due to an incorrect domain in the ```search``` Hence disabled `active_test` context to ensure proper fallback behavior.
```sql
Traceback (most recent call last):
File "/home/odoo/src/odoo/18.0/odoo/service/server.py", line 1328, in preload_registries
registry = Registry.new(dbname, update_module=update_module)
File "<decorator-gen-13>", line 2, in new
File "/home/odoo/src/odoo/18.0/odoo/tools/func.py", line 97, in locked
return func(inst, *args, **kwargs)
File "/home/odoo/src/odoo/18.0/odoo/modules/registry.py", line 129, in new
odoo.modules.load_modules(registry, force_demo, status, update_module)
File "/home/odoo/src/odoo/18.0/odoo/modules/loading.py", line 480, in load_modules
processed_modules += load_marked_modules(env, graph,
File "/home/odoo/src/odoo/18.0/odoo/modules/loading.py", line 365, in load_marked_modules
loaded, processed = load_module_graph(
File "/home/odoo/src/odoo/18.0/odoo/modules/loading.py", line 206, in load_module_graph
registry.init_models(env.cr, model_names, {'module': package.name}, new_install)
File "/home/odoo/src/odoo/18.0/odoo/modules/registry.py", line 604, in init_models
model._auto_init()
File "/home/odoo/src/odoo/18.0/odoo/models.py", line 3468, in _auto_init
new = field.update_db(self, columns)
File "/home/odoo/src/odoo/18.0/odoo/fields.py", line 3215, in update_db
return super(Many2one, self).update_db(model, columns)
File "/home/odoo/src/odoo/18.0/odoo/fields.py", line 1090, in update_db
self.update_db_notnull(model, column)
File "/home/odoo/src/odoo/18.0/odoo/fields.py", line 1142, in update_db_notnull
model._init_column(self.name)
File "/home/odoo/src/odoo/18.0/odoo/models.py", line 3384, in _init_column
value = field.default(self)
File "/home/odoo/src/odoo/18.0/addons/purchase_requisition_stock/models/purchase_requisition.py", line 13, in _default_picking_type_id
self.env['stock.warehouse']._warehouse_redirect_warning()
File "/home/odoo/src/odoo/18.0/addons/stock/models/stock_warehouse.py", line 172, in _warehouse_redirect_warning
raise RedirectWarning(msg, warehouse_action.id, _('Go to Warehouses'))
odoo.exceptions.RedirectWarning: ('Cree un almacén para la empresa Navieras Internacionales, S.A. (Navinter).', 464, 'Ir a los almacenes', None)
```
```sql
depr_2982092=> select id,name,active,company_id,warehouse_id from stock_picking_type where code = 'incoming' and active = 'f' order by company_id;
id | name | active | company_id | warehouse_id
----+----------------------------------------------------------------------------------------------------+--------+------------+--------------
6 | {"en_US": "Devoluciones"} | f | 1 | 1
67 | {"en_US": "Recepciones", "es_GT": "Recepciones"} | f | 1 | 12
72 | {"en_US": "Devoluciones", "es_GT": "Devoluciones"} | f | 1 | 12
1 | {"de_DE": "Anlieferungen", "en_US": "Recepciones", "es_GT": "Recepciones", "nl_NL": "Ontvangsten"} | f | 1 | 1
(4 rows)
```
OPW - [4869238](https://www.odoo.com/odoo/project/70/tasks/4869238?debug=1)
UPG - [2982092](https://upgrade.odoo.com/odoo/upgrade.request/2982092)
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prBranch users who have access to a parent company can now open the Profit and Loss report when journals use a different company currency. The change prevents an unnecessary access error while preserving normal permission limits.
Original PR description
This commit is the counterpart of a commit in community to add a test. ### Steps to reproduce: - Create a branch to a company - Create a journal on the parent company with a different currency from the company - Create a user that can access both the parent company and the branch, but can't change the settings of Odoo - Log as this user, select only the branch as current company - Accounting > Reporting > Profit & Loss - Access Error ### Cause: `_compute_display_name` on the journal reads `journal.company_id.currency_id` without sudo. The current user cannot read on `company_id` because of the rule `res_company_rule_employee`. ### Solution: Use `sudo()` to read the currency of the company. opw-4847500 Linked PR: https://github.com/odoo/odoo/pull/215455
Spreadsheet dashboards now treat creation date filters as date-and-time values, so results correctly reflect each user's timezone. This prevents dashboard filters from including or excluding the wrong records when dates are used.
Original PR description
The generated domain is wrong when filtering on the date. It doesn't account for the user timezone because the field matching is given as a "date" field instead of being a "datetime".
The generated domain looks like `[("create_date", ">=", "2025-06-27")]` instead of `[("create_date", ">=", "2025-06-27 21:59:59")]`
I'm fixing this in 18.0 because this fix won't affect existing databases (without updating the modules). The fix would be useless and I don't want to go though the pain of forward-ports for nothing. New databases are created in 18.0 every day (latest LTS)
Task: 4903362Creating a spreadsheet in a Documents folder no longer fails when one of the folder's internal editor members has been archived. This prevents unnecessary validation errors and keeps document workflows working even when former employees remain listed on folders.
Original PR description
Reproduce: 1. Create a new folder 2. Set a specific internal user as editor member on it 3. Archive that user 4. Try creating a spreadsheet in that folder -> ValidationError The check wrongly considered archived internal users as portal users. Task-4878693
The Colombian e-invoicing mandate module now explicitly includes a required dependency, preventing setup or usage errors when that related component is not present. This improves reliability for new installations, though existing databases are not automatically changed.
Original PR description
l10n_co_edi_mandate depends on l10n_co_dian, however this dependency wasn't set directly, relying on l10n_co_dian being auto-installed with l10n_co_edi which is a direct dependency. As such, errors could occur if user manually uninstalls l10n_co_dian. This fix addresses the issue for new installations, however existing databases won't be affected. See odoo/enterprise#77673
**Steps to reproduce:** From a Romanian company with the RO localization configured, when processing a payment transaction from the e-commerce, it can happen that the creation of the invoice fails due to a SerializationFailure but the EDI is correctly sent to the government service. As the creation of the invoice has failed, the system will retry to create it and trigger the sending of the EDI again. **Solution:** Trigger a commit before sending the EDI. opw-4844913 --- I confi
Original PR description
**Steps to reproduce:** From a Romanian company with the RO localization configured, when processing a payment transaction from the e-commerce, it can happen that the creation of the invoice fails due to a SerializationFailure but the EDI is correctly sent to the government service. As the creation of the invoice has failed, the system will retry to create it and trigger the sending of the EDI again. **Solution:** Trigger a commit before sending the EDI. opw-4844913 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#216114
Currently, an error is produced on searching in a security group with a forward slash ('/'). **Steps to reproduce:** - Navigate to `Settings > Users & Companies > Groups`. - Type '/' in the search bar and hit Enter. **Error:** `IndexError - pop from empty list` **Cause:** When the group name contains only slashes, splitting it by '/' at [1] results in an empty list. After computation, it attempts to pop from the empty list, resulting in an error. [1] - https://github.com/odoo/odo
Original PR description
Currently, an error is produced on searching in a security group with a forward slash ('/').
**Steps to reproduce:**
- Navigate to `Settings > Users & Companies > Groups`.
- Type '/' in the search bar and hit Enter.
**Error:**
`IndexError - pop from empty list`
**Cause:**
When the group name contains only slashes, splitting it by '/' at [1] results in an empty list. After computation, it attempts to pop from the empty list, resulting in an error.
[1] - https://github.com/odoo/odoo/blob/a301f8ae6aad59efd073a34c6f9ec323191d211b/odoo/addons/base/models/res_users.py#L234-L235
This commit ensures the group name is only assigned when values have content, preventing the error.
Sentry - 6685124199
Forward-Port-Of: odoo/odoo#214557Issue -> For databases with large `account_move_line` tables, running the `_existing_accounting` (when opening Settings) method to check if a company has accounting entries by searching for any `account_move_line` records belonging to the current company is slow. The default search order for this model is `date desc, move_name desc, id`. This causes an index scan on the table using `account_move_line_date_name_id_idx`. The combination of using `date` to order by and the query planner using an
Original PR description
Issue -> For databases with large `account_move_line` tables, running the `_existing_accounting` (when opening Settings) method to check if a company has accounting entries by searching for any `account_move_line` records belonging to the current company is slow. The default search order for this model is `date desc, move_name desc, id`. This causes an index scan on the table using `account_move_line_date_name_id_idx`. The combination of using `date` to order by and the query planner using an unrelated index for the search leads to a long running SELECT query. Solution --> We replace the `search` with a `search_count` where the ordering doesn't matter and the order by clause is skipped. Benchmark --> On customers' database with about 30M move lines and 1 `res.company` record, speedup on the SELECT query is as follows --> 62743.883 ms -> 0.392 ms Ticket [link](https://www.odoo.com/odoo/project/967/tasks/4811622) opw-4811622 Forward-Port-Of: odoo/odoo#215727
This **PR** enhances the default values for Hungarian electronic invoicing (EDI) by ensuring the delivery date is copied from the original invoice to the corresponding credit or debit note. **task**-4818819 Forward-Port-Of: odoo/odoo#211860
Original PR description
This **PR** enhances the default values for Hungarian electronic invoicing (EDI) by ensuring the delivery date is copied from the original invoice to the corresponding credit or debit note. **task**-4818819 Forward-Port-Of: odoo/odoo#211860
When doing the following steps: Purchase > Receipt > Landed Cost > Return > Return > Bill The landed cost would prevent the method _generate_price_difference_vals from correctly computing the correct Out Quantity. Hence, even if no stock is actually out, the bill would generate a COGS line for the currency rate difference for the quantity already out. --- ### Test result without fix: ``` 2025-06-25 11:17:39,821 33449 ERROR oes_test_17 odoo.addons.stock_landed_costs.tests.test_stoc
Original PR description
When doing the following steps: Purchase > Receipt > Landed Cost > Return > Return > Bill The landed cost would prevent the method _generate_price_difference_vals from correctly computing the correct…
When doing the following steps:
Purchase > Receipt > Landed Cost > Return > Return > Bill
The landed cost would prevent the method _generate_price_difference_vals from correctly computing the correct Out Quantity.
Hence, even if no stock is actually out, the bill would generate a COGS line for the currency rate difference for the quantity already out.
---
### Test result without fix:
```
2025-06-25 11:17:39,821 33449 ERROR oes_test_17 odoo.addons.stock_landed_costs.tests.test_stockvaluationlayer: FAIL: TestAccountInvoicingWithCOA.test_fifo_return_twice_and_bill_with_landed_cost_and_multi_currency
Traceback (most recent call last):
File "/home/odoo/projects/odoo-src/multiverse/src/17.0/odoo/addons/stock_landed_costs/tests/test_stockvaluationlayer.py", line 759, in test_fifo_return_twice_and_bill_with_landed_cost_and_multi_currency
self.assertRecordValues(bill2.line_ids, [
File "/home/odoo/projects/odoo-src/multiverse/src/17.0/odoo/odoo/tests/common.py", line 667, in assertRecordValues
self.fail('\n'.join(errors))
AssertionError: The records and expected_values do not match.
Wrong number of records to compare: 5 records versus 3 expected values.
==== Additional record ====
{'account_id': 388, 'amount_currency': 0.0, 'balance': 25.0}
==== Additional record ====
{'account_id': 406, 'amount_currency': 0.0, 'balance': -25.0}
```
---
OPW-4512411
Origin PR: #199440
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#215827Scenario: - install website_sale - go in settings and enable "extra steps" - go to configure extra steps - get in edit mode and add any visibility condition for the form - save Result: the form is hidden in all conditions, even when it should be shown. Why: In 0750eb6315fe9c2d1f1de36b9b756b5097ed11e0 17.0 redesign of the checkout flow, the structure of extra steps changed so now the root element when editing became the section tag of the form. This means that when we set a visibility on it,
Original PR description
Scenario: - install website_sale - go in settings and enable "extra steps" - go to configure extra steps - get in edit mode and add any visibility condition for the form - save Result: the form is hidden in all conditions, even when it should be shown. Why: In 0750eb6315fe9c2d1f1de36b9b756b5097ed11e0 17.0 redesign of the checkout flow, the structure of extra steps changed so now the root element when editing became the section tag of the form. This means that when we set a visibility on it, the form will be hidden by default then shown based on attributes such as data-visibility-selectors. But on the root tag, we only allow to modify only a very restricted list of tags, so we saved the hiding of the form, but didn't save the attributes that made it visibile based on a condition. Fix: add the attributes used for visibility in the authorized list on the root tag. opw-4765026 Forward-Port-Of: odoo/odoo#215479
Currently, once a fsm task report has been sent once, the "Send report" buttons are disabled in the form view. However, the contextual server action is always available, but a check in `action_send_report` prevents the report from being sent if the buttons are disabled. This commits allows re-sending the report, which can be useful if some changes have been made after the report was first sent. opw-4818953 Forward-Port-Of: odoo/enterprise#87104
Original PR description
Currently, once a fsm task report has been sent once, the "Send report" buttons are disabled in the form view. However, the contextual server action is always available, but a check in `action_send_report` prevents the report from being sent if the buttons are disabled. This commits allows re-sending the report, which can be useful if some changes have been made after the report was first sent. opw-4818953 Forward-Port-Of: odoo/enterprise#87104
**Issue 1** - Have a pricelist with the "Discount policy" == "without_discount" - Using this pricelist, create a SO with 1 subscription line and 1 non-subscription line - Set a discount on both lines - Save the SO - Issue: the discount on the non-subscription line has been reset to 0.0 **Issue 2** - Using the previous SO, add back a discount value for the non-subscription line - Confirm the SO and invoice it - Close the subscription - Issue: the discount on the non-subscription line
Original PR description
**Issue 1** - Have a pricelist with the "Discount policy" == "without_discount" - Using this pricelist, create a SO with 1 subscription line and 1 non-subscription line - Set a discount on both lines…
**Issue 1** - Have a pricelist with the "Discount policy" == "without_discount" - Using this pricelist, create a SO with 1 subscription line and 1 non-subscription line - Set a discount on both lines - Save the SO - Issue: the discount on the non-subscription line has been reset to 0.0 **Issue 2** - Using the previous SO, add back a discount value for the non-subscription line - Confirm the SO and invoice it - Close the subscription - Issue: the discount on the non-subscription line has been reset to 0.0 **Cause** Both issues come from the fact that `order_id.subscription_state` is a dependency of `_compute_discount` in `sale_subscription`. The super is called for non-subscription lines, recomputing the discount. **Solution** It is not possible to know which dependency triggered the compute, therefore the solutions are to: - avoid a recompute at creation after the `web_save` by not writing on the `subscription_state` field if not necessary - avoid calling super for lines if the subscription is closed opw-4645579 Forward-Port-Of: odoo/enterprise#84754
How to reproduce the issue: With l10n_es on an ES company: - Create an invoice from two months ago with a value of 1000. - Fully credit note this invoice on the current month. - On the mod 349 report, download the BOE report. The BOE report does not contains the rectification despite being mandatory as per: https://www.boe.es/buscar/doc.php?id=BOE-A-2010-5098 (look at the examples in CUMPLIMENTACIÓN DEL REGISTRO DE RECTIFICACIONES). This commit also fixes an issue where invoice reve
Original PR description
How to reproduce the issue: With l10n_es on an ES company: - Create an invoice from two months ago with a value of 1000. - Fully credit note this invoice on the current month. - On the mod 349 report, download the BOE report. The BOE report does not contains the rectification despite being mandatory as per: https://www.boe.es/buscar/doc.php?id=BOE-A-2010-5098 (look at the examples in CUMPLIMENTACIÓN DEL REGISTRO DE RECTIFICACIONES). This commit also fixes an issue where invoice reverted to draft where included in the boe report: - Create an invoice of 100 in January, credit note 50 in May. - Reset to draft both the invoice and the credit note. - Create another invoice of 888 in February, credit note 444 in May. - Generate the BOE report. The invoice reverted to draft is included in the boe report. opw-4653025 Forward-Port-Of: odoo/enterprise#88145 Forward-Port-Of: odoo/enterprise#86127