Monday, June 16, 2025
24 changes · 18.0
Enhancements to existing features
The Asset app now hides the Add Properties option when it cannot be used on asset model records. If users try to add properties to an asset without an associated asset model, they now see a clearer error message, reducing confusion and support effort.
Original PR description
This commit introduces two improvements to the 'Add Properties' button in the cog menu of the Asset model: 1. Hides the button if the record has state = 'model'. Previously, the button was available but no action was triggered. 2. Raises an error message if the button 'Add Properties' is clicked in an asset without an asset model associated. Previously, only a warning with the unclear message "You need edit access on the parent doument to update these property fields" was shown. task-4822091
Resolved issues and error corrections
Some mail conversation data can occasionally reference a participant whose contact profile is no longer available in the browser. This fix skips those incomplete entries when identifying the conversation counterpart, preventing unnecessary crashes and keeping messaging usable.
Original PR description
There are several flows where the persona of a member might not (or no longer) be known in JS. These members should simply be ignored when computing the correspondent of a channel rather than crashing.
Miscellaneous changes
When we are in the org chart, and click on the cap of an employee to see the manager information, if the manager of the employee is themselves, there's an traceback error. We can fix it by disabling the cap if the you are your own manager. To Reproduce on Runbot: 1. Go to an employee in Employee module. 2. Make sure the manager field has themselves as the manager 3. Click on the org chart 4. Click on the cap icon, and you'll see the error. opw-4716216 Forward-Port-Of: odoo/odoo#207483
Original PR description
When we are in the org chart, and click on the cap of an employee to see the manager information, if the manager of the employee is themselves, there's an traceback error. We can fix it by disabling the cap if the you are your own manager. To Reproduce on Runbot: 1. Go to an employee in Employee module. 2. Make sure the manager field has themselves as the manager 3. Click on the org chart 4. Click on the cap icon, and you'll see the error. opw-4716216 Forward-Port-Of: odoo/odoo#207483
Reversed point-of-sale orders in the Indian localization now receive the correct place of supply information. This helps ensure tax and compliance details remain complete when POS orders are reversed.
Original PR description
Before this commit: - The `_compute_l10n_in_state_id` method only considered `pos_session_ids` when assigning the state for Indian POS moves. - Reversed POS orders were ignored, leading to missing `l10n_in_state_id`. After this commit: - Added `reversed_pos_order_id` to the `@api.depends` decorator. - Updated domain to include moves with `reversed_pos_order_id`. Ensures correct place of supply is computed for reversed POS orders as well. OPW: 4862639
This fix makes an automated website event test wait until editing is properly finished before moving on. It reduces random test failures caused by timing differences, helping keep quality checks stable without changing customer-facing behavior.
Original PR description
The test `test_website_event_tour_admin` fails randomly depending on the processing speed available. When clicking on `a[title='Back to All Events']`, if the website happens to still be in edit mode, the click will be prevented: https://github.com/odoo/odoo/blob/18.0/addons/website/static/src/client_actions/website_preview/website_preview.js#L424-L438 We can use the clickOnSave function made specifically for this. It ensures exiting edit mode before continuing. --- runbot-223022
This fix prevents errors when an invoice line is linked to multiple sales order lines. It uses the analytic distribution from the first linked sales line so invoice creation can continue reliably.
Original PR description
In odoo/odoo#199763, `_related_analytic_distribution()` was introduced to pass the existing analytic distribution in a sale order line to an invoice line. However, sale_line_ids is a Many2Many field, so to avoid singleton errors in the case of multiple SOLs, only the analytic distribution of the first sale order line is passed. no-task --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The account type `Caixa` (Cash) and `Depósitos à Ordem` (Demand deposits) were missing from the Portuguese localization. Changed translations in pt.po for the template_chart.py context. Steps to reproduce: - install the accountant and l10n_pt module. - select a Portuguese company. - in the Chart of Accounts, notice there is no account named `Caixa` and `Depósitos à ordem`. Ticket [link](https://www.odoo.com/odoo/project/967/tasks/4829413) opw-4829413
Original PR description
The account type `Caixa` (Cash) and `Depósitos à Ordem` (Demand deposits) were missing from the Portuguese localization. Changed translations in pt.po for the template_chart.py context. Steps to reproduce: - install the accountant and l10n_pt module. - select a Portuguese company. - in the Chart of Accounts, notice there is no account named `Caixa` and `Depósitos à ordem`. Ticket [link](https://www.odoo.com/odoo/project/967/tasks/4829413) opw-4829413
This fix makes work order duration calculations ignore tiny microsecond differences when recording productivity time. It prevents occasional test and rounding failures caused by insignificant timing fluctuations, improving reliability without changing business workflows.
Original PR description
The `_set_duration` inverse method of `mrp.workorder` is ignoring microsecond variations when computing the `date_start` of a workorder productivity record. This method uses the current time as the end date but does not remove microseconds from it. This causes a intermittent error when running the `test_labor_cost_balancing_with_cost_share`, because the computed duration (around 0.03 hours or 1.8 seconds) can vary slightly depending on the microseconds captured by `datetime.now()`. This fluctuation results in a 1- or 2-second difference, which breaks the test. To fix it, we simply set the microsseconds of the end date to zero. This bug was introduced in: https://github.com/odoo/odoo/pull/80319/commits/15fef27edb3ec437d1dbec33481c5d778795bc59 Runbot failure example: https://runbot.odoo.com/odoo/runbot.build.error/226657 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Users trying to fetch a Shopee shipping label for a delivery that is not connected to a Shopee shop will now see a clear error message instead of a technical crash. This helps staff understand what is wrong and prevents confusing system tracebacks during shipping operations.
Original PR description
Steps to reproduce the bug:
- Create a storable product “P1”
- Create a delivery order with one unit of P1, not linked to any sale order
- Go to the delivery order list view
- Select the created delivery order
- Click on Action → Fetch shipping label
Problem:
A traceback is triggered:
```
ValueError: ValueError('Expected singleton: shopee.shop()') while
evaluating
'records._fetch_shipment_label()'
The above server error caused the following client error:
```
The `_fetch_shipment_label` function expects at least one item, but
we don't check it via a user error, because we're supposed to call
`_sync_shopee_pickings` instead, where all these filtering and checks
are done
opw-4812360The Data Cleaning module now uses a unique identifier for its model form, preventing it from being overwritten during installation. This ensures the expected configuration screen is available and avoids missing setup options for users.
Original PR description
**Issue:** The data_cleaning module contains two views, data_merge_model_views and data_cleaning_model_views, that share the same form view id. **Steps to Reproduce:** 1. Install the data_cleaning…
**Issue:** The data_cleaning module contains two views, data_merge_model_views and data_cleaning_model_views, that share the same form view id. **Steps to Reproduce:** 1. Install the data_cleaning module 2. Open psql in the terminal 3. Run the following query:” select id, name, model from ir_ui_view where model ilike 'data_%' and type = 'form';” 4. Observe that data_cleaning.model is missing from the results Expected Behavior: the form view for data_cleaning.model should be present in the database. Actual Behavior: the form view for data_cleaning.model is not found in the database. **Root Cause** The form view in data_cleaning_model_views has the same id as the one in data_merge_model_views. Because data_cleaning_model_views is loaded first (as defined in __manifest__.py), it gets overwritten by data_merge_model_views. **Fix** To prevent this issue, the form view id in data_cleaning_model_views has been renamed to a unique and more appropriate identifier. Opw-4517418
Commit [1] added a compatibility layer when we switched to Bootstrap 4. That compatibility layer actually still exists in master, even though we are now using Bootstrap 5. A specific rule was forcing input-group elements on one row... which conflicts with the fact that invalid feedbacks are supposed to wrap on the next row. This commit fixes that by re-enabling the wrap, when such a feedback is displayed only. In master, the rule should probably be removed, hoping outdated layouts were update
Original PR description
Commit [1] added a compatibility layer when we switched to Bootstrap 4. That compatibility layer actually still exists in master, even though we are now using Bootstrap 5. A specific rule was forcing…
Commit [1] added a compatibility layer when we switched to Bootstrap 4. That compatibility layer actually still exists in master, even though we are now using Bootstrap 5. A specific rule was forcing input-group elements on one row... which conflicts with the fact that invalid feedbacks are supposed to wrap on the next row.
This commit fixes that by re-enabling the wrap, when such a feedback is displayed only. In master, the rule should probably be removed, hoping outdated layouts were updated to Bootstrap 4+ correctly at this point (not even sure what exactly is broken by not forcing the input-group on one row).
Steps to reproduce:
- Add a form in your website page
- Add a date field (this is an input-group)
- Make it required
- Save
- Open the HTML editor(*) and add an invalid-feedback in that field
- Save
- Send your form without filling it => the input-group is broken
(*) starting from 18.4, there is a standard use case on the /my/security
page. There might be unknown usecases between 16.0 and 18.4.
[1]: https://github.com/odoo/odoo/commit/7aa473e09944bc5c1aba2dbcd611097dd36db6c5
Related to task-3959739
Forward-Port-Of: odoo/odoo#214029This reverts the fix of commit 2597d6f4c33fe2ae8a60e11059c2630ac8aff58c and flatten the background color of the body element instead. Scenario: - set a color to the body different than white - add snippets to have a height higher than the viewport - go down in the page Result: the background color is only set up to the viewport height. Cause: Before 18.0, the body takes 100% of the page height because we are scrolling over the #wrapwrap element. In 18.0 with 189a7c96e6e26825d
Original PR description
This reverts the fix of commit 2597d6f4c33fe2ae8a60e11059c2630ac8aff58c and flatten the background color of the body element instead. Scenario: - set a color to the body different than white - add…
This reverts the fix of commit 2597d6f4c33fe2ae8a60e11059c2630ac8aff58c and flatten the background color of the body element instead. Scenario: - set a color to the body different than white - add snippets to have a height higher than the viewport - go down in the page Result: the background color is only set up to the viewport height. Cause: Before 18.0, the body takes 100% of the page height because we are scrolling over the #wrapwrap element. In 18.0 with 189a7c96e6e26825dc05c0c6466576fe63aa091e, we are scrolling over the body element, that combined with the body having a height of 100% makes the body element being positionned from 0 to viewport height, and it's not present below that. Also to set background of the whole page, the browser uses the body background if there is no background on the html element, so even if the body didn't cover the whole page, we were getting the body color on the whole page. So the change in 2597d6f4c33fe2ae8a60e11059c2630ac8aff58c that set the html element to white, causes the background color to only be applied to up to the viewport height, with the background being blank below that. Fix: set the body background color to the flattened rgb color. opw-4863179 opw-4863724 Forward-Port-Of: odoo/odoo#213858
**Step to reproduce:** 1. Install `l10n_iq` and `res_partner`. 2. Create a contact with Iraq as the country and assign any state. 3. Create an invoice for that customer. **Observation:** - State codes appear as numbers (e.g., 01, 02, 03...) which are not ISO-compliant. **Issue:** - State codes in the CSV file were defined as simple numbers instead of proper ISO codes. **Solution:** - Updated all state codes to match the official ISO 3166-2:IQ codes. (Reference: https://www.iso.org
Original PR description
**Step to reproduce:** 1. Install `l10n_iq` and `res_partner`. 2. Create a contact with Iraq as the country and assign any state. 3. Create an invoice for that customer. **Observation:** - State codes appear as numbers (e.g., 01, 02, 03...) which are not ISO-compliant. **Issue:** - State codes in the CSV file were defined as simple numbers instead of proper ISO codes. **Solution:** - Updated all state codes to match the official ISO 3166-2:IQ codes. (Reference: https://www.iso.org/obp/ui/#iso:code:3166:IQ) - For Arabic names, appended `-AR` to the code (e.g., IQ-BG-AR) for Arabic-specific entries. opw-4808778 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#213972
### Description: Deleting manufacturing orders (MOs) is slow due to unoptimized code. The methods `_action_cancel` and `_compute_picking_ids` are the main performance issues. ### Fix: `_compute_picking_ids`, is improved by moving its search outside the loop and grouping by `group_id`, reducing the amount of calls to the ORM. A `skip_activity` context check is added in `_action_cancel` to bypass activity generation during cancellation, aligning with the existing check done later in `_
Original PR description
### Description: Deleting manufacturing orders (MOs) is slow due to unoptimized code. The methods `_action_cancel` and `_compute_picking_ids` are the main performance issues. ### Fix:…
### Description: Deleting manufacturing orders (MOs) is slow due to unoptimized code. The methods `_action_cancel` and `_compute_picking_ids` are the main performance issues. ### Fix: `_compute_picking_ids`, is improved by moving its search outside the loop and grouping by `group_id`, reducing the amount of calls to the ORM. A `skip_activity` context check is added in `_action_cancel` to bypass activity generation during cancellation, aligning with the existing check done later in `_log_activity_get_documents`. Also, a bug in `_action_cancel` was calling a filtering on`self`, rather than `production`, and that for each production, which was degrading the performance. ### Benchmark: | N° of MO | Before | After | |----------|--------|-------| | 80 | 15s | 1s | | 160 | 33s | 2s | | 1000 | 2:52 | 8s | ### Reference: opw-4734710 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#207960
Since the edited page is within an iframe, the built-in fonts used by the wysiwyg are also loaded inside the page within the iframe, which causes them to replace the one used when viewing the page as a visitor if it happens to be one of the fallback fonts. This commit avoids that by giving a distinct `font-family` to the fonts used by the wysiwyg. task-3080104 Forward-Port-Of: odoo/odoo#213868 Forward-Port-Of: odoo/odoo#112759
Original PR description
Since the edited page is within an iframe, the built-in fonts used by the wysiwyg are also loaded inside the page within the iframe, which causes them to replace the one used when viewing the page as a visitor if it happens to be one of the fallback fonts. This commit avoids that by giving a distinct `font-family` to the fonts used by the wysiwyg. task-3080104 Forward-Port-Of: odoo/odoo#213868 Forward-Port-Of: odoo/odoo#112759
Forward-Port-Of: odoo/odoo#212936 Forward-Port-Of: odoo/odoo#208639
Original PR description
Forward-Port-Of: odoo/odoo#212936 Forward-Port-Of: odoo/odoo#208639
Follow-up of [1]. - Using `invalidate_model` without giving the related field seems to be causing issues in the master version. Let's just mention what we need only to be sure. - Check the proper update of write_date.s (note that this was already done in some forward-ported versions of [1]). - Use two distinct "new dates" so that potential cache features do not make the test pass by chance, and ease debugging of the test. [1]: https://github.com/odoo/odoo/commit/4df533196d3cfdee34beb
Original PR description
Follow-up of [1]. - Using `invalidate_model` without giving the related field seems to be causing issues in the master version. Let's just mention what we need only to be sure. - Check the proper update of write_date.s (note that this was already done in some forward-ported versions of [1]). - Use two distinct "new dates" so that potential cache features do not make the test pass by chance, and ease debugging of the test. [1]: https://github.com/odoo/odoo/commit/4df533196d3cfdee34beb2ae604f569e67cf4f93 Forward-Port-Of: odoo/odoo#213851 Forward-Port-Of: odoo/odoo#213760
Versions -------- - 17.0+ Steps ----- 1. Have a partner with a `commercial_partner_id`; 2. for the `commercial_partner_id`, create an partner of type `invoice`; 3. create & confirm a sale order invoiced to the initial partner; 4. create & confirm a sale order invoiced to the invoice partner; 5. check the `credit_to_invoice` of the partner; 6. check the `credit_to_invoice` of the `commercial_partner_id`. Issue ----- The credit to invoice is twice what it should be. Cause ----
Original PR description
Versions -------- - 17.0+ Steps ----- 1. Have a partner with a `commercial_partner_id`; 2. for the `commercial_partner_id`, create an partner of type `invoice`; 3. create & confirm a sale order…
Versions -------- - 17.0+ Steps ----- 1. Have a partner with a `commercial_partner_id`; 2. for the `commercial_partner_id`, create an partner of type `invoice`; 3. create & confirm a sale order invoiced to the initial partner; 4. create & confirm a sale order invoiced to the invoice partner; 5. check the `credit_to_invoice` of the partner; 6. check the `credit_to_invoice` of the `commercial_partner_id`. Issue ----- The credit to invoice is twice what it should be. Cause ----- The `_compute_credit_to_invoice` method sums up the `credit_to_invoice` on a partner's `commercial_partner_id`. By first checking the partner's credit to invoice, it searched all sale orders credited to the commercial entity. Before it can sum these, it first has to compute the `credit_to_invoice` of the `commercial_partner_id`, which retrieves the same sale orders, and hence get summed up twice. Solution -------- Only compute the `credit_to_invoice` on commercial partners by taking the intersection of `self` & `self.commercial_partner_id`. opw-4855507 Forward-Port-Of: odoo/odoo#213849
The goal of this commit is to fix the `website_form_editor_tour` tour that is failing undeterministically. The tour fails because this flow happens; - The user types something ("A") as input and clicks somewhere else to commit its change. - The DOM is updated with the new value. - The user types something else ("B") on the same input. - The options are rebuild with the DOM value. -> "A" is displayed in the option input and "B" is lost. This is a know issue and it has been decided to no
Original PR description
The goal of this commit is to fix the `website_form_editor_tour` tour that is failing undeterministically. The tour fails because this flow happens;
- The user types something ("A") as input and clicks somewhere else to commit its change.
- The DOM is updated with the new value.
- The user types something else ("B") on the same input.
- The options are rebuild with the DOM value.
-> "A" is displayed in the option input and "B" is lost.
This is a know issue and it has been decided to not fix it in stable as the behavior seems really unlikely to happen with human behavior and the issue is not critical.
Although it is not optimal, the tour is fixed by adding delays before doing further steps.
runbot-64572
Forward-Port-Of: odoo/odoo#213197When User removes the currency from an invoice, A traceback will appear. Steps to reproduce the error: - Install ``l10n_es`` module and switch to ``ES Company`` - Enable Multiple currency - Create an invoice > Set customer > save - Now, Remove currency and customer from an invoice Traceback: ``` ValueError: Expected singleton: res.currency() ``` https://github.com/odoo/odoo/blob/51fcbd211d2b1abf4b93becedbcbb9e03002cdd6/addons/l10n_es/models/account_move.py#L23 This line causes
Original PR description
When User removes the currency from an invoice, A traceback will appear. Steps to reproduce the error: - Install ``l10n_es`` module and switch to ``ES Company`` - Enable Multiple currency - Create an invoice > Set customer > save - Now, Remove currency and customer from an invoice Traceback: ``` ValueError: Expected singleton: res.currency() ``` https://github.com/odoo/odoo/blob/51fcbd211d2b1abf4b93becedbcbb9e03002cdd6/addons/l10n_es/models/account_move.py#L23 This line causes a traceback with an empty currency when the user removes the currency from the invoice. sentry-6670501631 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#213731
In the Datev standard export, sales with foreign currency and currency indicator are exported to the wrong column. Steps to reproduce: - With a DE Company - Open Accounting / Reporting / Audit Reports / General Ledger - Click "Datev Data (ZIP)" - Open EXTF_accounting_entries.csv According to the documentation https://apps.datev.de/help-center/documents/1003221 Chapter 3. when a journal entry is in a foreign currency: - The amount in foreign currency should go into Column B - The c
Original PR description
In the Datev standard export, sales with foreign currency and currency indicator are exported to the wrong column. Steps to reproduce: - With a DE Company - Open Accounting / Reporting / Audit Reports / General Ledger - Click "Datev Data (ZIP)" - Open EXTF_accounting_entries.csv According to the documentation https://apps.datev.de/help-center/documents/1003221 Chapter 3. when a journal entry is in a foreign currency: - The amount in foreign currency should go into Column B - The currency code should go into Column C - The base currency amount (i.e. the company's local currency) should be shown in Columns E and F opw-4701001 Forward-Port-Of: odoo/enterprise#87366 Forward-Port-Of: odoo/enterprise#87002
Before this commit, printing the sale detail when a tax name existed in another company with the same name led to an expected singleton error. Additionally, the absence of `identification_letter` for "No Taxes" caused errors during sorting. opw-4137917 Forward-Port-Of: odoo/enterprise#69402
Original PR description
Before this commit, printing the sale detail when a tax name existed in another company with the same name led to an expected singleton error. Additionally, the absence of `identification_letter` for "No Taxes" caused errors during sorting. opw-4137917 Forward-Port-Of: odoo/enterprise#69402
Rounding errors may occur when using `int()` on float values. Steps to reproduce: - Create an invoice with a total amount of 256.46 - Create a RIBA payment for this invoice - Add this payment to a batch payment - Export the batch payment file In the exported file, the amount should be 25646, but it is incorrectly 25645 in two places. This happens because in Python: `int(256.46 * 100) → int(25645.999999...) → 25645` To fix this, we use `float_round()` to round correctly the float
Original PR description
Rounding errors may occur when using `int()` on float values. Steps to reproduce: - Create an invoice with a total amount of 256.46 - Create a RIBA payment for this invoice - Add this payment to a batch payment - Export the batch payment file In the exported file, the amount should be 25646, but it is incorrectly 25645 in two places. This happens because in Python: `int(256.46 * 100) → int(25645.999999...) → 25645` To fix this, we use `float_round()` to round correctly the float before applying `int()` to convert the value to an integer. This ensures accurate rounding for exported payment amounts. Ticket [link](https://www.odoo.com/odoo/project/967/tasks/4858205) opw-4858205 Forward-Port-Of: odoo/enterprise#87597
Steps to reproduce: 1. Install website_sale_renting. 2. Go to the Website -> shop, open the renting product 3. Try to set today's date as start date of the Rental Period Issue: - The default date was always set to the next day with the current time hours. That's making it impossible for users to select today's date without Adjusting the time manually. Solution: - Updated the logic for hourly rentals to set the default date next day with adding one hour from the current time, to allow
Original PR description
Steps to reproduce: 1. Install website_sale_renting. 2. Go to the Website -> shop, open the renting product 3. Try to set today's date as start date of the Rental Period Issue: - The default date was always set to the next day with the current time hours. That's making it impossible for users to select today's date without Adjusting the time manually. Solution: - Updated the logic for hourly rentals to set the default date next day with adding one hour from the current time, to allow customers to select the current date Reference-https://github.com/odoo/enterprise/commit/32b5db6242a0a9cf43002e3723442be7d0cd210a opw-4844754 Forward-Port-Of: odoo/enterprise#86908