Daily updates from Odoo
Thursday, August 14, 2025
55 changes
12 changes
Resolved issues and error corrections
This update fixes an unstable automated test in Web Studio that could fail unpredictably during validation. It improves confidence in release checks without changing user-facing behavior.
Original PR description
There was an undeterminism in a test relying on the event beforeunload beign defaultPrevented. For some reason it failed sometimes, probably because of an override somewhere. This commit fixes the problem by asserting other things in the test, arguably even more relevant than before. runbot-error-229754
A subscription upsell test was adjusted so it works reliably regardless of the year in which it is run. This helps keep automated checks stable and avoids false failures that could slow down releases.
Original PR description
Before this commit, when test_uninvoiced_upsell_close_log was launched in a year different than 2025, it would fail with the following error: ``` File…
Before this commit, when test_uninvoiced_upsell_close_log was launched in a year different than 2025, it would fail with the following error:
```
File "/data/build/enterprise/sale_subscription/tests/test_sale_subscription.py", line 2085, in test_uninvoiced_upsell_close_log
action = subscription.prepare_upsell_order()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/build/enterprise/sale_subscription/models/sale_order.py", line 1042, in prepare_upsell_order
action = self._prepare_renew_upsell_order('7_upsell', upsell_msg_body)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/build/enterprise/sale_subscription/models/sale_order.py", line 1012, in _prepare_renew_upsell_order
order = self._create_renew_upsell_order(subscription_state, message_body)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/build/enterprise/test_sale_subscription/models/sale_order.py", line 228, in _create_renew_upsell_order
order = super()._create_renew_upsell_order(subscription_state, message_body)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/build/enterprise/sale_subscription/models/sale_order.py", line 998, in _create_renew_upsell_order
values = self._prepare_upsell_renew_order_values(subscription_state)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/build/enterprise/project_sale_subscription/models/sale_order.py", line 40, in _prepare_upsell_renew_order_values
res = super()._prepare_upsell_renew_order_values(subscription_state)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/build/enterprise/partner_commission/models/sale_order.py", line 72, in _prepare_upsell_renew_order_values
values = super()._prepare_upsell_renew_order_values(subscription_state)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/build/enterprise/sale_subscription/models/sale_order.py", line 1182, in _prepare_upsell_renew_order_values
raise UserError(_('You cannot create an upsell for this subscription because it :\n'
odoo.exceptions.UserError: You cannot create an upsell for this subscription because it :
- Has not started yet.
- Has no invoiced period in the future.
```
runbot-task-230716
Forward-Port-Of: odoo/enterprise#92307Activity deadline filters now focus on the current user's own next activity deadline instead of mixing in deadlines from other users on the same record. This makes late, today, and future activity views match the counts users see in the activity menu and reduces confusion across apps.
Original PR description
Partially revert [1] as users expect to see the deadline of their next activity, matching the count displayed in the systray menu. Currently clicking "late activities" for example will show you all records with *any* late activity, instead of records where you personally have late activities. As the more common use case is to view your own activities, that should be what the filter shows. Users may create their own filters to find records based on the next overall deadline. [1]: ad95d7d42f195527bbaccdf349da8316e9c9df12 task-4988330 Forward-Port-Of: odoo/enterprise#92282
German EC Sales List CSV exports now include the required version information expected by the Elster portal. This prevents valid reports from being rejected during upload and helps users submit German tax reporting files successfully.
Original PR description
When uploading the EC Sales List csv to Elster.de portal, users will see the file rejected with the following error (EN translated) """ Your CSV file was created for an older version of the CSV interface. Please refer to the version table in the import help for the latest version of the interface and any changes. If the version information is correct, please check the encoding of your CSV file. The permitted encoding is UTF-8. """ This occurs because the csv is missing the version strings identifying the versions of data format References: https://www.elster.de/eportal/helpGlobal?themaGlobal=zmdo_import_eop https://www.datev-community.de/t5/Betriebliches-Rechnungswesen/Import-CSV-Daten-nacvh-Elster-f%C3%BCr-ZM/td-p/480079 opw-4850314 Forward-Port-Of: odoo/enterprise#92110
This fix prevents tiny rounding differences in Mexican POS eWallet payments from being treated as an amount still owed. Customers can proceed to payment normally when the order is effectively fully paid.
Original PR description
Before this commit, paying an order with eWallet could result in a small negative residual amount (due to tax calculation), instead of zero. This prevented users from proceeding to the payment screen. With this commit, the "lt" function is used to compare amounts while taking rounding precision into account, ensuring the residual is treated as zero when appropriate. opw-4867365 Forward-Port-Of: odoo/enterprise#91756 Forward-Port-Of: odoo/enterprise#88275
The Spanish SME Balance Sheet no longer counts certain group-company account balances twice. This ensures reported investment and liability figures match the actual account balances, improving accuracy for Spanish financial reporting.
Original PR description
Issue: - Amounts were exactly doubled in 'Current Investments in Group Companies and Associates' in the Spanish Balance Sheet - SMEs report as account codes 5523 and 5524 were incorrectly added to…
Issue: - Amounts were exactly doubled in 'Current Investments in Group Companies and Associates' in the Spanish Balance Sheet - SMEs report as account codes 5523 and 5524 were incorrectly added to multiple balance sheet sections Root Cause: - Account codes 5523% and 5524% were included in BOTH: 1. 12400 (Assets): 'Current investments in group companies' 2. 32400 (Liabilities): 'Group companies current liabilities' - This double-counting caused investment amounts to appear twice in the balance sheet How to Reproduce: 1. with Spain - SMEs Fiscal Localization's Package 2. Go to Accounting -> Configuration -> Journal -> Bank 3. Change suspense account to code 5523X or 5524X (should be added to chart of accounts before) 4. Post journal entries to accounts 55230X or 55240X 5. Generate 'Balance Sheet - SMEs (ES)' report 6. Observe amounts are exactly doubled compared to account balances Fix: - Removed duplicate account codes from balance_pymes_line_12400_sub_balances - These accounts are properly handled by the domain formula in line 32400 - Each account code now appears in only one balance sheet section" opw-4983300 Forward-Port-Of: odoo/enterprise#92210
This fix prevents receipt demand quantities from being inflated when warehouse users partially process lot-tracked products in the Barcode app and return later to complete them. It keeps inventory receipts accurate by correctly combining related backorder lines when leaving barcode workflows, including batch picking scenarios.
Original PR description
### Steps to reproduce: - Create a storable product tracked by lot - Create and confirm a receipt for 10 units of that product - Go to the barcode app and regiter 1 unit - Exit the picking - Go back…
### Steps to reproduce: - Create a storable product tracked by lot - Create and confirm a receipt for 10 units of that product - Go to the barcode app and regiter 1 unit - Exit the picking - Go back to the picking register the 9 remaining units - Exit the picking and comeback #### > The demand of the receipt has been updated from 10 to 19. ### Cause of the issue: Exiting the picking will launch a call of the `post_barcode_process` in order to keep track of the changes you made without changing the initial demand: https://github.com/odoo/enterprise/blob/c26c21cec14a234021bb13bbc2684334bc64b70b/stock_barcode/models/stock_move.py#L50-L53 THe first time you enter the picking you have a single move with a quantity of 10. The first time you exit, since you have set a qty_done of 1 (and hence have updated the quantity of the associated move to 1), the `split_uncompleted_moves` will then create a move for a quantity of 9 in order to keep 10 units assigned. The second time you enter the picking both moves are grouped in a single line since the product is tracked by lot, however, when you update the qty_done of that grouped line you will actually only update the quantity of the first move line and its related move. Since the `_truncate_overreserved_moves` was not designed to handle these grouped lines, it does not notice that the combined reservation overcomes the actual demand. opw-4731803 Forward-Port-Of: odoo/enterprise#90586 Forward-Port-Of: odoo/enterprise#89967
The default 13th month salary rate for Swiss payroll contracts was adjusted from 8.33% to 8.3333%. This improves payroll calculation precision and helps ensure Swiss employee compensation is computed more accurately.
Original PR description
-changed the default contractual thirteen month rate for Switzerland from 8.33 to 8.3333 Forward-Port-Of: odoo/enterprise#92129 Forward-Port-Of: odoo/enterprise#92095
Swiss payroll declarations now show which required information is missing and which employees are affected before users send or print them. This helps payroll teams correct issues more easily and reduces failed or incomplete declarations.
Original PR description
It is currently complicated for non trained users to figure out what is missing before sending or printing a declaration. In this PR we extend the warning mechanism to declarations to visualize what information is missing on what employees. Forward-Port-Of: odoo/enterprise#92083 Forward-Port-Of: odoo/enterprise#86195
This fixes an error that could block customers from adding a new address during checkout on Colombian eCommerce websites. The address form now works correctly regardless of how the identification type field is displayed, helping customers complete purchases without interruption.
Original PR description
To reproduce: ============= 1- Install Colombia accounting 2- Install eCommerce 3- Set company address to Colombia 4- Go to website and add item to cart 5- Checkout & click "Add new address" →…
To reproduce: ============= 1- Install Colombia accounting 2- Install eCommerce 3- Set company address to Colombia 4- Go to website and add item to cart 5- Checkout & click "Add new address" → Traceback occurs Problem & Solution: =================== The field l10n_latam_identification_type_id is always present in the address form but its HTML element changes: it's rendered as a `select` when is_commercial_address and can_edit_vat is true, and as an `input` otherwise. The JS code only looked for the `select`, so when the `input` was rendered instead, the selector was null and caused a traceback. Update the selector to look for the field in either `select` or `input` form, so the code works regardless of the rendering conditions. useful-links: https://github.com/odoo/odoo/blob/4806b08dcfc965cdbd463269be078f8da9f48863/addons/l10n_latam_base/views/portal_address_templates.xml#L10-L11 https://github.com/odoo/odoo/blob/4806b08dcfc965cdbd463269be078f8da9f48863/addons/l10n_latam_base/views/portal_address_templates.xml#L32-L33 opw-4969089 Forward-Port-Of: odoo/enterprise#91695
This fix prevents users from selecting internal bank reconciliation widget models in places like Knowledge properties. It avoids errors caused by choosing models that are not stored in the database and cannot support normal search operations.
Original PR description
To reproduce this issue, just try to perform a name_search/search_count/etc.. on `BankRecWidget` for example: - Example of Steps in Knowledge: - Open knowledge - Create an article - Create another article in the first one (child) - Add a properties - Select `Bank reconciliation widget` in Model - Traceback `BankRecWidget` and `BankRecWidgetLine` use ```py _auto = False _table_query = "0” ``` to avoid being stored in db. This kind of model doesn't work with several methods of the model api, such as `search_count`, `name_search` etc... This commit will add a models blacklist via ir_model._is_valid_for_model_selector opw-4763713 Forward-Port-Of: odoo/enterprise#90060 Forward-Port-Of: odoo/enterprise#88352
The Cash Flow report now handles grouping by account codes consistently, preventing an error that could block report generation in certain configurations. This helps finance users reliably view cash flow details when custom account code fields are present.
Original PR description
The term used by GROUP BY should be the same term in the SELECT, avoiding the posible error like: ERROR: column "account_move_line__account_id.code_store" must appear in the GROUP BY clause or be used in an aggregate function That appears when a column named account_code is created for the model account_move_line. opw-4963180 Forward-Port-Of: odoo/enterprise#91915
17 changes
Resolved issues and error corrections
Fixed an issue where opening My Requests in the Approvals app could fail when the same person appeared twice as an approver on one request. The system now safely uses one matching approver record, preventing the error and allowing users to view their approval requests normally.
Original PR description
#### Reproduce Approvals app -> My Approvals -> My Requests (Traceback Error) #### Issue The demo data contains a duplicate record for an approver (the user is set as default approver for the approval category and added again as record in xml data), so the request had 2 approvers with the same user. #### Fix Get the first record of filtered approvers for current user if there are many. task-4984137 Forward-Port-Of: odoo/enterprise#91806
A document sharing email template was corrected so it no longer references unavailable creator information. This prevents errors when document access records are created during upgrades, helping document sharing work reliably after migrations.
Original PR description
As `documents.access` records do not have `create_uid`, it isn't possible to reference it. This only comes up now as we've fixed the upgrade scripts to actually create this record (in odoo/upgrade#7959). Task-4480388 Forward-Port-Of: odoo/enterprise#92291
The update prevents users from selecting internal bank reconciliation widget models in places like Knowledge properties. This avoids errors when those models are used by features that expect normal database-backed records.
Original PR description
To reproduce this issue, just try to perform a name_search/search_count/etc.. on `BankRecWidget` for example: - Example of Steps in Knowledge: - Open knowledge - Create an article - Create another article in the first one (child) - Add a properties - Select `Bank reconciliation widget` in Model - Traceback `BankRecWidget` and `BankRecWidgetLine` use ```py _auto = False _table_query = "0” ``` to avoid being stored in db. This kind of model doesn't work with several methods of the model api, such as `search_count`, `name_search` etc... This commit will add a models blacklist via ir_model._is_valid_for_model_selector opw-4763713 Forward-Port-Of: odoo/enterprise#90060 Forward-Port-Of: odoo/enterprise#88352
A checkout issue affecting Colombian eCommerce websites has been fixed. Customers can now add a new address without the page crashing, improving checkout reliability.
Original PR description
To reproduce: ============= 1- Install Colombia accounting 2- Install eCommerce 3- Set company address to Colombia 4- Go to website and add item to cart 5- Checkout & click "Add new address" →…
To reproduce: ============= 1- Install Colombia accounting 2- Install eCommerce 3- Set company address to Colombia 4- Go to website and add item to cart 5- Checkout & click "Add new address" → Traceback occurs Problem & Solution: =================== The field l10n_latam_identification_type_id is always present in the address form but its HTML element changes: it's rendered as a `select` when is_commercial_address and can_edit_vat is true, and as an `input` otherwise. The JS code only looked for the `select`, so when the `input` was rendered instead, the selector was null and caused a traceback. Update the selector to look for the field in either `select` or `input` form, so the code works regardless of the rendering conditions. useful-links: https://github.com/odoo/odoo/blob/4806b08dcfc965cdbd463269be078f8da9f48863/addons/l10n_latam_base/views/portal_address_templates.xml#L10-L11 https://github.com/odoo/odoo/blob/4806b08dcfc965cdbd463269be078f8da9f48863/addons/l10n_latam_base/views/portal_address_templates.xml#L32-L33 opw-4969089 Forward-Port-Of: odoo/enterprise#91695
Portal templates in Field Service Sales were corrected after a recent subsection change caused display issues. This helps ensure customers and users see the intended layout without template errors.
Original PR description
\* industry_fsm_sale This commit fixes templates broken after the introduction of subsection in the section and note field ([1]). We wrote owl like "t-att-class" in python templates. task-5005432 [1]: https://github.com/odoo/enterprise/pull/91411
This fix ensures newly created salary offers appear when users return to applicant or employee offer lists. It also automatically fills the employee field when creating an offer from an employee record, reducing manual entry and confusion.
Original PR description
…ee field - = hr_contract_salary Steps: - Navigate to Recruitment > Job Positions > Applications> Offers - Now, create a New offer using the New button, and go back to offer list view - Navigate to Employee > Select an employee > Contract > Offers - Now, create a New offer using the New button, and go back to offer list view - Navigate to Employee > Select an employee > Contract > Offers - Now, click on New button to open offer form. Issues: - New offer is not included in list for applicants when returning via breadcrumb - New offer is not included in list for employees when returning via breadcrumb - Employee field is not pre-populated when creating a new offer for employee Fix: - Modified smart button action for applicants - Modified smart button action for employees - Computed the employee field to be autofilled Task - 4787302 Forward-Port-Of: odoo/enterprise#91452 Forward-Port-Of: odoo/enterprise#86160
Fixed an error in the Spanish SME Balance Sheet that could make certain group company investment amounts appear twice. This helps businesses using the Spain SME localization rely on accurate balance sheet figures for reporting and review.
Original PR description
Issue: - Amounts were exactly doubled in 'Current Investments in Group Companies and Associates' in the Spanish Balance Sheet - SMEs report as account codes 5523 and 5524 were incorrectly added to…
Issue: - Amounts were exactly doubled in 'Current Investments in Group Companies and Associates' in the Spanish Balance Sheet - SMEs report as account codes 5523 and 5524 were incorrectly added to multiple balance sheet sections Root Cause: - Account codes 5523% and 5524% were included in BOTH: 1. 12400 (Assets): 'Current investments in group companies' 2. 32400 (Liabilities): 'Group companies current liabilities' - This double-counting caused investment amounts to appear twice in the balance sheet How to Reproduce: 1. with Spain - SMEs Fiscal Localization's Package 2. Go to Accounting -> Configuration -> Journal -> Bank 3. Change suspense account to code 5523X or 5524X (should be added to chart of accounts before) 4. Post journal entries to accounts 55230X or 55240X 5. Generate 'Balance Sheet - SMEs (ES)' report 6. Observe amounts are exactly doubled compared to account balances Fix: - Removed duplicate account codes from balance_pymes_line_12400_sub_balances - These accounts are properly handled by the domain formula in line 32400 - Each account code now appears in only one balance sheet section" opw-4983300 Forward-Port-Of: odoo/enterprise#92210
Swiss payroll declarations now show which employee details are missing before users send or print them. This helps payroll teams correct issues more easily and reduces confusion for users who are not familiar with the declaration process.
Original PR description
It is currently complicated for non trained users to figure out what is missing before sending or printing a declaration. In this PR we extend the warning mechanism to declarations to visualize what information is missing on what employees. Forward-Port-Of: odoo/enterprise#92144 Forward-Port-Of: odoo/enterprise#86195
The default Swiss payroll rate for the contractual 13th month has been adjusted from 8.33% to 8.3333%. This improves payroll calculation precision for Swiss employees and helps avoid small rounding discrepancies.
Original PR description
-changed the default contractual thirteen month rate for Switzerland from 8.33 to 8.3333 Forward-Port-Of: odoo/enterprise#92231 Forward-Port-Of: odoo/enterprise#92095
Payslips now show the correct weekly hours when an employee uses a flexible working schedule. Finalized or paid payslips also keep the hours that applied at the time they were completed, so later schedule changes do not alter printed records.
Original PR description
Steps to reproduce: - Enable "Flexible Hours" in a working schedule. - Assign the schedule to an employee. - Generate a payslip for the employee. - Observe that the "Working Schedule" section always…
Steps to reproduce: - Enable "Flexible Hours" in a working schedule. - Assign the schedule to an employee. - Generate a payslip for the employee. - Observe that the "Working Schedule" section always shows `hours_per_week` from the total hours calculated from the Work Schedule defined before turning on "Flexible Hours" Description: - the payslip incorrectly displayed the weekly working hours from the Work Schedule regardless of whether the employee's schedule used flexible hours. - also, if we changed the work schedule timings, after the payslip is in 'done' or 'paid' state, and printed it again, it will print the changed hours, which is not desired, the payslip should print hours same as when it was done. Cause: - the report template did not check for the `flexible_hours` flag and always rendered the value from `contract_id.hours_per_week`. Fix: - added a condition in the payslip template to check if `flexible_hours` is enabled. - if true, it displays `full_time_required_hours` from the working schedule instead of the contract's `hours_per_week`. - also, now we will also check the state of the payslip, in order to print the right hours even after setting it to 'done' or 'paid' and the schedule changes! task-4719717
This fix stops OCR processing from replacing an expense name that a user has already edited after upload. It helps ensure employee-entered expense descriptions are preserved and avoids confusion from unexpected name changes.
Original PR description
This commit https://github.com/odoo/odoo/commit/ca1f644a3c15f17482f56a2ece2a57f0f03098ff introduced the "untitled expense" title for expense when being uploaded. The user can then change manually the name. However, if the OCR is called after, it overrides the name previously set by the user. Therefore, if the name of an expense starts with "Untitled Expense", the OCR should not override the name. task-4653999
German EC Sales List CSV exports now include the required version information expected by the Elster portal. This prevents valid reports from being rejected during upload and helps businesses submit their VAT-related declarations without manual corrections.
Original PR description
When uploading the EC Sales List csv to Elster.de portal, users will see the file rejected with the following error (EN translated) """ Your CSV file was created for an older version of the CSV interface. Please refer to the version table in the import help for the latest version of the interface and any changes. If the version information is correct, please check the encoding of your CSV file. The permitted encoding is UTF-8. """ This occurs because the csv is missing the version strings identifying the versions of data format References: https://www.elster.de/eportal/helpGlobal?themaGlobal=zmdo_import_eop https://www.datev-community.de/t5/Betriebliches-Rechnungswesen/Import-CSV-Daten-nacvh-Elster-f%C3%BCr-ZM/td-p/480079 opw-4850314 Forward-Port-Of: odoo/enterprise#92110
Fixes an issue where Mexican POS orders paid with eWallet could be stopped before the payment screen because a tiny tax rounding difference appeared as a negative remaining balance. The system now treats these near-zero amounts correctly, helping cashiers complete affected sales smoothly.
Original PR description
Before this commit, paying an order with eWallet could result in a small negative residual amount (due to tax calculation), instead of zero. This prevented users from proceeding to the payment screen. With this commit, the "lt" function is used to compare amounts while taking rounding precision into account, ensuring the residual is treated as zero when appropriate. opw-4867365 Forward-Port-Of: odoo/enterprise#91756 Forward-Port-Of: odoo/enterprise#88275
This fixes an internal subscription test that could fail when run outside the year 2025. It helps keep automated quality checks stable over time without changing customer-facing subscription behavior.
Original PR description
Before this commit, when test_uninvoiced_upsell_close_log was launched in a year different than 2025, it would fail with the following error: ``` File…
Before this commit, when test_uninvoiced_upsell_close_log was launched in a year different than 2025, it would fail with the following error:
```
File "/data/build/enterprise/sale_subscription/tests/test_sale_subscription.py", line 2085, in test_uninvoiced_upsell_close_log
action = subscription.prepare_upsell_order()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/build/enterprise/sale_subscription/models/sale_order.py", line 1042, in prepare_upsell_order
action = self._prepare_renew_upsell_order('7_upsell', upsell_msg_body)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/build/enterprise/sale_subscription/models/sale_order.py", line 1012, in _prepare_renew_upsell_order
order = self._create_renew_upsell_order(subscription_state, message_body)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/build/enterprise/test_sale_subscription/models/sale_order.py", line 228, in _create_renew_upsell_order
order = super()._create_renew_upsell_order(subscription_state, message_body)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/build/enterprise/sale_subscription/models/sale_order.py", line 998, in _create_renew_upsell_order
values = self._prepare_upsell_renew_order_values(subscription_state)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/build/enterprise/project_sale_subscription/models/sale_order.py", line 40, in _prepare_upsell_renew_order_values
res = super()._prepare_upsell_renew_order_values(subscription_state)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/build/enterprise/partner_commission/models/sale_order.py", line 72, in _prepare_upsell_renew_order_values
values = super()._prepare_upsell_renew_order_values(subscription_state)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/build/enterprise/sale_subscription/models/sale_order.py", line 1182, in _prepare_upsell_renew_order_values
raise UserError(_('You cannot create an upsell for this subscription because it :\n'
odoo.exceptions.UserError: You cannot create an upsell for this subscription because it :
- Has not started yet.
- Has no invoiced period in the future.
```
runbot-task-230716
Forward-Port-Of: odoo/enterprise#92307This update corrects access permissions used by automated tests for Australian payroll accounting. It helps ensure payroll and accounting checks run reliably without failing because the test user lacks the right access groups.
Original PR description
[FIX] l10n_au_hr_payroll_account: missing groups The common test file is accessing models in account and hr modules but the user miss groups to have access to them. runbot-230912
Demo employee records in several country-specific payroll modules now use the correct payroll structure type. This helps demo environments show accurate payroll behavior and reduces confusion during evaluations, testing, or training.
Original PR description
Some employees on demo data don't have the correct structure type. This solves this issue. Task: 4890507 Forward-Port-Of: odoo/enterprise#88487
This update adjusts the appointment website test configuration so newly exposed snippet layouts are recognized correctly. It helps keep automated quality checks stable after a related website editor change, with no expected impact on daily users.
Original PR description
Starting from [1], the various dynamic snippet layouts are directly accessible from the snippet selection dialog instead of using the "Templates" option. The goal of this commit is to simply add the new snippets keys in the "sub-snippet templates" config to prevent the snippets drag and drop test from failing. [1]: https://github.com/odoo/odoo/commit/e3b062e5d3820ddfcee2eb669f21edc0c53c3330 runbot-230822 Community PR: https://github.com/odoo/odoo/pull/223010
26 changes
Resolved issues and error corrections
This fixes an automated live chat chatbot check that could fail because it moved on before changes were fully saved. The update waits for saving to finish, helping keep quality checks stable without changing customer-facing behavior.
Original PR description
This commit fixes the "change_chatbot_step_type" tour which fails because it doesn't wait for the form to be properly saved. This commit fixes the issue by waiting until the save button disappears. fixes runbot-229962 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 change removes an unnecessary warning caused by the use of an outdated internal method in inventory valuation logic. It helps keep system logs cleaner without changing day-to-day user workflows.
Original PR description
Before this commit a deprecated method is used and create a useless warning. 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
Purchase catalog prices are now converted from the vendor's currency into the purchase order currency. This prevents buyers from seeing mismatched prices when adding products through the catalog, improving accuracy for requests for quotation and purchase orders.
Original PR description
Before this commit, the unit price in the catalog for purchase order wasn't converted from other currencies to the order one It was just set to the price regardless of the vendor currency This fix will automatically convert the catalog prices from seller's currency to purchase.order's currency Steps to reproduce: - Create a product to Purchase - Add a vendor in the Purchase Tab - Set quantity to 1, price to 100 and currency to EUR - Create a RFQ - Select the Vendor from the product created - Check to currency to be USD - Add the product and take note of the Unit Price - Remove the product line - Go to Catalog - Compare the Price with the Unit Price (They doesn't match before the fix) opw-4909789
Non-admin users can now update settings on recurring calendar meetings without being blocked by an access error. This keeps everyday calendar management working smoothly for users who do not have administrative permissions.
Original PR description
**Issue:** An access error occurs when a non-admin user attempts to modify the meeting settings of a recurring calendar event. **Steps to reproduce:** - Log in as non admin user - Go to Calendar > Create new meeting. - Set Reminders - Check the Recurrent checkbox and save the event. - Edit the Recurring Event settings and save again (2–3 times) An access error is raised as non admin users aren't allowed to read ir.cron.trigger opw-4899572
Confirming a sales order for a service that creates a project no longer removes analytic accounts that users already added manually. This prevents extra rework and helps mandatory accounting allocations remain in place for invoicing.
Original PR description
Problem: When a user creates an analytic distribution model and is applied to a product that creates a project when ordered, any other analytic account, that are not included in the distribution…
Problem: When a user creates an analytic distribution model and is applied to a product that creates a project when ordered, any other analytic account, that are not included in the distribution model, added to the quotation will get overwritten upon confirming the quotation. The override on `_compute_analytic_distribution` in sale_project depends on the order's project. In the case where a project gets created upon order, the compute will trigger, which effectively recomputes the analytic distribution based on the model, overwriting other analytic account not defined on the model. Solution: The override on `compute_analytic_distribution` in sale_project should not call `super` when it gets triggered based on any change to the order's project. If the compute is triggered based on a change to the order's project, only the project's analytic account should get added onto the existing analytic distribution on the sale order line. This will ensure that any other analytic accounts added to the sale order line will not get overwritten by the recompute. Purpose: Implementing this change will save the user the extra step of needing to add the mandated analytic accounts again to the sale order line. Before the change, the user will need to add the mandated analytic account in order to confirm the quotation. Since the mandated analytic account gets overwritten from the compute based on the distribution models, the user will have to add the mandated analytic account back to the sale order line in order to create an invoice. Steps to Reproduce on Runbot: 1. Install Sales, Accounting, Project 2. Enable Analyic Accounting in Settings > Analytic Accounting 3. Create an Analytic Distribution Model with 2 different analytic account and set the product category to All 4. Create a new analytic plan that is mandatory 5. Create a new analytic account linked to the new analytic plan 6. Create a new product that is a service under the 'All' category and creates a project on order 7. Create a sales order with the new product and notice that the analytic distribution is from the model and not from the mandated analytic plan. 8. manually Add the mandated analytic account 9. Confirm the sales order and notice that the mandated analytic account is gone opw-4934291 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Timesheet entries under one hour now reduce a project's remaining time by the exact number of minutes entered instead of rounding to whole hours. This gives users more accurate project time tracking and prevents misleading remaining-time estimates.
Original PR description
_______________________________________ ## Short functional explanation of the error When a user encodes an amount of minutes below 30, the estimated time remaining for the task doesn't change. But…
_______________________________________ ## Short functional explanation of the error When a user encodes an amount of minutes below 30, the estimated time remaining for the task doesn't change. But when the user encodes an amount above 30, but below 1 hour, the estimated time decreases of 1 hour. ## Reproduction Steps 1. Go to the Timesheets application. Click on the Timesheets tab and click on "All timesheets". 2. For any user, click on "Add a line" and create a test project. 3. Click on the project you created and set the allocated time to 8 hours, for example. 4. Go back to all timesheets. You should be able to see the remaining time. 5. For this project, add an entry of 15 or 45 minutes, depending on the case you would like to test. 6. Refresh the page. ### Expected behavior If the entry was set at 45 minutes, the estimated remaining time should be 7:15. If the entry was set at 15 minutes, the estimated remaining time should be at 7h45. ### Unexpected behavior If the entry was set at 45 minutes, the estimated remaining time shown is 7:00. If the entry was set at 15 minutes, the estimated remaining time shown is 8h00. ## Origin of the issue The estimated time was an integer which was rounded in the code. _________________________________________ opw-4988446 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr 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
Card mailing recipients who share the same email address are no longer incorrectly treated as duplicates when their personalized card links differ. This helps ensure intended recipients receive their individualized card messages instead of being skipped during batch sending.
Original PR description
When sending a card mailing to recipients with duplicate emails, they are always considered duplicate emails. This is because: 1) We use "body" to detect duplicate emails, but "body" is never updated with the individualized card url. We now update the "body" as in the context of a mailing, "body_html" is just a copy of "body". 2) Mailings consider that all emails are always the same, meaning if it's detected that a mail was already sent to an email address during the mailing (in a previous batch) it would skip the actual duplicate body check. We disable that feature for card mailings. task-5009229
Confirmed repair orders can now keep kit components added after confirmation. This prevents those kit parts from disappearing after saving, helping repair teams maintain accurate component lists and avoid rework.
Original PR description
Steps to reproduce the bug: - Create a repair order with any component. - Confirm the order. - Try to add a kit as a component. Problem: After saving, the kit disappears. When a kit is added to a confirmed repair order, its move should be confirmed and therefore exploded. However, the moves created from this kit move are just copies of the original move. Fields with copy=False are not copied, including the repair_id field. In this case, repair_id must be added to link the move to the repair order, so it needs to be set manually. opw-4937817
This change updates HR tests so they run correctly in databases without demo data. It helps prevent false test failures and supports more reliable validation before releases.
Original PR description
Before this commit the test `test_webjson_employees` was failing in no demo builds as the json route only works in demo databases or when explicitly set. See https://github.com/odoo/odoo/pull/182196 This commit enables the system parameter, so that the test can be run as intended in no demo databases. Runbot Error: https://runbot.odoo.com/odoo/error/162907 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This change adjusts an automated test for the HTML editor toolbar to reduce random failures. It helps keep development and release validation more stable without changing the product experience for users.
Original PR description
This is a deparate attempt to fix this test that keeps failing non-deterministically. Previous attempts were [1] and [2]. [1]: https://github.com/odoo/odoo/pull/222583 [2]: https://github.com/odoo/odoo/pull/222828
This fix prevents serial numbers from being duplicated on point-of-sale order lines after a page refresh. It ensures tracked product serial details are saved and removed correctly, reducing order confusion and improving checkout accuracy.
Original PR description
**Step to reproduce:** - start pos - add product tracked with serial number - refresh the page **Observation:** - serial number is attached twice in same orderline **Issue:** currently, when dealing…
**Step to reproduce:**
- start pos
- add product tracked with serial number
- refresh the page
**Observation:**
- serial number is attached twice in same orderline
**Issue:**
currently, when dealing with tracked product, we add the lots in values
values.pack_lot_ids = packLotLine.map((lot) => ["create", lot])
these values are used to create pos_order_line.
Now, in case of product tracked by 'serial' , we again call `setPackLotLines`
https://github.com/odoo/odoo/blob/b3b0a0959ae12f53f702c359c1205d89a8e92ffb/addons/point_of_sale/static/src/app/store/pos_store.js#L897-L901
there, we remove the initially added lot and again add the same lot, (with new id).
but the old one is not properly unlinked from indexed db.
```
for (const lotLine of lotLinesToRemove) {
this.pack_lot_ids = this.pack_lot_ids.filter((pll) => pll.id !== lotLine.id);
}
```
hence on refresh, same lot (with different id) is attached to orderline.
**Fix:**
this pr tries to fix the issue at both places, we will add the lot only once
and also unlink the lot properly.
Note: issue only in 18.0, in higher version, SN vanishes after refresh
opw-4897882
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThe accounting dashboard now excludes draft invoices from the checked items view, so users only see invoices that have been formally posted. This helps finance teams avoid confusing draft work with confirmed accounting records.
Original PR description
state = posted has been added in 18.0 but removed in https://github.com/odoo/odoo/commit/68fa35faa332615a2862935a82f778e38a2a3041#diff-6e3139ca3c848ecd9159cbee86a94aa51a3c7e0d2b62bbccfac1023c18a1edf5L586 initial opw-4349684
This fix allows Odoo's website and report templates to work correctly when running on newer Python versions that generate longer internal expressions. It prevents valid templates from failing due to a technical compatibility limit, helping maintain reliable system behavior during Python upgrades.
Original PR description
Not entirely clear why it was apparently excluded, but apparently in 3.13 some qweb expressions require the use of `EXTENDED_ARG`. Specifically [1] makes the expression long enough that it needs at least one "long jump" which then requires an `EXTENDED_ARGUMENT`, here's the sizes for the expression in question in various Python versions: - 3.10: 102 bytes - 3.11: 188 bytes - 3.12: 214 bytes - 3.13: 272 bytes Thus it makes sense at at some point the earliest jumps in the expression (and `and`/`or` *are* jumps, since they're short-circuiting) would become "long". These increases in size can be due to a multitude of factors e.g. changes in inline cache details (3.11 and above), jumps becoming strictly typed and requiring `TO_BOOL` instructions (3.13), ... [1]: https://github.com/odoo/odoo/commit/cc68a012649f9eb331265deba3197abaf1700d97#diff-92dda03d204cc6ea8b7aacd0c07939843c83b1841f4a3049903844777d83c07bL154-R223 Forward-Port-Of: odoo/odoo#222939
This fix ensures Italian EDI withholding tax descriptions are sent as plain text instead of including hidden formatting tags. It prevents incorrect text from appearing in generated XML documents and helps keep electronic tax reporting accurate.
Original PR description
The description field of the tax record was changed from char to html. This can break the dit functionality, as it now inserts the html tags into the description field. This PR aims to format the field as plaintext before rendering the XML to avoid such isses. opw-4985645
Portal users can now view purchase orders that include products without images. The page skips missing product images instead of failing, preventing an error that blocked access to the purchase order view.
Original PR description
In the purchase order portal template (`purchase.purchase_order_portal_content`), `image_data_uri(line.product_id.image_128)` was called without checking if the product had an image, leading to a rendering error when `image_128` is False. Steps to reproduce the bug: - create a product without an image - create a purchase order with that product - partner: portal user (e.g joel) - connect as portal user - go to the purchase order - the portal view will raise an error because it tries to render an image Solution: Added a conditional check to only render the `<img>` tag if the product image exists, preventing template evaluation errors. opw-5013230
This change reverts a recent sales update that could cause rental order creation to fail when currency information was missing or inconsistent. It unblocks the planning-to-rental flow needed for hotel industry rental demos and restores expected order creation behavior.
Original PR description
"line.currency_id" might be empty or contain more than 1 value, resulting in a crash of the method. This reverts commit ced1335c38834d5ac31f27705a2f7a0047ca8cc2. Traceback discovered when creating a rental order from a resource (planning flow). <img width="1607" height="907" alt="image" src="https://github.com/user-attachments/assets/0980b89b-fc2a-4bfe-a4c7-a290c92bb0e4" /> Quick revert needed to unblock the flow and allow a demo of hotel industry rentals.
This fix ensures a manufacturing test setup has the needed product variant permissions when demo data is not installed. It reduces the risk of false test failures and helps keep manufacturing-related updates reliable.
Original PR description
### Issue: The setUpClass of the `TestMultistepManufacturingWarehouse` test class fails without demo data since the `product_id` field is invisible in the bom view when the `product.group_product_variant` and is not automatic without demo data's: https://github.com/odoo/odoo/blob/7391082cfa42afdc62d17f1dac5cad97cf177e81/addons/product/data/product_demo.xml#L4-L7 https://github.com/odoo/odoo/blob/7391082cfa42afdc62d17f1dac5cad97cf177e81/addons/mrp/views/mrp_bom_views.xml#L63 I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update makes an internal automated test for bus notifications more reliable by ensuring the test setup is fully ready before notifications are triggered. This helps prevent random test failures and supports smoother validation of future changes, with no expected impact on end users.
Original PR description
This commit fixes the `test_postcommit` that fails in a non deterministic fashion. This test ensures bus notifications created in the post commit hook result in only one batch. To do so, the test listens on the connection with a selector. However, the main thread doesn't wait for the selector to be register before triggering the postcommit hook. This commit ensures the test waits for the selector to register the database connection before going further. runbot-77470 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#222810
This fix ensures simulated time changes are only applied to the intended active database during testing. It prevents unrelated databases, such as logging databases, from being unintentionally affected and reduces the risk of confusing test side effects.
Original PR description
Filtering the postgres database was not enough, the log_db was also affected. Since only the order was impacted, this was creating strange side effect in databases like the log-db where it was only modified when the function exists. Checking the -d is more reliable and safer to avoid any side effect when testing with faketime. Forward-Port-Of: odoo/odoo#222805
Belgian and French reports now compare totals in a way that accounts for tiny rounding differences. This prevents reports from incorrectly flagging mismatches when the displayed amounts are effectively the same.
Original PR description
Currently, the code was checking for a strict equality between two sums. However, it may happen that there are many decimals that aren't displayed on the UI, hence the strict equality check fails. For instance `30201.63 != 30201.629999999997`. Instead, we now use the `float_compare` which takes care of rounding issues. opw-5000147
Subscription invoices now link only the timesheets that belong before the next invoice date. This prevents hours from the next billing period from being attached to the current invoice and accidentally excluded from future billing.
Original PR description
Problem: When the user invoices a product based on timesheet from a subscription in a given month, the timesheets linked to the invoice incorrectly includes timesheets dated the same as the next…
Problem: When the user invoices a product based on timesheet from a subscription in a given month, the timesheets linked to the invoice incorrectly includes timesheets dated the same as the next invoice date of the subscription. This occurs if the client does not specify a timesheet period when creating the invoice. For example, the user invoices a subscription for the period of July 1st to July 31st and the next invoice date of the subscription is August 1st. There are timesheets dated in July and a timesheet dated August 1st. The quantity delivered for the invoice will only include timesheets within the July period. However, the linked timesheet to the invoice will mistakenly include the timesheet from August 1st. Purpose: Although the linked timesheet has no effect on the computation of qty_delivered for the current period, the timesheets dated the same as the next_invoice_date will get linked to the invoice and no longer be considered as delivered hours for the next period, which could cause gaps in hours delivered. The next_invoice_date should not be included in the date range when linking timesheets within the period of the invoice, since these hours were not included in the computation of quantity delivered. Steps to reproduce on Runbot: 1. Install Sales, Project, Timesheet 2. Enable Timesheet in Project > Settings 3. Create a service product that is based on timesheet and creates project and task on order 4. Create a quotation for the service product and set the recurrence to be monthly and set the start date to be the first of the past month 5. Confirm the quotation and set the next invoice date to be the first of the current month 6. Create timesheet hours within the period and one dated to be the first of the current month 7. Create an invoice for the subscription and notice that the timesheet from the first of the current month is linked to the invoice. opw-4689894
The Belgian payroll departure wizards now only show employees from the company the user is currently working in. This prevents confusion and accidental selection of employees from other companies in multi-company environments.
Original PR description
Added a domain to employees to limit the employee field in the departurre wizard to the logged in company **Steps to reproduce:** - Log into a Blgian Company - Access the Departure wizard through Payroll/Reporting or through the cog actions in an employee. **Issue:** Previously, when using the departure wizard, the employees shown were all the employees across different companies, when in reality it should be employees of the logged in company only **Fix:** Added employee domain so that it allows employees from the current logged in company only Task: 4965719 Forward-Port-Of: odoo/enterprise#90813
A payroll accounting test was missing a required dependency for Colorado tax calculations. Adding this dependency ensures the Colorado test case can run reliably and helps prevent false failures in payroll validation.
Original PR description
Issue: - Test case fails for the U.S. state of Colorado because the COINCOMETAX salary rule is defined in the l10n_us_hr_payroll_state_calculation module, but the test module test_l10n_us_hr_payroll_account does not depend on it. Fix: - Add a dependency on l10n_us_hr_payroll_state_calculation in the test_l10n_us_hr_payroll_account module. task-4949218
Upgrading the Colombian DIAN localization no longer removes the invoice and credit note email templates used for DIAN communications. This helps businesses keep their configured sending templates intact and avoids disruption after module updates.
Original PR description
**Steps to reproduce:** - Install l10n_co_dian => "Invoice (DIAN): Sending" and "Credit Note (DIAN): Sending" email templates are created - Upgrade l10n_co_dian **Issue:** "Invoice (DIAN): Sending" and "Credit Note (DIAN): Sending" are deleted. **Cause:** Email templates are reset during a module upgrade. These DIAN email templates are not defined in a XML, but created by a python function. This function is only called during installation. **Solution:** Set the "nopupdate" to True for these email templates to prevent them to be reset during the module upgrade. opw-4964347
Payslips now show the right weekly working hours when an employee uses a flexible-hours schedule. This prevents incorrect schedule information from appearing on payroll documents and improves clarity for employees and payroll teams.
Original PR description
> note: this PR should only be FW'd till `saas~18.4`, after that for `saas~18.5` (i.e., `master`), [this PR](https://github.com/odoo/enterprise/pull/85557) should be merged. ### Steps to reproduce: -…
> note: this PR should only be FW'd till `saas~18.4`, after that for `saas~18.5` (i.e., `master`), [this PR](https://github.com/odoo/enterprise/pull/85557) should be merged. ### Steps to reproduce: - Enable "Flexible Hours" in a working schedule. - Assign the schedule to an employee. - Generate a payslip for the employee. - Observe that the "Working Schedule" section always shows `hours_per_week` from the total hours calculated from the Work Schedule defined before turning on "Flexible Hours" ### Description: - the payslip incorrectly displayed the weekly working hours from the Work Schedule regardless of whether the employee's schedule used flexible hours. ### Cause: - the report template did not check for the `flexible_hours` flag and always rendered the value from `contract_id.hours_per_week`. ### Fix: - added a condition in the payslip template to check if `flexible_hours` is enabled. - if true, it displays `full_time_required_hours` from the working schedule instead of the contract's `hours_per_week`. task: 4719717
This fixes a conversion issue when portal users upload Excel files into shared document folders. Portal users are now kept at view-only access on converted spreadsheets, preventing errors and preserving the intended sharing restrictions.
Original PR description
Let's say a Document Folder is shared with a portal user with 'edit' access. The portal user shares a .xlsx file to the folder, and an internal user later try to convert the file to odoo spreadsheet. During the conversion, the portal user has 'edit' role on the folder, which is copied to the documents.access records of the converted sheet. Since Odoo prevents Spreadsheets from being shared in edit mode to portal users, _check_spreadsheet() raises a Validation Error. <img width="544" height="188" alt="image" src="https://github.com/user-attachments/assets/48426ff8-0cd9-4fb0-8e52-31099e586064" /> To resolve this issue, we force portal users to have `view` role on Spreadsheets during the XLSX to Spreadsheet conversion. opw-4753670