Daily updates from Odoo
Friday, October 31, 2025
14 changes · master
Resolved issues and error corrections
This fix prevents overlapping work order time tracking entries from being wrongly removed or changed when manufacturing orders are saved. It keeps displayed work order duration and saved time records consistent, improving reliability for production tracking.
Original PR description
#### Issue: In this bug, workorder duration inverse is causing some time_ids to be deleted. To reproduce: 1- Create a db with mrp installed, and enable work orders in Setting 2- Create a MO, and…
#### Issue:
In this bug, workorder duration inverse is causing some time_ids to be deleted.
To reproduce:
1- Create a db with mrp installed, and enable work orders in Setting
2- Create a MO, and confirm it
3- Add a new work order to the MO
4- Add two time tracking lines:
- First one 10:00 -> 12:00
- Second one 10:00 -> 11:00
5- As you see, duration reflects duration of first line as it is the interval duration
6- Save and close work center form. Then save MO form.
7- Open work orders again: As you see second line is unlinked
#### Cause:
The reason to this bug, is because in Enterprise, the `_compute_duration` override changes the logic of how duration is computed but the inverse function doesn't reflect the same logic.
To be specific this is the compute function override: https://github.com/odoo/enterprise/blob/3cbe2bbbfd989a3daaa32769a843aeaa09c7ed3e/mrp_workorder/models/mrp_workorder.py#L757-L766
In which duration is calculated using get_duration: https://github.com/odoo/enterprise/blob/3cbe2bbbfd989a3daaa32769a843aeaa09c7ed3e/mrp_workorder/models/mrp_workorder.py#L828-L837
Which doesn't sum the durations, but calculates the intervals duration counting overlaps only once.
However, there is no override of inverse method in Enterprise, meaning that the logic behind inverse will not match with this logic. In the inverse it is assumed duration is sum of all time_ids intervals: https://github.com/odoo/odoo/blob/9b286285a6c66bc2d629eacf651c3439cffb55cc/addons/mrp/models/mrp_workorder.py#L355-L400
As a result, if time_ids overlap:
new_order_duration < old_order_duration
As a result some time_ids will be unlinked and some will have duration changed.
#### Fix:
Inside the inverse function in Community we can do:
```diff
+ old_order_duration = order.get_duration()
- sum(order.time_ids.mapped('duration'))
```
As get_duration in Odoo Community is:
https://github.com/odoo/odoo/blob/9b286285a6c66bc2d629eacf651c3439cffb55cc/addons/mrp/models/mrp_workorder.py#L889-L899
The order.get_duration will be sum of duration of all time_ids in community, hence the logic will be unchanged.
In Enterprise, this is going to reflect the logic implemented in override of get_duration, as a result the duration logic will be consistent in compute and inverse function.
However, this might cause another issue:
If `order.duration` is not computed yet, and inverse method `_set_duration` is called, then `get_duration` inside `_set_duration` will be called before the `get_duration` in compute method. As a result there might be a small unexpected time difference between `old_order_duration` and `new_order_diuration`. To avoid that inside `get_working_duration` we can use cursor now instead:
```diff
+ now = self.env.cr.now()
- now = datetime.now()
```
opw-5082477
Forward-Port-Of: odoo/enterprise#96632Fixed an issue where closing a live chat window did not end the conversation when the final human agent left. This ensures customers and support teams see accurate chat status and prevents conversations from remaining open incorrectly.
Original PR description
*: ai_website_livechat, test_discuss_full_enterprise Before this commit, when the last agent from a live chat conversation leave, the live chat conversation did not end. Steps to reproduce: - install…
*: ai_website_livechat, test_discuss_full_enterprise Before this commit, when the last agent from a live chat conversation leave, the live chat conversation did not end. Steps to reproduce: - install "ai" and "im_livechat" modules - have a visitor initiate a live chat conversation with 1 available human agent - have have human agent open conversation in chat window and close chat window + confirm button => the live chat conversation does not end When live chat agent is about to close the chat window of live chat, there's a warning to tell that this will make him/her leave the conversation and thus end the conversation. When proceeding, it doesn't actually do this. This is a bug caused by overrides of `ChatWindow._onClose()`, which is a function invoked during the closing of chat window, that has an option `notifyState` that determines whether the user leaves the conversation or not. The overridden code had to ensure the param is preserved and passed to `super` calls, but they fail to do this, and thus the closing of chat window is not making the user leave the conversation. This commit fixes the issue by passing `...arguments` to super calls to make sure the params are preserved as expected by original code of the `_onClose` function. Note that we had a test for the good working of the feature, but this test run with `im_livechat` assets and not overrides on top of it such as `ai` module. The main culpit of the problem was caused by the override in `ai` module. To have test coverage for this problem, the test is not executed in both `im_livechat` test suite and the `test_discuss_full_enterprise`, which is a module whose HOOT suite runs code of discuss with all overrides such as `ai` module. Forward-Port-Of: odoo/enterprise#98481
Ecuadorian vendor bill imports now select purchase taxes instead of accidentally applying sales taxes with the same rate. This helps keep imported supplier bills accurate and reduces manual correction work for accounting teams.
Original PR description
### Issue:
When importing a bill, some sale taxes are added to the lines.
### Steps to reproduce:
- Install 'l10n_ec_edi' and switch to an Ecuadorian company
- Accounting > Vendor > Bill
- Import an XML fill with a tax of 15%
- The created lines use the tax "VAT 15% G" which is a sale tax
### Cause:
The search to get the tax takes the first one from the right tax group.
### Solution:
Added `('type_tax_use', '=', 'purchase')` in the search domain to only retrieve purchase taxes.
opw-5174139
Forward-Port-Of: odoo/enterprise#98188Vendor bill imports for Chilean electronic documents now recognize numeric currency codes as well as standard currency abbreviations. This prevents import failures when suppliers send valid XML files using numeric currency values, with a safe fallback to Chilean pesos if the currency cannot be matched.
Original PR description
### Steps to reproduce: - Install "l10n_cl_edi" and switch to a Chilean company - Go in Accounting > Vendor > Bills - Import an XML with the line `<Moneda>013</Moneda>` - Traceback ### Cause: `Moneda` can be the currency name code like `USD` but also a numeric code corresponding to the currency. ### Solution: Add a dictionary linking codes to the currency names and check the dictionary if `Moneda` is numeric. Also add a fallback on `CLP` in case the value of `Moneda` fails to be translated to a currency. This avoids a traceback later when reading `vals['currency_id']`. opw-5184950 Forward-Port-Of: odoo/enterprise#98067
Users who work across multiple companies can now assign themselves to planning slots for the company where their employee record exists, even when another company is set as current. This prevents silent failures and makes planning assignment behave as expected in multi-company setups.
Original PR description
_______________________________________ ## Short functional explanation of the error Let's say we have the scenario where a user has access to company_1 and company_2, but only has a corresponding…
_______________________________________ ## Short functional explanation of the error Let's say we have the scenario where a user has access to company_1 and company_2, but only has a corresponding employee in company_2. If the user selects company_1 and company_2 but keeps company_1 as his current company, and tries to assign himself a task that has been created for company_2, nothing happens. ## Reproduction Steps 1. As an admin, create a user with which you'll be able to log. Make sure that you have at least 2 companies created, and that the user has access to both. Create an employee for that user in company_2. 2. Select both companies. In planning, create a slot for company_2 and publish it. 3. Log in as the user you created. Make sure that the current company is company_1. Select company_2. 4. Go to planning and try to assign yourself to the slot you've just created as an admin ### Expected behavior Either an error message shows, or the employee is assigned to the slot for company_2 (as company_2 is selected). ### Unexpected behavior Nothing happens ## Origin of the issue When the current company isn't the one corresponding to the one the employee is in, even if another company is selected and contains the employee, self.env.user.employee_id is set at False _________________________________________ opw-4963674 --- Forward-Port-Of: odoo/enterprise#95933 Forward-Port-Of: odoo/enterprise#91616
Scanned purchase receipts are now correctly recognized as purchase documents instead of sales documents. This prevents the system from applying sales taxes where purchase taxes should be used, improving accounting accuracy for OCR-processed receipts.
Original PR description
Since task [4776275](https://www.odoo.com/odoo/project/2068/tasks/4776275) (commit [a7e9575](https://github.com/odoo/enterprise/commit/a7e9575d4c7fccff06db8a3ec2b9315d8ac33805)), the OCR is able to automatically detect and change a vendor bill into a receipt. The calls to `is_purchase_document` should have been updated to reflect that, but they weren't. Because of this, purchase receipts were considered as sale receipts, causing multiple issues such as sale taxes being selected instead of purchase taxes. task-none Forward-Port-Of: odoo/enterprise#98472
This fixes an error that could prevent users from generating analytic budgets when using the split option. Budget creation now completes reliably in this workflow, reducing interruptions for accounting teams.
Original PR description
Currently, on creating a budget using split budget causing an error. **Steps to Reporduce:** 1) Install **account_budget module(with Demo)** 2) Navigate to **Accounting>Accounting>Analytic Budget**…
Currently, on creating a budget using split budget causing an error. **Steps to Reporduce:** 1) Install **account_budget module(with Demo)** 2) Navigate to **Accounting>Accounting>Analytic Budget** 3) Click on `Generate` set `Analytic Plan` and click on `Split` Error: `ValueError: Cannot convert budget.line.achieved_amount to SQL because it is not stored` Root Cause: since [this commit](https://github.com/odoo/odoo/pull/224667/commits/53b4670b1ad375ffc3800fc3beb97e960f229dc6), a new aggregate spec `sum_currency` was added. As a result, the code at [1] is executed for currency-aware aggregates. From the line, `self._field_to_sql(self._table, fname, query)` the ORM tries to create an SQL expression for `achieved_amount`. Because `achieved_amount` is computed `_field_to_sql` fails and error is raised. Fix: Provide a default SQL expression for computed fields on Budget Line [1]: https://github.com/odoo/odoo/blob/af668f545676f72385c52629f8498edfe22219cd/odoo/orm/models.py#L1972-L2004 Used Reference: https://github.com/odoo/odoo/blob/d42102cac8fff3967cb605a897bbb0e8690464ed/addons/crm/models/crm_lead.py#L286-L298 sentry-6917352415 Forward-Port-Of: odoo/enterprise#98215
Users can now send SMS authentication messages for signing as long as they still have purchased SMS credits available. This prevents valid signing requests from being blocked when the remaining balance is below one full credit but still enough to pay for one or more SMS messages.
Original PR description
Before this PR, when the authentication method is SMS in a sign document, the check to decide whether the authentication SMS is sent out checks that the amount of owned credits is >=1. The correct approach would be to check that they are >= sms_price but this price depends on the phone number of the recipient (or its international prefix) which we still don't know at the time of this computation. Because of this, when the function was originally written, the check was set to >=1 since 1>sms_price for every country. This, however, blocks the user from sending messages when sms_price<num_credits<1 which could even be multiple sms. By switching the 1 to a 0 we allow to send every sms the user purchased credits for and the last sms (which would bring the credits to <0) will be blocked directly by the iap server. Task: 4876220
The barcode app now respects the delivery setting that blocks extra products when workers scan whole packages. This prevents unintended items from being added to deliveries, reducing picking errors and improving inventory control.
Original PR description
## Issue 1: "Allow Extra Products" option ignored for packages ### Steps to reproduce: - In the settings enable "Packages" - Go to Inventory > Configuration > Warehouse Management > Operation Types -…
## Issue 1: "Allow Extra Products" option ignored for packages
### Steps to reproduce:
- In the settings enable "Packages"
- Go to Inventory > Configuration > Warehouse Management > Operation Types
- Disable "Allow Extra Products" on the "Delivery" operation type
- Create two storable product P1, P2 and add on hand quantities
- 10 x P1 in a package PACK01
- 10 x P2 in a package PACK02
- Create and confirm a delivery for 10 unit of P1
- Open your delivery from the barcode app
- Scan PACK02
#### > The content of PACK02 is added to the delivery even thought it contains extra products.
### Cause of the issue:
The check for extra products is only applied when scanning individual products but is bypassed by package scan. To be more precise, the `barcode_allow_extra_product` option is checked in the public method `createNewLine`:
https://github.com/odoo/enterprise/blob/331442fd9cbd59d542432b2237299df9497ce241/stock_barcode/static/src/models/barcode_picking_model.js#L59-L80
While this method is called at new line creation when a product is scanned, scanning a package will add new lines during the `_processPackage` adn bypasses the rest of the `_processBarcode`:
https://github.com/odoo/enterprise/blob/331442fd9cbd59d542432b2237299df9497ce241/stock_barcode/static/src/models/barcode_model.js#L1261-L1267
The issue being that the `__processPackage` does not check the `barcode_allow_extra_product` option and creates its new lines via the private `_createNewLine` call:
https://github.com/odoo/enterprise/blob/331442fd9cbd59d542432b2237299df9497ce241/stock_barcode/static/src/models/barcode_picking_model.js#L1564-L1565
https://github.com/odoo/enterprise/blob/331442fd9cbd59d542432b2237299df9497ce241/stock_barcode/static/src/models/barcode_picking_model.js#L1655-L1667
https://github.com/odoo/enterprise/blob/331442fd9cbd59d542432b2237299df9497ce241/stock_barcode/static/src/models/barcode_picking_model.js#L1671
### Fix:
Since scanning a package is expected to add all its content to the picking, and since a package can not be split among two locations, it is necessary to check in advance if any product of its content is extra and avoid any update in this case.
## Issue 2: impossibility of package line removal
### State of the art:
There is currently no option to remove a package line from the barcode. In particular, once the option `show_entire_packs`(Move Entire Packages) is enabled on a picking type, you can not remove the package line once generated by a scan.
#### Steps to reproduce:
- In the settings enable "Packages"
- Go to Inventory > Configuration > Warehoue Management > Operation Types
- Enable "Move Entire Packages" on the "Delivery" operation type
- Create a storable product and add on hand quanties:
- 10 units in package PACK01
- 10 units in package PACK02
- Create and confirm a delivery for PACK01 (in the package lines)
- Open your delivery from the barcode app
- Scan PACK02
#### > The new line associated to PACK02 can not be removed by any mean
opw-4863621
opw-5080637
Forward-Port-Of: odoo/enterprise#97700
Forward-Port-Of: odoo/enterprise#96299The Australian payroll integration now uses updated IAP proxy connection URLs and a revised connection process. This helps keep payroll reporting and superannuation data exchanges working reliably while preserving existing connections.
Original PR description
Adds the new urls configured for the iap proxy. Adapts for the updated connection flow. This does not break any existing connections. Related PR: https://github.com/odoo/iap-apps/pull/1124 Forward-Port-Of: odoo/enterprise#95071
Users who are not administrators can now use the AI document sorting action when their documents are eligible for auto-sorting. This fixes missing access to the button and ensures AI can correctly identify destination folders, reducing manual re-upload work.
Original PR description
Purpose: -------- Non-admin users should be able to trigger the auto-sort of their documents (since anyways they could delete and reupload their documents, which will trigger the auto-sort). - The "Sort with AI" button was missing in the topbar for non-admin users. To fix this, a boolean `ai_has_sort_prompt` is added in the search panel values (the button was shown if `ai_sort_prompt` was set, which is only accessible by users with group_system) - The display name of folders is now the folder name if the env is sudo-ed even if the user has not access this folder (these folders are valid targets if they are in the `ai_sort_prompt`, but they were inserted as "Restricted Folder" so the LLM could not decide in which folder to move the document) - Add a few sudo's so that the auto-sort action can be triggered by a non admin user Task-5144695 Forward-Port-Of: odoo/enterprise#96874
Corrects Mexican payroll CFDI generation so the employment subsidy section is only included for the specific subsidy payment types allowed by the government. This prevents payroll submissions with other payment inputs from being rejected.
Original PR description
Bug: If we add other inputs to a payslip, in the CFDI, then sending to the government will fail. Cause: In the CFDI, the node 'SubsidioAlEmpleo' is present when it shouldn't. Fix: The node should be present only for other payments of code 002, 007 or 008, all related to subsidies. Task: 5224176 Forward-Port-Of: odoo/enterprise#98529
Requests for quotation created from approvals now use the currency configured for the selected vendor instead of defaulting to the company currency. This keeps purchasing amounts consistent with other RFQ creation flows and avoids currency mismatches when updating existing purchase orders.
Original PR description
Issue: When creating an RFQ from an approval, the created purchase order does not use the currency set on the vendor of the product. Rather, it uses the currency of the company, with the value converted based on the vendor's currency to get the price. This is not consistent with other ways we create RFQs, which all respect the vendor currency. Solution: Pass the vendor's currency into the values sent when creating the purchase order. In the case of modifying an existing purchase order, only modify purchase orders matching vendor's currency. opw-4549937 Forward-Port-Of: odoo/enterprise#98205 Forward-Port-Of: odoo/enterprise#97069
The Helpdesk website's "Browse Articles" button now sends portal users directly to the linked Knowledge article instead of an empty Knowledge home page. This prevents confusion and helps customers reach the intended self-service content faster.
Original PR description
To reproduce: ============= 1. Create a Helpdesk Team linked to a Knowledge Article 2. Access the Help page on website as a portal user 3. Click on "Browse Articles" button -> redirected to empty knowledge home portal view Problem: ======== before this commit, redirection was made through the method `redirect_to_article` which will later call `_redirect_to_portal_view` that doesn't use the `article` parameter anymore as there is a patch on the front side to handle the redirection to the articale through the router, but as the calls are server-side, the patch is not applied and the redirection fails. Solution: ========= instead of calling `redirect_to_article`, directly redirect to the article's `website_url`. opw-5114885 Forward-Port-Of: odoo/enterprise#98363