Daily updates from Odoo
Thursday, June 4, 2026
230 changes
22 changes
Resolved issues and error corrections
This update resolves an error that occurred when users created new accounts in the accounting module, specifically for the Mexican (l10n_mx) localization. A recent change made account codes optional, but the system was incorrectly handling the absence of a code. This fix ensures accounts are created correctly regardless of whether an account code is provided.
Original PR description
Currently, an error occurs when a user creates an account record. Steps to Reproduce: - Install `Accounting` and `l10n_mx` module with demo data. - Switch to `ZAPATERIA URTADO ÑERI` company. - Go to…
Currently, an error occurs when a user creates an account record. Steps to Reproduce: - Install `Accounting` and `l10n_mx` module with demo data. - Switch to `ZAPATERIA URTADO ÑERI` company. - Go to `Accounting` > `Configuration` > `Accounting` > `Chart of Accounts` and create a record. `TypeError: 'bool' object is not subscriptable` After a [recent commit], account codes became optional and can be removed. As a result, when a user creates an account without a code, the code attempts to check whether the first letter of the account code is in the debit codes [1]. Since the account code is False, it raises an error. This commit ensures that if the internal group of an account is asset or expense, the debit tag is assigned to the account. Otherwise, the credit tag is assigned to the account tags. [recent commit]: https://github.com/odoo/odoo/commit/c3313b336b9f1305c363097745926f2bdf61e277 [1]- https://github.com/odoo/odoo/blob/a60643538479caf29aefeec89b8d356d8d5439c7/addons/l10n_mx/models/account_account.py#L17-L20 sentry-7490691483 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an issue where Luxembourg tax reports were incorrectly generating company registry numbers instead of the agent's RCS number when a natural person accountant wasn't linked. The fix ensures the correct RCS number is included in the XML, preventing rejection by Luxembourg tax authorities. This ensures compliance and accurate reporting.
Original PR description
**Steps to reproduce:** * install `l10n_lu_reports`. * Create a company in Luxembourg with a `company_registry` number set. * Link this company to an accounting firm that is a natural person…
**Steps to reproduce:** * install `l10n_lu_reports`. * Create a company in Luxembourg with a `company_registry` number set. * Link this company to an accounting firm that is a natural person (independent accountant) with no business registration number — i.e. `l10n_lu_agent_rcs_number` is left empty on the agent partner. * Go to the tax report and generate the XML declaration. **Observed behavior:** * The `<Agent><RCSNbr>` field in the generated XML contains the company's own `company_registry` value instead of `NE`. * The file is rejected by the Luxembourg tax administration. **Cause:** * In `l10n_lu_generate_xml.py`, the `agent_rcs_number` template value was built with a plain `or` chain: `agent.l10n_lu_agent_rcs_number or company.company_registry or "NE"` * When an agent is set but has no RCS number (natural person), the fallback incorrectly continued to `company.company_registry` instead of stopping at `"NE"`. **Fix:** * Use a conditional expression so that `company.company_registry` is only used as a fallback when **no agent is linked** to the company: `(agent.l10n_lu_agent_rcs_number if agent else company.company_registry) or "NE"` opw-6044689 Forward-Port-Of: odoo/enterprise#112968
This update resolves an issue where changes made to form fields within a translation dialog were unexpectedly saved, even if the user didn't click 'OK' to confirm. The fix ensures that changes are only applied when the user explicitly saves the translation, improving data consistency and preventing unintended modifications. This improves the user experience and reduces potential errors.
Original PR description
[FIX] website: stop saving an attribute translation on close Steps to see the issue: - Drop a form on your page - Add a placeholder on one of the inputs - Save your changes, and switch to another language - Start translating - Click on the input with the placeholder - Make some changes to the placeholder, but don't click "Ok" - Close the dialog => The changes are still applied. task-5190459 Forward-Port-Of: odoo/odoo#264052
This update ensures that sensitive payroll information, like wages and yearly costs, is only visible to authorized users within the payroll group. A recent change in how tracking messages are generated no longer allows for filtering, so a new system has been implemented to separate and restrict access to these messages.
Original PR description
When a new version is created from the salary configurator, a tracking message summarizing field changes is posted on the employee chatter. This message may contain sensitive payroll information such…
When a new version is created from the salary configurator, a tracking message summarizing field changes is posted on the employee chatter. This message may contain sensitive payroll information such as wage and yearly cost, which should not be visible to users outside the payroll group. Previously, all tracking messages on hr.employee were visible to any user with access to the employee record. After the mail tracking refactor introduced in task (3645865) (https://www.odoo.com/odoo/project/1251/tasks/3645865), tracking values are now rendered directly into the message body, making the old field-level filtering mechanism no longer applicable. To restore payroll visibility restrictions: * Tracking values linked to payroll-restricted fields are separated from regular tracking values during `_track_log`. * Payroll-sensitive tracking values are posted in a dedicated tracking message using the subtype `mt_hr_payroll_sensitive`. * Regular tracking values continue to use the standard tracking flow and remain visible to all users with access to the employee chatter. * Employee chatter message fetching is overridden to hide payroll-sensitive messages from users outside `group_hr_payroll_user`. A test was also added to ensure payroll-sensitive tracking messages remain hidden from non-payroll users. Task: 4985543
This update ensures that manufacturing orders linked to projects with mandatory analytic plans are properly configured before confirmation. Previously, users could bypass this requirement, leading to potential accounting discrepancies. Now, the system enforces the use of a valid analytic distribution, preventing errors and improving data accuracy.
Original PR description
Currently, it is possible to confirm a manufacturing order linked to a project without an analytic distribution, even when a plan is set as mandatory for Manufacturing Orders. Fix: On action_confirm, check whether the related project has mandatory plans set and, if so, ensure they are filled — raising a ValidationError otherwise. task-id [6250034](https://www.odoo.com/odoo/project/967/tasks/6250034) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#266943
This update fixes an issue where group allocations with past start dates were not correctly calculating accrual amounts. The change ensures that accruals are accurately computed when a group allocation is created, regardless of the start date, preventing zero accrual values.
Original PR description
Problem ------------------ When creating group allocations, when the allocation type is accrual and the start date is set in the past, the newly created allocations have the accrual amounts at 0. To…
Problem ------------------ When creating group allocations, when the allocation type is accrual and the start date is set in the past, the newly created allocations have the accrual amounts at 0. To reproduce: 1. Create an accrual plan with an easily measurable milestone (e.g. 1 day every day) 2. From the allocations view -> New Group Allocation 3. Enter the following values: Grant -> By Employee Employees -> select your employee Time Off Type -> Paid Time Off (doesn't matter too much) Allocation Type -> Based on Accrual Plan Validity Period -> any date a few days in the past (Personally I tested with 1/1/2025 and no end date) Allocation -> Keep at 0 Allocate Time Off 4. Go to the newly created allocation The allocation amount is 0. Reason ---------------------- When creating group allocations, the `hr.leave.allocation.generate.multi.wizard` calls the `_process_accrual_plans()` method to compute the accruals, but when the allocations are created, the nextcall and lastcall fields are set, so the accruals are not computed and the scheduled action also does nothing until the nextcall date. The onchange method manually sets the nextcall date to False so the accruals are processed. Solution ------------------ Created a method to get the fields that need to be set to calculate the initial accrual amounts from the start date, which is called both in the onchange and to batch write in the wizard before accrual plans are processed. The wizard checks the duration values before overwriting the number_of_days field, since user manually setting the amount should overwrite the calculations. task-4938695 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#267768 Forward-Port-Of: odoo/odoo#265783
This update fixes an issue where the cursor position was incorrect after moving content within the HTML editor. Now, when moving a table or paragraph, the cursor automatically adjusts to remain within the newly positioned content, ensuring a smoother and more intuitive editing experience. This improves usability and prevents confusion for users.
Original PR description
#### Description of the issue/feature this PR addresses: - MoveNode restores the cursor at the container end position - After moving a table, the cursor ends outside the table body #### Desired behavior after PR is merged: - Preserve the selection if it was inside the moved node - Otherwise place the cursor at the start of the moved node #### Steps to reproduce: - Create a table in the editor - Move the table using Movenode - Drop the table and check the cursor position - The cursor ends outside the moved table body - Select some text in a paragraph - Move that paragraph using Movenode - The selection is placed at the end of the moved node task-6215743 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#267844 Forward-Port-Of: odoo/odoo#264264
This update optimizes the styling of Odoo's Kanban dropdowns, specifically addressing slow CSS performance. By simplifying the CSS rules and adjusting how borders are displayed based on screen size, this change improves the responsiveness and speed of the Kanban interface.
Original PR description
This commit removes several expensive CSS selectors. After reviewing all usages, we found that `.o_kanban_card_manage_settings` always contains `div` elements with `col-*` classes as direct children. We also found that the border behavior depends on the available screen width rather than the bottom sheet itself: it is only needed when the elements are displayed side by side and should be removed when they are stacked vertically. An ´!important´ declaration was also added to compensate for the reduced selector specificity. 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#267979
This update fixes a previous limitation where channel owners without system admin privileges couldn't promote members to admin roles. The change ensures that channel owners can now correctly assign admin access, improving channel management capabilities. This resolves a technical issue impacting channel governance.
Original PR description
`canSetAdmin` was checking the target member role instead of the current user's role. Because of that, a channel owner who was not a system admin could not promote another member to admin. task-6250058 Forward-Port-Of: odoo/odoo#267999 Forward-Port-Of: odoo/odoo#266615
This update corrects an issue where decreasing line quantities in POS orders wasn't working reliably, particularly when using certification modules like Point of Sale. The change ensures that line decreases are accurately tracked and reflected in the order, preventing incorrect quantity calculations. This improves the overall POS order management experience.
Original PR description
This commit will affect all certification modules for the POS (pos_blackbox_be, l10n_se_pos, l10n_de_pos_res_cert) Inside the base `handleDecreaseLine` we match all the lines which have the same…
This commit will affect all certification modules for the POS (pos_blackbox_be, l10n_se_pos, l10n_de_pos_res_cert) Inside the base `handleDecreaseLine` we match all the lines which have the same product_id and compute the new quantity based on those. At the end we create a new line with the decreased quantity. This method is called when `disallowLineQuantityChange()` returns `false`, so when either of `pos_blackbox_be`, `l10n_se_pos` or `l10_de_pos_res_cert` are installed. The problem is that different combos will still have the same product_id and total_excluded_currency, so the `current_saved_quantity` adds the other unrelated combos together and tries to remove from the total of all the combos with the same parent. This commit will keep the decrease line for an order in the uiState. So instead of iterating over all the lines in the order and matching lines which have the same product_id we always keep track of the original line and the matching decrease line for that line. Task-[6173236](https://www.odoo.com/odoo/project/1737/tasks/6173236) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#262744
This update fixes an inconsistency in the HTML editor's toolbar. Previously, the toolbar remained active when selecting text within protected blocks like Code or Table of Contents, leading to confusing behavior. Now, the toolbar automatically closes when selecting text within these blocks, ensuring a smoother and more intuitive editing experience.
Original PR description
Problem: The toolbar is disabled when selecting text inside Code or Table of Content blocks, but it remains active when selecting the block itself through the “⋮⋮” handle, leading to inconsistent behavior. Cause: `_updateToolbar` does not check whether `targetedNodes` contains only protected nodes. In such cases, the toolbar should be closed. Solution: When `targetedNodes` contains only protected nodes, prevent the toolbar from opening. Steps to reproduce: - Insert a Table of Content block. - Click on the “⋮⋮” handle while hovering the block. - Observe that the toolbar opens, while it should remain closed. task-6250028 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#266661
This update ensures that file uploads initiated through the link popover are immediately canceled when the user discards the popover. Previously, uploads continued in the background even after the discard button was pressed, leading to potential issues with data integrity. This change improves the user experience by preventing unexpected uploads.
Original PR description
**Current behavior before PR:** Steps to reproduce the issue: - Go to Todo, In the network tab switch to "Slow 4G" so that file upload can take few seconds to upload. - Upload a file using link popover. - While the file upload is in progress, hit the discard button of the link popover. - Notice that the upload continues in the background and when it completes successfully, link is inserted. **Desired behavior after PR is merged:** Discarding the link popover during file upload should cancel the upload request and prevent inserting the link. task-6199113 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#267695 Forward-Port-Of: odoo/odoo#263463
This update corrects a technical problem affecting how the `pdp_verification_display_state` field is calculated. The change replaces a problematic setting with a new method (`depends_context`) to ensure proper functionality within the partner merge wizard, preventing errors.
Original PR description
The computed field `pdp_verification_display_state` uses the `company_dependent` field. This causes an issue with the partner merge wizard in saas-18.2+. This commit fixes it by using the `depends_context` instead. runbot.build.error-939449 Forward-Port-Of: odoo/odoo#267481
This update resolves an issue where demo mode incorrectly required authentication and two-factor authentication (totp). It also corrects a technical error related to how documents were processed, ensuring proper handling regardless of whether the user is a Peppol User or a PDP. This enhancement improves the stability and usability of the demo environment.
Original PR description
And don't force the totp in demo mode Also, fix the mocking of the send_documents when sending documents with a Peppol User and not a PDP one. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#267893 Forward-Port-Of: odoo/odoo#267461
This update corrects a flaw in how Odoo tracks device support status. Previously, changes weren't reliably reflected in the database when a device switched between supported and unsupported states. Now, device status changes are tracked separately, ensuring accurate database updates and preventing issues with device recognition.
Original PR description
When a device is marked unsupported (e.g. FDM after power outage) and becomes supported with the same identifier (e.g. FDM after the client restarts it after the power outage), the changed was not taken into account because we used to track changes in a set of supported + unsupported. We now track changes in supported and unsupported separately to make sure the db is informed of the changes. Forward-Port-Of: odoo/odoo#267967
This update corrects a problem where DHL shipping labels weren't using the correct template dimensions, resulting in labels printed in the wrong size (8x4 instead of 6x4). The fix maps the incorrect label template selection to the correct DHL API format, ensuring labels match the specified dimensions.
Original PR description
Issue ----- Labels generated with DHL do not respect the template (dimensions) set on the delivery method. Steps to reproduce ----- - Set up DHL - set label template as 6X4_A4_PDF - Create a delivery…
Issue
-----
Labels generated with DHL do not respect the template (dimensions) set on the
delivery method.
Steps to reproduce
-----
- Set up DHL
- set label template as 6X4_A4_PDF
- Create a delivery using the method
- Validate the delivery
> The generated label is in 8x4 inch format instead of 6x4 full page
Explanation
-----
All info below was found in DHL's API doc from the following YAML file
https://developer.dhl.com/sites/default/files/2026-05/dpdhl-express-api-3.3.0.yaml
There are 2 issues with the current implementation regarding the label format.
1. The formats defined on the model (the `ProviderDHL` `delivery.carrier`) do not match the ones of the API. From the API, the accepted values are the following:
- ECOM26_84_A4_001
- ECOM26_84_001
- ECOM_TC_A4
- ECOM26_A6_002
- ECOM26_84CI_001
- ECOM26_84CI_002
- ECOM26_84CI_003
- ECOM_A4_RU_002
- ECOM26_84_LBBX_001
- ECOM26_64_LBBX_001
(values taken from the excerpt below)
```
templateName:
description: >-
Please enter DHL Express document template name.
<BR> Sample Transport label
templates:<BR> ECOM26_84_A4_001
<BR> ECOM26_84_001 - default<BR>
ECOM_TC_A4<BR> ECOM26_A6_002<BR>
ECOM26_84CI_001<BR> ECOM26_84CI_002 - supported
single customer barcode<BR> ECOM26_84CI_003 -
to be used if customer barcodes are used<BR>
ECOM_A4_RU_002<BR>
ECOM26_84_LBBX_001 - supported for loose BBX shipment<BR>
ECOM26_64_LBBX_001 - supported for loose BBX shipment<BR>
[...]
type: string
maxLength: 25
example: ECOM26_84_001
```
[...]: additional info unrelated to labels (useful only for other `typeCode` values)
Since `ProviderDHL` is a model, the `dhl_label_template` selection values cannot be changed and must thus be mapped to the corresponding API values.
- 8X4_A4_PDF => ECOM26_84_A4_001
- 8X4_thermal => ECOM26_84_001
- 8X4_A4_TC_PDF => ECOM_TC_A4
- 6X4_thermal => ECOM26_A6_002
- 6X4_A4_PDF => ECOM26_A6_002
- 8X4_CI_PDF => ECOM26_84CI_001
- 8X4_CI_thermal => ECOM26_84CI_001
- 8X4_RU_A4_PDF => ECOM_A4_RU_002
- 6X4_PDF => ECOM26_A6_002
- 8X4_PDF => ECOM26_84_001
Couple notes about this matching:
- There is no 6x4 in the API, so A6 is used instead (A6 is 105x148mm, 4x6 is 101.6x152.4mm so not a perfect match but the best option still)
- ECOM26_84_001 and ECOM26_A6_002 are used as default values for the respective formats when there is no exact match possible (eg 6x4 only has one option in the API, the default one)
- "A4" is being ignored, because of point 2
2. There is a specific field to force the label to be in A4 format (according to the API, see excerpt below)
```
fitLabelsToA4:
description: >-
To print respective Transport Label and Waybill document into
A4 margin PDF.<BR> Note:
ECOM26_A6_002,ECOM26_84CI_001,ECOM26_84CI_002,ARCH_6X4,ARCH_8X4
template. <BR> This option is applicable only
for PDF encodingFormat selection.<BR> false:
Transport Label and Waybill document will use default margin
settings (default behavior) <BR> true:
Transport Label and Waybill document will print into A4 margin
PDF
type: boolean
example: false
```
-----
Ticket:
opw-6148713
Forward-Port-Of: odoo/enterprise#117281This fix resolves an issue where creating new survey records would sometimes fail due to an error in how the system handles empty lists. The code now guards against this scenario, ensuring data can be saved correctly. This prevents disruptions to the recruitment process.
Original PR description
To reproduce error. 1) make a new interview record 2) make sure user has interview group but not survey group 3) try to access/make an interview record. convert_to_cache returns none when it is…
To reproduce error.
1) make a new interview record
2) make sure user has interview group but not survey group 3) try to access/make an interview record.
convert_to_cache returns none when it is passed an empty list see link below:
https://github.com/odoo/odoo/blob/b16aaff17a65987c958c3285157ef1e4443e864f/odoo/orm/fields_misc.py#L71
```
Traceback (most recent call last):
File "/home/odoo/src/odoo/saas-19.3/odoo/http/router.py", line 279, in __call__
response = serve_db(request)
^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.3/odoo/http/router.py", line 443, in serve_db
raise _update_served_exception(request, exc)
File "/home/odoo/src/odoo/saas-19.3/odoo/http/router.py", line 441, in serve_db
return retrying(serve_func, env=request.env)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.3/odoo/http/retrying.py", line 52, in retrying
result = func()
^^^^^^
File "/home/odoo/src/odoo/saas-19.3/odoo/http/router.py", line 593, in serve_ir_http
response = request.dispatcher.dispatch(rule.endpoint, args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.3/odoo/http/dispatcher.py", line 311, in dispatch
result = self.request.registry['ir.http']._dispatch(endpoint)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.3/odoo/addons/base/models/ir_http.py", line 415, in _dispatch
result = endpoint(**request.params)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.3/odoo/http/routing_map.py", line 207, in route_wrapper
result = endpoint(self, *args, **params_ok)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.3/addons/web/controllers/dataset.py", line 32, in call_kw
return call_kw(request.env[model], method, args, kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.3/odoo/service/model.py", line 55, in call_kw
result = method(recs, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.3/addons/web/models/models.py", line 2084, in onchange
snapshot1 = RecordSnapshot(record, fields_spec)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.3/addons/web/models/models.py", line 2170, in __init__
self.fetch(name)
File "/home/odoo/src/odoo/saas-19.3/addons/web/models/models.py", line 2185, in fetch
self[field_name] = self.record[field_name]
~~~~~~~~~~~^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.3/odoo/orm/models.py", line 6130, in __getitem__
return self._fields[key].__get__(self)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.3/odoo/orm/fields.py", line 1815, in __get__
self.compute_value(recs)
File "/home/odoo/src/odoo/saas-19.3/odoo/orm/fields.py", line 1986, in compute_value
records._compute_field_value(self)
File "/home/odoo/src/odoo/saas-19.3/addons/mail/models/mail_thread.py", line 502, in _compute_field_value
return super()._compute_field_value(field)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.3/odoo/orm/models.py", line 4340, in _compute_field_value
determine(field.compute, self)
File "/home/odoo/src/odoo/saas-19.3/odoo/orm/fields.py", line 82, in determine
return needle(*args)
^^^^^^^^^^^^^
File "/home/odoo/src/odoo/saas-19.3/addons/hr_recruitment_survey/models/survey_survey.py", line 19, in _compute_allowed_survey_types
survey.allowed_survey_types = [*survey.allowed_survey_types, 'recruitment']
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Value after * must be an iterable, not bool
```
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-prThis update fixes an issue where purchase bills were incorrectly created in the company's default currency, regardless of the original purchase order currency. Now, bills automatically inherit the currency of the purchase order, ensuring accurate financial reporting. This improves the reliability of our accounting processes.
Original PR description
**Steps to reproduce:** - create a storable product - confirm a PO in another currency than the main for this product - click on the "bill matching" smart button - select only the purchase order line from your PO - click on match **Current behavior:** this creates on Bill in the main currency **Expected behavior:** the currency should be inherited from the POL **Cause of the issue:** Inside action_match_lines() if there is no amls selected we call _action_create_bill_from_po_lines(). https://github.com/odoo/odoo/blob/e3b0ca11d99b2ef819cdad68b169112cd73668b6/addons/purchase/models/purchase_bill_line_match.py#L157 Inside this method, there's currently no mechanism to take the currency from the POL when we create the bill. **fix:** If multiple different other currencies we take the main currency of the company opw-6131314 Forward-Port-Of: odoo/odoo#267090 Forward-Port-Of: odoo/odoo#266013
This update significantly speeds up the process of validating stock quantities within Odoo, a key function for managing inventory. The changes address inefficiencies in how stock quantities were checked, resulting in a dramatic reduction in processing time, especially for large datasets. This improves overall system performance and responsiveness.
Original PR description
Applying stock quants validation was performing poorly due to multiple bottlenecks in `Picking._check_entire_pack` and `StockMoveLine._apply_putaway_strategy`: * **Redundant updates** were performed…
Applying stock quants validation was performing poorly due to multiple bottlenecks in `Picking._check_entire_pack` and `StockMoveLine._apply_putaway_strategy`: * **Redundant updates** were performed on `location_dest_id` in the move lines and the package levels (which internally update all related move lines too), even when the location remained unchanged. * The main loop inside `_check_entire_pack` was **O(N^2)** time relative to the number of move lines due to internal filtering logic. * **Cache misses** triggered unnecessary SQL queries when retrieving `move_line_ids` from `package levels`, while they are already cached via the pickings and can be grouped by `package_level`. --- ### Benchmark Benchmark conducted on a customer database with **400k** `stock_move_line` records within **800** `pickings`, testing performance of the action `StockQuant.action_validate` with different sizes of move lines. Each test was run multiple times and shown is the average mean, all with negligible variance. | Metric | Before | After | Delta | | :--- | :--- | :--- | :--- | | **Benchmark (1k lines)** | 10.5s | 2.2s | -80% | | **Benchmark (5k lines)** | 121s | 8.5s | -93% | | **Benchmark (50k lines)** | 887s | 56s | -94% | | **Benchmark (400k lines)** | timeout | 777s | (within time limit) | **OPW-6045513** Forward-Port-Of: odoo/odoo#262717 Forward-Port-Of: odoo/odoo#257829
This update fixes a previous issue where purchase order information was missing from vendor credit notes (in_refund). Now, users can easily see which purchase order each credit note line is associated with, improving accuracy and streamlining the credit note process. This ensures consistent reporting and simplifies reconciliation.
Original PR description
The purchase_order_id column in invoice lines was hidden for vendor credit notes (in_refund), while it was visible for vendor invoices (in_invoice). This prevented users from identifying which purchase order each line belonged to when a credit note was linked to one or more POs. Include 'in_refund' in the column_invisible condition so the purchase order column is also available on vendor credit note lines. 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#267316
This update resolves an issue where currency amounts in Arabic RTL (right-to-left) user interfaces were incorrectly displayed with the minus sign appearing to the right of the currency symbol. The fix ensures that currency amounts are consistently formatted left-to-right, improving readability and accuracy for users in Arabic-speaking regions. This ensures financial data is presented correctly for all users.
Original PR description
Steps to reproduce 1. Create a company with Egypt localization, currency EGP 2. On a bank journal, set Outstanding Receipt and Outstanding Payment accounts 3. Register a customer payment so the…
Steps to reproduce 1. Create a company with Egypt localization, currency EGP 2. On a bank journal, set Outstanding Receipt and Outstanding Payment accounts 3. Register a customer payment so the journal dashboard shows the Payments row with a negative amount 4. Switch the user language to Arabic 5. Open the Accounting dashboard Issue The Payments amount renders as "LE 5,000.00-" instead of "-5,000.00 LE". formatCurrency returns the string "-5,000.00 LE". In an Arabic page the leading "-" has no intrinsic direction, so the browser attaches it to the surrounding right-to-left Arabic text and visually moves it past the symbol. Sibling rows on the same dashboard render correctly because they already wrap the amount in dir="ltr", see https://github.com/odoo/odoo/blob/d0424f2ffcf99ee59befe288150f1643b3fa0112/addons/account/views/account_journal_dashboard_view.xml#L252 opw-6183749 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#267812 Forward-Port-Of: odoo/odoo#266742
This update corrects a technical issue where message authors were sometimes incorrectly identified. The fix ensures that message authors are accurately linked to either partners or guests based on the message's model, improving the reliability of communication tracking. This resolves a potential inconsistency in how message authorship is recorded.
Original PR description
A message's author is identified by one of two fields depending on its model: `author_id` (for partners) or `author_guest_id` (for guests). Previously in `changeThread`, the value of `thread.effectiveSelf` (which can be either a Partner or a Guest) was provided as the `author_id` regardless of its actual model. This commit explicitly uses `store.self_partner` as the `author_id` and `store.self_guest` as the `author_guest_id` to resolve the occasional mismatch. Forward-Port-Of: odoo/odoo#267828 Forward-Port-Of: odoo/odoo#267464
19 changes
Resolved issues and error corrections
This update resolves an issue where Luxembourg tax reports were incorrectly generating company registry numbers instead of the agent's RCS number when a natural person accountant wasn't linked. The fix ensures the correct RCS number is included in the XML, preventing rejection by the Luxembourg tax administration. This ensures compliance and accurate reporting.
Original PR description
**Steps to reproduce:** * install `l10n_lu_reports`. * Create a company in Luxembourg with a `company_registry` number set. * Link this company to an accounting firm that is a natural person…
**Steps to reproduce:** * install `l10n_lu_reports`. * Create a company in Luxembourg with a `company_registry` number set. * Link this company to an accounting firm that is a natural person (independent accountant) with no business registration number — i.e. `l10n_lu_agent_rcs_number` is left empty on the agent partner. * Go to the tax report and generate the XML declaration. **Observed behavior:** * The `<Agent><RCSNbr>` field in the generated XML contains the company's own `company_registry` value instead of `NE`. * The file is rejected by the Luxembourg tax administration. **Cause:** * In `l10n_lu_generate_xml.py`, the `agent_rcs_number` template value was built with a plain `or` chain: `agent.l10n_lu_agent_rcs_number or company.company_registry or "NE"` * When an agent is set but has no RCS number (natural person), the fallback incorrectly continued to `company.company_registry` instead of stopping at `"NE"`. **Fix:** * Use a conditional expression so that `company.company_registry` is only used as a fallback when **no agent is linked** to the company: `(agent.l10n_lu_agent_rcs_number if agent else company.company_registry) or "NE"` opw-6044689 Forward-Port-Of: odoo/enterprise#112968
This update ensures that manufacturing orders linked to projects always have a correctly configured analytic plan. Previously, users could confirm orders without a plan, even when one was required. Now, the system will prevent order confirmation until a valid plan is selected, improving data accuracy and financial reporting.
Original PR description
Currently, it is possible to confirm a manufacturing order linked to a project without an analytic distribution, even when a plan is set as mandatory for Manufacturing Orders. Fix: On action_confirm, check whether the related project has mandatory plans set and, if so, ensure they are filled — raising a ValidationError otherwise. task-id [6250034](https://www.odoo.com/odoo/project/967/tasks/6250034) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#266943
This update optimizes the styling of Odoo's Kanban dropdowns, specifically addressing slow CSS performance. By simplifying the CSS selectors used, the system now loads faster and responds more efficiently, leading to a smoother user experience.
Original PR description
This commit removes several expensive CSS selectors. After reviewing all usages, we found that `.o_kanban_card_manage_settings` always contains `div` elements with `col-*` classes as direct children. We also found that the border behavior depends on the available screen width rather than the bottom sheet itself: it is only needed when the elements are displayed side by side and should be removed when they are stacked vertically. An ´!important´ declaration was also added to compensate for the reduced selector specificity. 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#267979
This update ensures that the subject displayed in the chatter reflects any changes made to the message subject within the composer. Previously, updates to the composer's subject weren't automatically reflected in the chatter, leading to inconsistencies. This improvement provides a more accurate and up-to-date view of message subjects.
Original PR description
If the user updates the subject in the composer, the suggested subject in the chatter should reflect the latest message. task-5944635
This update fixes an issue where SII invoice JSONs weren't accurately representing quarterly tax periods. The system now correctly uses '2T' for the Periodo field when the company's tax periodicity is set to quarterly, aligning with Spanish tax regulations. This ensures accurate reporting for VAT compliance.
Original PR description
### Issue: When the company `tax_periodicity` is set to quarterly, the generated SII invoice JSON still uses the monthly period format According to the documentation, the options for Periodo include…
### Issue: When the company `tax_periodicity` is set to quarterly, the generated SII invoice JSON still uses the monthly period format According to the documentation, the options for Periodo include distinction between monthly and trimester (p224 - 225): https://sede.agenciatributaria.gob.es/static_files/Sede/Procedimiento_ayuda/G417/FicherosSuministros/V_1_1/SII-Descripcion-ServicioWeb-v1-1_es_es.pdf ### Cause: The invoice JSON generation does not consider the company's `tax_periodicity` This logic was probably omitted because `account_reports` may not be installed However, when the periodicity is configured, the generated SII document should reflect it correctly ### Steps to reproduce: - Install `l10n_es_edi_sii` and `account_reports` - In Settings, set `Tax Periodicity` to `Quarterly` - In Settings, set `Tax Agency for SII` to `Agencia Tributaria Española` - Change ES Company vat number to `ESA12345674` - Create an invoice (Date: 01/05/2026, Customer: ES Company) - Open the generated JSON document - Check the Periodo value, it should be 2T in May opw-6050587 Forward-Port-Of: odoo/odoo#267708 Forward-Port-Of: odoo/odoo#264063
This update resolves an issue where decreasing a line item in a POS order wasn't functioning reliably, particularly when certain certification modules (like those for SE and DE) were enabled. The change ensures that line decreases are accurately tracked and applied to the order, improving the overall POS experience. This fix impacts all certified POS modules.
Original PR description
This commit will affect all certification modules for the POS (pos_blackbox_be, l10n_se_pos, l10n_de_pos_res_cert) Inside the base `handleDecreaseLine` we match all the lines which have the same…
This commit will affect all certification modules for the POS (pos_blackbox_be, l10n_se_pos, l10n_de_pos_res_cert) Inside the base `handleDecreaseLine` we match all the lines which have the same product_id and compute the new quantity based on those. At the end we create a new line with the decreased quantity. This method is called when `disallowLineQuantityChange()` returns `false`, so when either of `pos_blackbox_be`, `l10n_se_pos` or `l10_de_pos_res_cert` are installed. The problem is that different combos will still have the same product_id and total_excluded_currency, so the `current_saved_quantity` adds the other unrelated combos together and tries to remove from the total of all the combos with the same parent. This commit will keep the decrease line for an order in the uiState. So instead of iterating over all the lines in the order and matching lines which have the same product_id we always keep track of the original line and the matching decrease line for that line. Task-[6173236](https://www.odoo.com/odoo/project/1737/tasks/6173236) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#262744
This update fixes an inconsistency in the HTML editor's toolbar. Previously, the toolbar remained active when selecting text within protected blocks like Code or Table of Contents, but now it's correctly disabled in these scenarios, ensuring a more reliable and intuitive user experience. This improves the editor's stability and usability.
Original PR description
Problem: The toolbar is disabled when selecting text inside Code or Table of Content blocks, but it remains active when selecting the block itself through the “⋮⋮” handle, leading to inconsistent behavior. Cause: `_updateToolbar` does not check whether `targetedNodes` contains only protected nodes. In such cases, the toolbar should be closed. Solution: When `targetedNodes` contains only protected nodes, prevent the toolbar from opening. Steps to reproduce: - Insert a Table of Content block. - Click on the “⋮⋮” handle while hovering the block. - Observe that the toolbar opens, while it should remain closed. task-6250028 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#266661
This update resolves an issue where changes to attribute translations within a dialog were unexpectedly saved, even after the dialog was closed. The fix ensures that modifications are only applied when the user explicitly confirms their changes, improving data consistency and preventing unintended updates. This improves the user experience and data integrity.
Original PR description
[FIX] website: stop saving an attribute translation on close Steps to see the issue: - Drop a form on your page - Add a placeholder on one of the inputs - Save your changes, and switch to another language - Start translating - Click on the input with the placeholder - Make some changes to the placeholder, but don't click "Ok" - Close the dialog => The changes are still applied. task-5190459 Forward-Port-Of: odoo/odoo#264052
This update corrects a technical problem affecting how the `pdp_verification_display_state` field is calculated. The change replaces an outdated method with a more reliable approach, ensuring proper functionality within the partner merge wizard. This resolves a previous error that impacted the system's ability to correctly process partner data.
Original PR description
The computed field `pdp_verification_display_state` uses the `company_dependent` field. This causes an issue with the partner merge wizard in saas-18.2+. This commit fixes it by using the `depends_context` instead. runbot.build.error-939449 Forward-Port-Of: odoo/odoo#267481
This update resolves an issue preventing proper demo mode operation by bypassing unnecessary authentication steps and removing forced two-factor authentication. Additionally, the system now correctly handles document sending for both Peppol Users and PDPs, ensuring accurate data processing during demonstrations. This improves the reliability and usability of the French PDP demo environment.
Original PR description
And don't force the totp in demo mode Also, fix the mocking of the send_documents when sending documents with a Peppol User and not a PDP one. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#267893 Forward-Port-Of: odoo/odoo#267461
This update resolves an issue where multiple Mercado Pago payment terminals were incorrectly linked to a single WebSocket connection. Previously, this meant responses from additional terminals wouldn't be processed correctly. The fix ensures that each active terminal receives its own connection, guaranteeing accurate webhook handling and payment processing. This improves the reliability of the Mercado Pago integration.
Original PR description
Issue Upon initialization of the pos a PaymentInterface is constructed for every pos_payment_method (even archived pos payment methods ?!). [As we allow only one WebSocket subscription per…
Issue Upon initialization of the pos a PaymentInterface is constructed for every pos_payment_method (even archived pos payment methods ?!). [As we allow only one WebSocket subscription per channel](https://github.com/odoo/odoo/blob/4e1c89890c5fd54a79dcf5bf20268e51d8fe6e69/addons/point_of_sale/static/src/app/utils/payment/payment_interface.js#L100) for the PaymentInterface, all webhook responses will be linked to only one PaymentInterface. Meaning that when you have two Mercado Pago pos_payment_method terminals configured, only the first pos_payment_method (id=1) will be subscribed to the WebSocket and all the webhook responses from the second pos_payment_method terminal (id=2) will arrive to the PayementInterface of the first pos_payment_method (id=1). Where payload.payment_method_id (id=2) != this.payment_method_id.id (id=1). Solution - Only iterate and create a PaymentInterface for compatible pos_payment_methods which are active - Check if the webhook response is linked to the PendingPaymentLine opw-6069455 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#262184
This update corrects a problem where DHL shipping labels weren't using the correct dimensions (6x4 inches) due to a mismatch between Odoo's settings and the DHL API. The code now maps the selected label template to the correct DHL API format, ensuring labels are printed in the intended size. This prevents incorrect label dimensions and potential shipping errors.
Original PR description
Issue ----- Labels generated with DHL do not respect the template (dimensions) set on the delivery method. Steps to reproduce ----- - Set up DHL - set label template as 6X4_A4_PDF - Create a delivery…
Issue
-----
Labels generated with DHL do not respect the template (dimensions) set on the
delivery method.
Steps to reproduce
-----
- Set up DHL
- set label template as 6X4_A4_PDF
- Create a delivery using the method
- Validate the delivery
> The generated label is in 8x4 inch format instead of 6x4 full page
Explanation
-----
All info below was found in DHL's API doc from the following YAML file
https://developer.dhl.com/sites/default/files/2026-05/dpdhl-express-api-3.3.0.yaml
There are 2 issues with the current implementation regarding the label format.
1. The formats defined on the model (the `ProviderDHL` `delivery.carrier`) do not match the ones of the API. From the API, the accepted values are the following:
- ECOM26_84_A4_001
- ECOM26_84_001
- ECOM_TC_A4
- ECOM26_A6_002
- ECOM26_84CI_001
- ECOM26_84CI_002
- ECOM26_84CI_003
- ECOM_A4_RU_002
- ECOM26_84_LBBX_001
- ECOM26_64_LBBX_001
(values taken from the excerpt below)
```
templateName:
description: >-
Please enter DHL Express document template name.
<BR> Sample Transport label
templates:<BR> ECOM26_84_A4_001
<BR> ECOM26_84_001 - default<BR>
ECOM_TC_A4<BR> ECOM26_A6_002<BR>
ECOM26_84CI_001<BR> ECOM26_84CI_002 - supported
single customer barcode<BR> ECOM26_84CI_003 -
to be used if customer barcodes are used<BR>
ECOM_A4_RU_002<BR>
ECOM26_84_LBBX_001 - supported for loose BBX shipment<BR>
ECOM26_64_LBBX_001 - supported for loose BBX shipment<BR>
[...]
type: string
maxLength: 25
example: ECOM26_84_001
```
[...]: additional info unrelated to labels (useful only for other `typeCode` values)
Since `ProviderDHL` is a model, the `dhl_label_template` selection values cannot be changed and must thus be mapped to the corresponding API values.
- 8X4_A4_PDF => ECOM26_84_A4_001
- 8X4_thermal => ECOM26_84_001
- 8X4_A4_TC_PDF => ECOM_TC_A4
- 6X4_thermal => ECOM26_A6_002
- 6X4_A4_PDF => ECOM26_A6_002
- 8X4_CI_PDF => ECOM26_84CI_001
- 8X4_CI_thermal => ECOM26_84CI_001
- 8X4_RU_A4_PDF => ECOM_A4_RU_002
- 6X4_PDF => ECOM26_A6_002
- 8X4_PDF => ECOM26_84_001
Couple notes about this matching:
- There is no 6x4 in the API, so A6 is used instead (A6 is 105x148mm, 4x6 is 101.6x152.4mm so not a perfect match but the best option still)
- ECOM26_84_001 and ECOM26_A6_002 are used as default values for the respective formats when there is no exact match possible (eg 6x4 only has one option in the API, the default one)
- "A4" is being ignored, because of point 2
2. There is a specific field to force the label to be in A4 format (according to the API, see excerpt below)
```
fitLabelsToA4:
description: >-
To print respective Transport Label and Waybill document into
A4 margin PDF.<BR> Note:
ECOM26_A6_002,ECOM26_84CI_001,ECOM26_84CI_002,ARCH_6X4,ARCH_8X4
template. <BR> This option is applicable only
for PDF encodingFormat selection.<BR> false:
Transport Label and Waybill document will use default margin
settings (default behavior) <BR> true:
Transport Label and Waybill document will print into A4 margin
PDF
type: boolean
example: false
```
-----
Ticket:
opw-6148713
Forward-Port-Of: odoo/enterprise#117281This update corrects a bug where analytic accounts weren't consistently linked to invoice cost lines, leading to unbalanced accounting reports. The change ensures that both invoice cost lines and related purchase orders have the correct analytic account assigned, resulting in accurate financial reporting. This resolves an issue impacting project cost analysis.
Original PR description
Steps to reproduce: - Activate Anglo-Saxon accounting - Create a product with track inventory and an automated inventory valuation product category - Define MTO on the product - Add this product to…
Steps to reproduce: - Activate Anglo-Saxon accounting - Create a product with track inventory and an automated inventory valuation product category - Define MTO on the product - Add this product to an Analytic Distribution Model (i.e. Legal) - Create a SO for this product - Create and confirm the PO related to it, the Analytic account is set on the PO. - Confirm the reception of the product - This creates a Stock valuation layer with the Analytic account - Confirm the SO - Confirm the delivery of the product - This creates a Stock valuation layer with the Analytic account too - Create the Invoice Issue: Missing analytic account on the 110300 Stock Interim (Delivered) creating unabalanced analytic accounting Other: test_report_invoice_items_anglo_saxon_automatic_valuation introduced in this PR https://github.com/odoo/odoo/pull/205777 checks that in a project's analytic report, the values based on cogs lines are displayed in the cost section. With this fix, both cogs lines will have an analytic account so their impact on the project analytic report will even out. This made the test fail. To keep the benefit of this test, we simulate that the user manually removes the analytic account on some of the cogs lines (those targetting stock interim received). The test was removed by https://github.com/odoo/odoo/pull/236971 from 19.2 onward opw-6060567 Forward-Port-Of: odoo/odoo#266617 Forward-Port-Of: odoo/odoo#261798
This update significantly speeds up the process of validating stock quantities within Odoo, a key function for managing inventory. The changes addressed inefficiencies in how stock quantities were checked, resulting in a dramatic reduction in processing time, especially for large datasets. This improves overall system performance and responsiveness.
Original PR description
Applying stock quants validation was performing poorly due to multiple bottlenecks in `Picking._check_entire_pack` and `StockMoveLine._apply_putaway_strategy`: * **Redundant updates** were performed…
Applying stock quants validation was performing poorly due to multiple bottlenecks in `Picking._check_entire_pack` and `StockMoveLine._apply_putaway_strategy`: * **Redundant updates** were performed on `location_dest_id` in the move lines and the package levels (which internally update all related move lines too), even when the location remained unchanged. * The main loop inside `_check_entire_pack` was **O(N^2)** time relative to the number of move lines due to internal filtering logic. * **Cache misses** triggered unnecessary SQL queries when retrieving `move_line_ids` from `package levels`, while they are already cached via the pickings and can be grouped by `package_level`. --- ### Benchmark Benchmark conducted on a customer database with **400k** `stock_move_line` records within **800** `pickings`, testing performance of the action `StockQuant.action_validate` with different sizes of move lines. Each test was run multiple times and shown is the average mean, all with negligible variance. | Metric | Before | After | Delta | | :--- | :--- | :--- | :--- | | **Benchmark (1k lines)** | 10.5s | 2.2s | -80% | | **Benchmark (5k lines)** | 121s | 8.5s | -93% | | **Benchmark (50k lines)** | 887s | 56s | -94% | | **Benchmark (400k lines)** | timeout | 777s | (within time limit) | **OPW-6045513** Forward-Port-Of: odoo/odoo#262717 Forward-Port-Of: odoo/odoo#257829
This update addresses a potential issue with how Odoo updates its modules. By implementing a small timeout and rollback mechanism, the system now handles module updates more reliably, preventing disruptions and ensuring translations for user error messages are correctly applied. This enhances the overall stability and user experience.
Original PR description
Add a small lock timeout when updating modules just like it is done in master (19.3). Also add rollback so that translation of user errors work (in case we need to fetch the language from the database). runbot-234930 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#267698
This update resolves an issue preventing refunds in the Colombian Point of Sale (PoS) system. The fix corrects outdated code referencing an older function name, ensuring refunds can now be processed without errors. This improves the functionality for Colombian businesses using the Odoo Enterprise system.
Original PR description
**Steps to reproduce:** - Setup a columbian company, DIAN should be in demo mode - Go to the PoS and make a sale with a columbian customer - Refund it - A traceback appears **Why the fix:** Some legacy code was left untouched when we changed the old **get_partner()** to the new **getPartner()** so we got a traceback as this function does not exist anymore. We also change the **set_partner(partner)** to **setPartner(partner)** as it was also forgotten. opw-6231856 Forward-Port-Of: odoo/enterprise#118478 Forward-Port-Of: odoo/enterprise#118054
This update fixes a previous issue where purchase order information was missing from vendor credit notes (in_refund). Now, users can easily see which purchase order each credit note line is associated with, improving accuracy and streamlining the credit note process. This ensures consistent reporting and simplifies reconciliation.
Original PR description
The purchase_order_id column in invoice lines was hidden for vendor credit notes (in_refund), while it was visible for vendor invoices (in_invoice). This prevented users from identifying which purchase order each line belonged to when a credit note was linked to one or more POs. Include 'in_refund' in the column_invisible condition so the purchase order column is also available on vendor credit note lines. 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#267316
This update resolves an issue where message authors were incorrectly identified, leading to potential inconsistencies in communication records. The change ensures that the correct 'author_id' or 'author_guest_id' is used based on the message's model, improving the accuracy of message attribution.
Original PR description
A message's author is identified by one of two fields depending on its model: `author_id` (for partners) or `author_guest_id` (for guests). Previously in `changeThread`, the value of `thread.effectiveSelf` (which can be either a Partner or a Guest) was provided as the `author_id` regardless of its actual model. This commit explicitly uses `store.self_partner` as the `author_id` and `store.self_guest` as the `author_guest_id` to resolve the occasional mismatch. Forward-Port-Of: odoo/odoo#267828 Forward-Port-Of: odoo/odoo#267464
This update ensures that errors related to intrastat codes are only triggered when creating product templates with dynamic attributes and no variants. Previously, the validation was incorrectly raised, causing issues when setting intrastat codes. This change improves data accuracy and prevents unnecessary errors during product template creation.
Original PR description
Problem: When saving an intrastat code on a product template with no variants, an error should be raised because intrastat codes are stored on the product variants. However, the error gets raised when creating a product template with intrastat code set because the variants get created after the product template is created, so it doesn't find any variant although the default variant will be created right after saving the product template. Solution: The constraint should only be triggered when saving the intrastat code on a product template with dynamic attributes and no variants. Since dynamic attributes are the only ones that can lead to a product template with no variants, we can check if the product template has dynamic attributes and no variants before raising the error. Forward-Port-Of: odoo/enterprise#118986
24 changes
Resolved issues and error corrections
This update fixes an issue where EDI invoices were incorrectly assigned to individual contacts due to shared VAT numbers. The change prioritizes main companies and active vendors during matching, ensuring invoices are routed to the correct business entity. This improves data accuracy and reduces manual intervention in invoice processing.
Original PR description
### Description of the issue/feature this PR addresses: **Issue:** When processing incoming EDI/Peppol invoices, multiple contacts (parent companies, joint ventures, child contacts) frequently share…
### Description of the issue/feature this PR addresses: **Issue:** When processing incoming EDI/Peppol invoices, multiple contacts (parent companies, joint ventures, child contacts) frequently share the same VAT number. Because the parser's tie-breaker relies primarily on VAT, invoices are often incorrectly assigned to individual child contacts or newly created joint ventures rather than the correct vendor. **Solution:** Prepend is_company DESC, supplier_rank DESC to the SQL search order in the _import_retrieve_customer fallback domain. This ensures that the matching logic explicitly prioritizes business entities over individual contacts, and active vendors over other records. ### Current behavior before PR: When searching by VAT with limit=1, the parser uses order='company_id, parent_id DESC, id DESC'. If a parent company and a child contact share a VAT, the query frequently returns the child contact or a newer joint venture due to the id DESC fallback. ### Desired behavior after PR is merged: The parser will correctly prioritize main companies over individual contacts when VAT numbers are shared. If multiple companies share the same VAT, the most active vendor will be selected. opw-6174628 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#266224
This update fixes a technical problem in Odoo related to how ordered sets are copied in Python 3.14. The change ensures that the set copy operation is performed reliably, preventing errors that could impact data consistency. This improves the stability of the system.
Original PR description
In Python 3.14, iterating over weak references (like `transaction.envs`) can trigger a `RuntimeError: dictionary changed size during iteration`. This happens mostly because the Garbage Collector can remove a weakref while `OrderedSet.copy()` is rebuilding the set via `dict.fromkeys()`. Instead of re-initializing the set by iterating over its elements, we now directly use the dictionary's native `.copy()` method. This atomic operation prevents the GC from modifying the size of the underlying `_map` during the copy. Forward-Port-Of: odoo/odoo#267947
This update resolves an issue where Luxembourg tax reports were incorrectly including the company's registry number instead of the agent's RCS number. This prevented the reports from being accepted by the Luxembourg tax administration. The fix ensures the correct RCS number is used when an agent is linked, complying with Luxembourg tax regulations.
Original PR description
**Steps to reproduce:** * install `l10n_lu_reports`. * Create a company in Luxembourg with a `company_registry` number set. * Link this company to an accounting firm that is a natural person…
**Steps to reproduce:** * install `l10n_lu_reports`. * Create a company in Luxembourg with a `company_registry` number set. * Link this company to an accounting firm that is a natural person (independent accountant) with no business registration number — i.e. `l10n_lu_agent_rcs_number` is left empty on the agent partner. * Go to the tax report and generate the XML declaration. **Observed behavior:** * The `<Agent><RCSNbr>` field in the generated XML contains the company's own `company_registry` value instead of `NE`. * The file is rejected by the Luxembourg tax administration. **Cause:** * In `l10n_lu_generate_xml.py`, the `agent_rcs_number` template value was built with a plain `or` chain: `agent.l10n_lu_agent_rcs_number or company.company_registry or "NE"` * When an agent is set but has no RCS number (natural person), the fallback incorrectly continued to `company.company_registry` instead of stopping at `"NE"`. **Fix:** * Use a conditional expression so that `company.company_registry` is only used as a fallback when **no agent is linked** to the company: `(agent.l10n_lu_agent_rcs_number if agent else company.company_registry) or "NE"` opw-6044689 Forward-Port-Of: odoo/enterprise#112968
This update ensures all date displays in the Point of Sale module consistently use Odoo's standard date format. Previously, receipts and reports used device-specific date formats, leading to potential inconsistencies. This change improves clarity and accuracy for users.
Original PR description
Why this commit: --- There are two instances in version 17.0 where dates use toLocaleString(), which relies on the device's local format instead of the Odoo-configured format. Since Odoo already…
Why this commit: --- There are two instances in version 17.0 where dates use toLocaleString(), which relies on the device's local format instead of the Odoo-configured format. Since Odoo already defines a standard date format, all toLocaleString() usages in pos should be replaced to ensure consistency. Starting from version 17.0, cash in/out receipts and the sales report use the local device time format. This commit updates those references and aligns them with the Odoo-configured date format. During forwardporting the fix in version 19.0 needs to be added to [base.js](https://github.com/odoo/odoo/blob/0352c5e8543b75083cf555c3d5b4f164f949b465/addons/point_of_sale/static/src/app/models/related_models/base.js#L64-L69). As formatDateOrTime function is used in the [reciept header](https://github.com/odoo/odoo/blob/0352c5e8543b75083cf555c3d5b4f164f949b465/addons/point_of_sale/static/src/app/screens/receipt_screen/receipt/receipt_header/receipt_header.xml#L13) printing date on all reciepts. After this commit: --- <img width="947" height="982" alt="image" src="https://github.com/user-attachments/assets/2d9e4199-75dd-40ea-aeb1-27401c9022f3" /> All date references consistently use the Odoo-configured date format. OPW: 6087341 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#266770 Forward-Port-Of: odoo/odoo#259112
This update resolves an issue preventing Live Chat users with standard access from using chatbot messages within custom filters. The fix adjusts security permissions to allow the ‘im_livechat_group_manager’ group access to chatbot messages, ensuring broader functionality for Live Chat users.
Original PR description
**Steps to Reproduce** 1. Install the **Live Chat** module in version 18.4 or above. 2. Go to: **Settings → Users** * Open your user and change the access rights from **Live Chat / Administrator** to…
**Steps to Reproduce**
1. Install the **Live Chat** module in version 18.4 or above.
2. Go to: **Settings → Users**
* Open your user and change the access rights from **Live Chat / Administrator** to **Live Chat / User**.
* Alternatively, create a new user giving him rights of the **Live Chat / User** group.
3. Login using the Live Chat user.
4. Open the **Live Chat** application and navigate to: **Live Chat → Sessions**
5. Open any existing session. The session and its messages are accessible without any issue.
6. In the search bar, click: **Filters → Custom Filter**
7. Select the field `Chatbot Messages (chatbot_message_ids)`. You will face the below traceback.
**Issue Description:**
The issue happens because `discuss.channel` records are accessible to users having the `im_livechat_group_user` group through the Sessions menu: https://github.com/odoo/odoo/blob/459a775a066fe1465e53fc751045baed39f80118/addons/im_livechat/views/im_livechat_channel_views.xml#L310-L315
The field `chatbot_message_ids` is defined as:
https://github.com/odoo/odoo/blob/459a775a066fe1465e53fc751045baed39f80118/addons/im_livechat/models/discuss_channel.py#L165
This field points to the `chatbot.message` model, but access to that model is restricted to `im_livechat_group_manager` only:
https://github.com/odoo/odoo/blob/459a775a066fe1465e53fc751045baed39f80118/addons/im_livechat/security/ir.model.access.csv#L15
As a result, when a Live Chat user tries to use `chatbot_message_ids` in a custom filter, Odoo attempts to read `chatbot.message` records and raises an `AccessError`.
This issue started happening after the access rights changes introduced in pr : https://github.com/odoo/odoo/pull/201880
Specifically, the following ACL changes:
https://github.com/odoo/odoo/pull/201880/changes#diff-c1592d633a34db44a7cc2a527482cecc56127cbba72649e7318dcf63ccf477afR19-R20
**Solution:**
To fix this issue, added the group `im_livechat_group_manager` on the field `chatbot_message_ids` so only those user can access the field who belong to the group.
**Traceback:**
```.py
odoo.exceptions.AccessError: You are not allowed to access
'Chatbot Message' (chatbot.message) records.
This operation is allowed for the following groups:
- Live Chat/Administrator
Contact your administrator to request access if necessary.
```
opw - [6169395]
upg - [4274573]
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#264682This update ensures that manufacturing orders linked to projects with mandatory analytic plans are properly configured before confirmation. Previously, users could bypass this requirement, leading to potential accounting discrepancies. Now, the system enforces the use of a valid analytic distribution, preventing errors and improving data accuracy.
Original PR description
Currently, it is possible to confirm a manufacturing order linked to a project without an analytic distribution, even when a plan is set as mandatory for Manufacturing Orders. Fix: On action_confirm, check whether the related project has mandatory plans set and, if so, ensure they are filled — raising a ValidationError otherwise. task-id [6250034](https://www.odoo.com/odoo/project/967/tasks/6250034) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#266943
This update fixes an issue where the cursor position was incorrect after moving content within the HTML editor. Now, when moving a table or paragraph, the cursor automatically adjusts to the beginning of the moved content, preserving the user's selection and ensuring a smoother editing experience.
Original PR description
#### Description of the issue/feature this PR addresses: - MoveNode restores the cursor at the container end position - After moving a table, the cursor ends outside the table body #### Desired behavior after PR is merged: - Preserve the selection if it was inside the moved node - Otherwise place the cursor at the start of the moved node #### Steps to reproduce: - Create a table in the editor - Move the table using Movenode - Drop the table and check the cursor position - The cursor ends outside the moved table body - Select some text in a paragraph - Move that paragraph using Movenode - The selection is placed at the end of the moved node task-6215743 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#267549 Forward-Port-Of: odoo/odoo#264264
This update optimizes the styling of Kanban dropdowns, specifically addressing slow loading times. By simplifying the CSS, we've significantly improved the responsiveness and speed of this key feature. This change focuses on performance and user experience.
Original PR description
This commit removes several expensive CSS selectors. After reviewing all usages, we found that `.o_kanban_card_manage_settings` always contains `div` elements with `col-*` classes as direct children. We also found that the border behavior depends on the available screen width rather than the bottom sheet itself: it is only needed when the elements are displayed side by side and should be removed when they are stacked vertically. An ´!important´ declaration was also added to compensate for the reduced selector specificity. 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#267979
This update optimizes the website's styling process, making it faster and more efficient. By switching from a complex selector to a simpler class on the body, the system now recalculates styles more quickly, particularly when dealing with large tables or during website resizing. This results in a smoother user experience.
Original PR description
Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#267969
This update fixes an issue where SII invoice JSONs weren't accurately displaying quarterly tax periods. The change ensures that the generated JSON correctly reflects the company's 'Tax Periodicity' setting, aligning with Spanish tax regulations. This improves data accuracy for tax reporting.
Original PR description
### Issue: When the company `tax_periodicity` is set to quarterly, the generated SII invoice JSON still uses the monthly period format According to the documentation, the options for Periodo include…
### Issue: When the company `tax_periodicity` is set to quarterly, the generated SII invoice JSON still uses the monthly period format According to the documentation, the options for Periodo include distinction between monthly and trimester (p224 - 225): https://sede.agenciatributaria.gob.es/static_files/Sede/Procedimiento_ayuda/G417/FicherosSuministros/V_1_1/SII-Descripcion-ServicioWeb-v1-1_es_es.pdf ### Cause: The invoice JSON generation does not consider the company's `tax_periodicity` This logic was probably omitted because `account_reports` may not be installed However, when the periodicity is configured, the generated SII document should reflect it correctly ### Steps to reproduce: - Install `l10n_es_edi_sii` and `account_reports` - In Settings, set `Tax Periodicity` to `Quarterly` - In Settings, set `Tax Agency for SII` to `Agencia Tributaria Española` - Change ES Company vat number to `ESA12345674` - Create an invoice (Date: 01/05/2026, Customer: ES Company) - Open the generated JSON document - Check the Periodo value, it should be 2T in May opw-6050587 Forward-Port-Of: odoo/odoo#267708 Forward-Port-Of: odoo/odoo#264063
This update corrects a bug in the POS system that was incorrectly handling line quantity decreases, particularly when certain certification modules (like those for SE and DE) were enabled. The change ensures accurate tracking of decreased lines within orders, preventing incorrect quantity calculations and improving order accuracy. This resolves a previous issue impacting the POS experience for users with these modules.
Original PR description
This commit will affect all certification modules for the POS (pos_blackbox_be, l10n_se_pos, l10n_de_pos_res_cert) Inside the base `handleDecreaseLine` we match all the lines which have the same…
This commit will affect all certification modules for the POS (pos_blackbox_be, l10n_se_pos, l10n_de_pos_res_cert) Inside the base `handleDecreaseLine` we match all the lines which have the same product_id and compute the new quantity based on those. At the end we create a new line with the decreased quantity. This method is called when `disallowLineQuantityChange()` returns `false`, so when either of `pos_blackbox_be`, `l10n_se_pos` or `l10_de_pos_res_cert` are installed. The problem is that different combos will still have the same product_id and total_excluded_currency, so the `current_saved_quantity` adds the other unrelated combos together and tries to remove from the total of all the combos with the same parent. This commit will keep the decrease line for an order in the uiState. So instead of iterating over all the lines in the order and matching lines which have the same product_id we always keep track of the original line and the matching decrease line for that line. Task-[6173236](https://www.odoo.com/odoo/project/1737/tasks/6173236) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#262744
This update fixes an issue where the calculation of Cost of Goods Sold (COGS) was incorrectly averaging delivery and return values, leading to inaccurate COGS figures. Previously, returns weren't properly accounted for, resulting in inflated COGS calculations. Now, returns are correctly deducted, ensuring accurate COGS reporting for sales with deliveries and returns.
Original PR description
When the cogs are computed using the Stock Moves values, we would not differentiate between deliveries and returns, taking both in the cogs value computation. This meant that when doing multiple…
When the cogs are computed using the Stock Moves values, we would not differentiate between deliveries and returns, taking both in the cogs value computation. This meant that when doing multiple deliveries with returns before posting the invoice, if the deliveries/returns had different cost, the COGS would be an average of all of them. Example: Delivery $10 -> Return $10 -> Delivery $20 ==> COGS $13.33
## HOW TO REPRODUCE
- Create Product FIFO Perpetual, cost=10, onHand=1
- Create Sale order for 1 unit
- Deliver and return
- Change cost from 10 to 20:
- Set on hand to 0
- Change product cost to 20
- Set on hand to 1
- Duplicate SO delivery and validate
- Create and Post Invoice => COGS == 13.33
## FIX EXPLANATION
Returns / Refunds are counted negatively.
So when we compute the moves value, instead of doing `(10 + 10 + 20) / (1 + 1 + 1)`, we do `(10 - 10 + 20) / (1 - 1 + 1)`.
We need to propagate this logic to the cogs quantity, so that we don't believe that we invoiced 3 units while only 1 (1-1+1) was delivered.
---
Note:
For the update in test `test_fifo_delivered_invoice_post_delivery_with_return`, I put back the original values modified by 5978bc5dc683d317f4ab87f6c9c9d843568bf4ea
---
<img width="1852" height="363" alt="image" src="https://github.com/user-attachments/assets/ea9f16b2-a818-4c21-b3c3-aa296792f477" />
<img width="1203" height="787" alt="image" src="https://github.com/user-attachments/assets/7348d15a-b840-4ee0-b1da-2b954cdb3d5e" />
---
## Test result without fix:
```
2026-05-28 11:57:45,899 36667 INFO oes_test_19.0 odoo.addons.sale_stock.tests.test_anglo_saxon_valuation: Starting TestAngloSaxonValuation.test_fifo_invoice_with_delivery_with_return ...
2026-05-28 11:57:47,138 36667 INFO oes_test_19.0 odoo.addons.sale_stock.tests.test_anglo_saxon_valuation: ======================================================================
2026-05-28 11:57:47,138 36667 ERROR oes_test_19.0 odoo.addons.sale_stock.tests.test_anglo_saxon_valuation: FAIL: TestAngloSaxonValuation.test_fifo_invoice_with_delivery_with_return
Traceback (most recent call last):
File "/home/odoo/Odoo/src/19.0/odoo/addons/sale_stock/tests/test_anglo_saxon_valuation.py", line 1099, in test_fifo_invoice_with_delivery_with_return
self.assertRecordValues(invoice.line_ids, [
File "/home/odoo/Odoo/src/19.0/odoo/odoo/tests/common.py", line 727, in assertRecordValues
self.assertSequenceEqual(expected_reformatted, record_reformatted, seq_type=list)
AssertionError: Lists differ: [{'ac[22 chars]t': 0, 'credit': 50}, {'account_id': 9141, 'de[114 chars]: 0}] != [{'ac[22 chars]t': 0.0, 'credit': 50.0}, {'account_id': 9141,[132 chars]0.0}]
First differing element 2:
{'account_id': 9138, 'debit': 0, 'credit': 20}
{'account_id': 9138, 'debit': 0.0, 'credit': 13.33}
- [{'account_id': 9162, 'credit': 50, 'debit': 0},
+ [{'account_id': 9162, 'credit': 50.0, 'debit': 0.0},
? ++ ++
- {'account_id': 9141, 'credit': 0, 'debit': 50},
+ {'account_id': 9141, 'credit': 0.0, 'debit': 50.0},
? ++ ++
- {'account_id': 9138, 'credit': 20, 'debit': 0},
? ^^
+ {'account_id': 9138, 'credit': 13.33, 'debit': 0.0},
? ^^^^^ ++
- {'account_id': 9168, 'credit': 0, 'debit': 20}]
? ^^
+ {'account_id': 9168, 'credit': 0.0, 'debit': 13.33}]
? ++ ^^^^^
```
---
OPW-6213321
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#266917This update resolves an issue where the HTML editor toolbar remained active when selecting text within Code or Table of Content blocks. The fix ensures the toolbar is disabled when selecting protected content, providing a more consistent and intuitive user experience. This improves editor stability and usability.
Original PR description
Problem: The toolbar is disabled when selecting text inside Code or Table of Content blocks, but it remains active when selecting the block itself through the “⋮⋮” handle, leading to inconsistent behavior. Cause: `_updateToolbar` does not check whether `targetedNodes` contains only protected nodes. In such cases, the toolbar should be closed. Solution: When `targetedNodes` contains only protected nodes, prevent the toolbar from opening. Steps to reproduce: - Insert a Table of Content block. - Click on the “⋮⋮” handle while hovering the block. - Observe that the toolbar opens, while it should remain closed. task-6250028 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#266661
This update prevents unwanted translation changes from being saved to the system when a translation dialog is closed without confirming the updates. Previously, edits made to placeholder text within the dialog would persist across language selections. This ensures data consistency and prevents unexpected behavior for users.
Original PR description
[FIX] website: stop saving an attribute translation on close Steps to see the issue: - Drop a form on your page - Add a placeholder on one of the inputs - Save your changes, and switch to another language - Start translating - Click on the input with the placeholder - Make some changes to the placeholder, but don't click "Ok" - Close the dialog => The changes are still applied. task-5190459 Forward-Port-Of: odoo/odoo#264052
This update resolves an issue where negative line items in Mexican CFDI invoices were incorrectly distributed. The change addresses a conflict introduced by new features and removes a previous check that was no longer relevant. This ensures accurate CFDI invoice generation.
Original PR description
In MX CFDI, negative lines are not allowed so they are distributed over other lines. But because this PR introduces some other `special_type` like `global_discount` and `down_payment`, it becomes useless to check `base_line['special_type'] == False`. Fix for https://github.com/odoo/odoo/pull/267435 task-5900496 --- I confirm I have signed the CLA and read the PR guidelines at [www.odoo.com/submit-pr](http://www.odoo.com/submit-pr) Forward-Port-Of: odoo/enterprise#119254
This update corrects a technical problem affecting how the `pdp_verification_display_state` field is calculated. The change replaces a problematic setting with a new method, ensuring proper functionality within the partner merge wizard and preventing potential errors. This ensures accurate data processing for French-specific features.
Original PR description
The computed field `pdp_verification_display_state` uses the `company_dependent` field. This causes an issue with the partner merge wizard in saas-18.2+. This commit fixes it by using the `depends_context` instead. runbot.build.error-939449 Forward-Port-Of: odoo/odoo#267481
This change corrects a problem where DHL shipping labels weren't using the correct template dimensions, resulting in labels printed in the wrong size (8x4 instead of 6x4). The code now maps the selected label template to the correct format required by the DHL API, ensuring accurate label dimensions.
Original PR description
Issue ----- Labels generated with DHL do not respect the template (dimensions) set on the delivery method. Steps to reproduce ----- - Set up DHL - set label template as 6X4_A4_PDF - Create a delivery…
Issue
-----
Labels generated with DHL do not respect the template (dimensions) set on the
delivery method.
Steps to reproduce
-----
- Set up DHL
- set label template as 6X4_A4_PDF
- Create a delivery using the method
- Validate the delivery
> The generated label is in 8x4 inch format instead of 6x4 full page
Explanation
-----
All info below was found in DHL's API doc from the following YAML file
https://developer.dhl.com/sites/default/files/2026-05/dpdhl-express-api-3.3.0.yaml
There are 2 issues with the current implementation regarding the label format.
1. The formats defined on the model (the `ProviderDHL` `delivery.carrier`) do not match the ones of the API. From the API, the accepted values are the following:
- ECOM26_84_A4_001
- ECOM26_84_001
- ECOM_TC_A4
- ECOM26_A6_002
- ECOM26_84CI_001
- ECOM26_84CI_002
- ECOM26_84CI_003
- ECOM_A4_RU_002
- ECOM26_84_LBBX_001
- ECOM26_64_LBBX_001
(values taken from the excerpt below)
```
templateName:
description: >-
Please enter DHL Express document template name.
<BR> Sample Transport label
templates:<BR> ECOM26_84_A4_001
<BR> ECOM26_84_001 - default<BR>
ECOM_TC_A4<BR> ECOM26_A6_002<BR>
ECOM26_84CI_001<BR> ECOM26_84CI_002 - supported
single customer barcode<BR> ECOM26_84CI_003 -
to be used if customer barcodes are used<BR>
ECOM_A4_RU_002<BR>
ECOM26_84_LBBX_001 - supported for loose BBX shipment<BR>
ECOM26_64_LBBX_001 - supported for loose BBX shipment<BR>
[...]
type: string
maxLength: 25
example: ECOM26_84_001
```
[...]: additional info unrelated to labels (useful only for other `typeCode` values)
Since `ProviderDHL` is a model, the `dhl_label_template` selection values cannot be changed and must thus be mapped to the corresponding API values.
- 8X4_A4_PDF => ECOM26_84_A4_001
- 8X4_thermal => ECOM26_84_001
- 8X4_A4_TC_PDF => ECOM_TC_A4
- 6X4_thermal => ECOM26_A6_002
- 6X4_A4_PDF => ECOM26_A6_002
- 8X4_CI_PDF => ECOM26_84CI_001
- 8X4_CI_thermal => ECOM26_84CI_001
- 8X4_RU_A4_PDF => ECOM_A4_RU_002
- 6X4_PDF => ECOM26_A6_002
- 8X4_PDF => ECOM26_84_001
Couple notes about this matching:
- There is no 6x4 in the API, so A6 is used instead (A6 is 105x148mm, 4x6 is 101.6x152.4mm so not a perfect match but the best option still)
- ECOM26_84_001 and ECOM26_A6_002 are used as default values for the respective formats when there is no exact match possible (eg 6x4 only has one option in the API, the default one)
- "A4" is being ignored, because of point 2
2. There is a specific field to force the label to be in A4 format (according to the API, see excerpt below)
```
fitLabelsToA4:
description: >-
To print respective Transport Label and Waybill document into
A4 margin PDF.<BR> Note:
ECOM26_A6_002,ECOM26_84CI_001,ECOM26_84CI_002,ARCH_6X4,ARCH_8X4
template. <BR> This option is applicable only
for PDF encodingFormat selection.<BR> false:
Transport Label and Waybill document will use default margin
settings (default behavior) <BR> true:
Transport Label and Waybill document will print into A4 margin
PDF
type: boolean
example: false
```
-----
Ticket:
opw-6148713
Forward-Port-Of: odoo/enterprise#117281This update significantly speeds up the process of validating stock quantities within Odoo, a key function for managing inventory. The changes addressed inefficiencies in how stock quantities were checked, resulting in a dramatic reduction in processing time, especially for large datasets. This improves overall system responsiveness and reduces delays in order fulfillment.
Original PR description
Applying stock quants validation was performing poorly due to multiple bottlenecks in `Picking._check_entire_pack` and `StockMoveLine._apply_putaway_strategy`: * **Redundant updates** were performed…
Applying stock quants validation was performing poorly due to multiple bottlenecks in `Picking._check_entire_pack` and `StockMoveLine._apply_putaway_strategy`: * **Redundant updates** were performed on `location_dest_id` in the move lines and the package levels (which internally update all related move lines too), even when the location remained unchanged. * The main loop inside `_check_entire_pack` was **O(N^2)** time relative to the number of move lines due to internal filtering logic. * **Cache misses** triggered unnecessary SQL queries when retrieving `move_line_ids` from `package levels`, while they are already cached via the pickings and can be grouped by `package_level`. --- ### Benchmark Benchmark conducted on a customer database with **400k** `stock_move_line` records within **800** `pickings`, testing performance of the action `StockQuant.action_validate` with different sizes of move lines. Each test was run multiple times and shown is the average mean, all with negligible variance. | Metric | Before | After | Delta | | :--- | :--- | :--- | :--- | | **Benchmark (1k lines)** | 10.5s | 2.2s | -80% | | **Benchmark (5k lines)** | 121s | 8.5s | -93% | | **Benchmark (50k lines)** | 887s | 56s | -94% | | **Benchmark (400k lines)** | timeout | 777s | (within time limit) | **OPW-6045513** Forward-Port-Of: odoo/odoo#262717 Forward-Port-Of: odoo/odoo#257829
This update addresses a minor issue with how Odoo updates modules, resulting in faster and more reliable updates. The change mirrors a recent update in the main Odoo version (19.3) and includes a rollback mechanism to ensure correct translation of user error messages. This improves the overall user experience and stability.
Original PR description
Add a small lock timeout when updating modules just like it is done in master (19.3). Also add rollback so that translation of user errors work (in case we need to fetch the language from the database). runbot-234930 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#267698
This update fixes a previous issue where purchase order information was missing from vendor credit notes (in_refund). Now, users can easily see which purchase order each credit note line is associated with, improving accuracy and streamlining the reconciliation process. This ensures consistent reporting across invoice and credit note types.
Original PR description
The purchase_order_id column in invoice lines was hidden for vendor credit notes (in_refund), while it was visible for vendor invoices (in_invoice). This prevented users from identifying which purchase order each line belonged to when a credit note was linked to one or more POs. Include 'in_refund' in the column_invisible condition so the purchase order column is also available on vendor credit note lines. 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#267316
This update resolves an issue where Mollie payments failed when customers didn't provide a fully populated billing address. Mollie now requires all necessary address fields (street, postal code, city, and country) to process payments, ensuring compliance with Mollie's requirements and preventing payment failures.
Original PR description
Steps to reproduce: 1. Setup a Mollie online payment method. 2. Make a payment with a customer that has an incomplete* billing address. Expected behaviour: The payment request is initiated. Actual behaviour: Mollie rejects the payment request. *: Mollie will either accept no billing address, or a full address (must include street, postal code, city and country). If only some of these fields are present, Mollie will reject the payment request. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes a visual issue where alert content was misaligned within the Odoo portal. The change was a result of a previous alignment adjustment, and the original styling causing the misalignment has been removed. This ensures alerts display correctly for all users.
Original PR description
The alert content is misaligned these changes are side effects of commit[1], the `h5` and `p` in the alert have margin that creates whitespace in the alert. Commit[2] addressed a misalignment issue and alignment issue due to nested `row` but these became irrelevant with commit[1]. This is why we remove the styling. task-5262108 [1]: odoo/odoo@513931a5e540f22f37e317f80fd131701cbbc8f0 [2]: odoo/odoo@d64dbaadcb1bef27d89a89e9d42bdb38890c73e0 | Before | After | |--------|--------| | <img width="1029" height="523" alt="image" src="https://github.com/user-attachments/assets/ff3f827b-652a-4a84-ad7e-205200cf3256" />| <img width="1022" height="486" alt="image" src="https://github.com/user-attachments/assets/b86163d8-bedd-4cb6-a950-ba36a6b401ee" /> | --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update corrects a flaw in the interval inversion function, ensuring accurate results across a wider range of scenarios. The fix addresses inconsistencies in how intervals were handled, particularly at the edges of the specified limits. This improves the reliability of calculations related to time ranges and date intervals.
Original PR description
The [commit] introduced the method for inverting the interval inside the given limits. The method was failing for the following edge cases: ```python >>> invert_intervals([(1, 2), (4, 5)], 0, 10) result - [(2, 4), (5, 10)] expected - [(0, 1), (2, 4), (5, 10)]? >>> invert_intervals([(-2, -1)], 0, 10) result - [(0, 10)] expected - same >>> invert_intervals([(11, 12)], 0, 10) result - [] expected - [(0, 10)] >>> invert_intervals([(-1, 1), (2, 5), (8, 12)], 0, 10) result - [(1, 2), (5, 8)] expected - same >>> invert_intervals([(2, 5), (8, 12)], 0, 10) result - [(5, 8)] expected - [(0, 2), (5, 8)] >>> invert_intervals([(2, 5), (11, 12)], 0, 10) result - [] expected - [(0, 2), (5, 10)] ``` This commit fixes the function to correctly handle all the cases. The test cases are also added to test all the edge cases. [commit]: https://github.com/odoo/enterprise/commit/53450065be0c3ec9d648d4fd39ec3a9a912bd06c Forward-Port-Of: odoo/odoo#267917
This update fixes an error in the executive summary report that was incorrectly calculating the period length. Previously, it was measuring the gap between dates instead of the number of days, leading to inaccurate metrics like Average Debtor Days. This change ensures the report accurately reflects the period's length, improving the reliability of key business data.
Original PR description
`_report_custom_engine_executive_summary_ndays` returned `date_to - date_from`, which is the gap between the two dates, not the count of days they span. For example April 2026-04-01 to 2026-04-30 will returned 29 instead of 30, making Average Debtor Days incorrect. Add +1 so the day count is inclusive of both endpoints, matching the rest of the report's date handling. opw-6215362 Forward-Port-Of: odoo/enterprise#118953
1 change
Resolved issues and error corrections
This update fixes an issue where barcode scanning incorrectly displayed delivered quantities on sales orders. The problem stemmed from how the system processed barcode scans, leading to inaccurate order fulfillment. The fix ensures that quantities are correctly reflected after scanning lots, resolving delivery discrepancies.
Original PR description
Currently when user adds adds quantity in barcode using lots it leads to incorrect sale order quantities. ## Steps to replicate: - Install Sales and Barcode (no demo data). - Enable Lots & Serial…
Currently when user adds adds quantity in barcode using lots it leads to incorrect sale order quantities.
## Steps to replicate:
- Install Sales and Barcode (no demo data).
- Enable Lots & Serial Numbers in settings.
- Create Test Product with Tracking by Lots.
- Go to Inventory > Products>Lots & Serial Numbers and create 3 lots for the product.
- Update each lot’s on-hand quantity to 10 from the product page.
- Create and confirm a Sales Order for the product (lines: qty 3 and 2 units).
- Open the delivery in the Barcode app:
- Scan lot 2 > increase qty to 3 using +1 button
- Scan lot 3 > increase qty to 2 using +1 button
- Validate and go to the sale order.
## Observed Behavior:
The sale order delivered quantities are flipped and a backorder is created even though the quantity for the product is satisfied.
## Root cause:
The issue occurs because when a sales order is confirmed, the system defaults to
using lot 1 on the delivery receipt. When a user scans lot 2, the `_processBarcode` function is triggered, which calls `_findLine` at [1] to select the appropriate line on the receipt.
As the loop in `_findLine` iterates through `pageLines` with values like:
```
[{display_name: "Test product", quantity: 3, lot_id: { name: 'lot1' }},
{display_name: "Test product", quantity: 2, lot_id: { name: 'lot1' }}]
```
During the first iteration, `foundLine` is set at [2] for the line with quantity 3 . Since the subsequent if condition is not satisfied, the loop hits the continue block at [3].
On the next iteration, the line with quantity 2 causes `foundLine` to be overwritten at [2], and the continue block is executed again at [3].
This results in the line with quantity 2 being selected as the line to update at the end of the function.
When the user manually increases the quantity to 3, the line that originally required quantity 2 is updated and fulfilled.
Later, when lot 3 is scanned, the line that required quantity 3 is selected for update, and manually increasing the quantity to 2 before validating the order leads to a backorder and causes the delivered quantities to be flipped.
[1]:
https://github.com/odoo/enterprise/blob/81eaeb4b18d849c644160234def6c69013591abe/stock_barcode/static/src/models/barcode_model.js#L1335-L1337 [2]:
https://github.com/odoo/enterprise/blob/81eaeb4b18d849c644160234def6c69013591abe/stock_barcode/static/src/models/barcode_model.js#L1690-L1699 [3]:
https://github.com/odoo/enterprise/blob/81eaeb4b18d849c644160234def6c69013591abe/stock_barcode/static/src/models/barcode_model.js#L1727-L1729
## Solution:
Avoid grouping lines from different moves unless using batch transfers. This ensures that backorders are not created when the barcode lines are fulfilled.
opw-5423943
Forward-Port-Of: odoo/enterprise#118085
Forward-Port-Of: odoo/enterprise#10903210 changes
Resolved issues and error corrections
This update fixes an issue where the cursor position was incorrect after moving content within the HTML editor. Now, when moving a table or paragraph, the cursor automatically adjusts to the start of the moved content, preserving the user's selection and ensuring a smoother editing experience.
Original PR description
#### Description of the issue/feature this PR addresses: - MoveNode restores the cursor at the container end position - After moving a table, the cursor ends outside the table body #### Desired behavior after PR is merged: - Preserve the selection if it was inside the moved node - Otherwise place the cursor at the start of the moved node #### Steps to reproduce: - Create a table in the editor - Move the table using Movenode - Drop the table and check the cursor position - The cursor ends outside the moved table body - Select some text in a paragraph - Move that paragraph using Movenode - The selection is placed at the end of the moved node task-6215743 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#266419 Forward-Port-Of: odoo/odoo#264264
This update fixes a technical problem in Odoo's internal tools that could occasionally cause errors when copying data sets. The change utilizes a more reliable method for copying dictionaries, preventing issues related to Python's garbage collection process. This ensures data integrity and stability.
Original PR description
In Python 3.14, iterating over weak references (like `transaction.envs`) can trigger a `RuntimeError: dictionary changed size during iteration`. This happens mostly because the Garbage Collector can remove a weakref while `OrderedSet.copy()` is rebuilding the set via `dict.fromkeys()`. Instead of re-initializing the set by iterating over its elements, we now directly use the dictionary's native `.copy()` method. This atomic operation prevents the GC from modifying the size of the underlying `_map` during the copy. Forward-Port-Of: odoo/odoo#267947
This update resolves a technical issue flagged by Pylint, a code analysis tool, within the tests for our French localization module (l10n_fr_pdp). The fix ensures our code meets quality standards and prevents potential errors during development. This ensures the continued stability and reliability of the French-specific features.
Original PR description
```
FAIL: TestPyLint.test_pylint
Traceback (most recent call last):
File "/data/build/odoo/odoo/addons/test_lint/tests/test_pylint.py", line 109, in test_pylint
self.fail(f"pylint test failed:\n\n{r.stdout}\n{r.stderr}".strip())
~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: pylint test failed:
************* Module l10n_fr_pdp.tests.test_partner
function already defined line 134 (E0102) at odoo/addons/l10n_fr_pdp/tests/test_partner.py:152
--------------------------------------------------------------------
Your code has been rated at 10.00/10 (previous run: 10.00/10, +0.00)
```
runbot.build.error-939452
Forward-Port-Of: odoo/odoo#267472This update corrects a bug where taxes were incorrectly applied to COGS lines generated from vendor bills. The fix ensures that COGS lines, representing internal operations, are not subject to tax calculations, maintaining accurate financial reporting. This resolves a previous issue impacting tax accuracy on sales transactions.
Original PR description
Issue: After manually modifying the taxes on a vendor bill that generates COGS lines, confirming the vendor bill causes the taxes to revert to their original values before the manual edit. This…
Issue: After manually modifying the taxes on a vendor bill that generates COGS lines, confirming the vendor bill causes the taxes to revert to their original values before the manual edit. This happens because the product’s purchase taxes are applied to the generated COGS lines, which triggers the tax recomputation logic and overwrites the manually adjusted tax amounts. However, COGS lines represent internal operations and should not have taxes applied to them Steps to reproduce: 1. Turn on Anglo-Saxon accounting 2. Turn on automatic accounting 3. Make a FIFO product category and make the valuation automatic 4. Make a new product and set the FIFO product category on it 5. Make sure the product has a vendor tax set 6. Make a purchase order for 10 of the FIFO product category at $10 7. Create and validate the receipt for 10 8. Make a sales order for 6 of the FIFO product category at $10 9. Create and validate the delivery for 6 10. Create the vendor bill for 10 the purchase order created above (make sure that there is a tax set on the vendor bill; the vendor tax that was set on the product). Make this vendor bill set for 10 at $20 11. Edit the tax at the bottom of the total 12. Confirm the vendor bill 13. Notice that the tax at the bottom of the total changes 14. Reset the vendor bill 15. Remove the purchase tax from the product 16. Confirm the vendor bill again and notice that the tax at the bottom of the total does not change this time Cause: On confirmation, the COGS lines on the vendor bill will be generated and “_compute_tax_ids” will be triggered on those lines. Since COGS lines have a “product_id” set on them, those lines will receive the purchase tax set on the product. Setting the “tax_ids” on those COGS lines will cause tax computation to trigger again, which will reset the manually edited tax amount to the new computed amount. However, since COGS lines come in pairs that are equal and opposite in amount, the taxes from both COGS lines will cancel out, and the new computed tax amount does not change Solution: Skip setting the purchase taxes of the product onto COGS lines in “_compute_tax_ids” opw-6110692 Forward-Port-Of: odoo/odoo#267957 Forward-Port-Of: odoo/odoo#265352
This update resolves an issue preventing users from correctly inserting dynamic fields into SMS templates within Marketing Automation. The fix ensures the system recognizes the correct data source (`mailing_model_real`) for SMS templates, allowing users to build campaigns with accurate, personalized messages. This improves the overall reliability of the SMS marketing feature.
Original PR description
The SMS template form view in Marketing Automation was missing the `dynamic_placeholder_model_reference_field` option on the `body_plaintext` field. Without this option, the dynamic placeholder hook falls back to looking for a `model` field in the record data, but `mailing.mailing` uses `mailing_model_real` instead. Steps To Reproduce: - Install marketing_automation_sms and CRM modules (also activate Leads). - Start a new Campaign in Marketing Automation. - Set Target to Lead/Opportunity. - Add New Activity > Activity Type = SMS > SMS Template = create one. - In the SMS template dialog, click the "Insert Field" button. - Error appears: "You need to select a model before opening the dynamic placeholder selector." Ticket [link](https://www.odoo.com/odoo/project.task/5488849) opw-5488849 Forward-Port-Of: odoo/enterprise#104423
This update fixes an issue where incorrect tax reason codes were being generated when using co-contractant fiscal positions. This prevented the system from properly validating invoices against Peppol standards, ensuring compliance and accurate tax reporting. The change ensures the correct tax reason code is applied, resolving a validation error.
Original PR description
When a co-contractant fisacl position is selected and the user chooses a tax that does not belong to that fiscal position, a tax exemption reason code is added, which breaks the schematron validation on peppol. related-task-id-5905176 Forward-Port-Of: odoo/odoo#266429 Forward-Port-Of: odoo/odoo#264887
This update resolves an issue preventing accurate order data synchronization from Point of Sale systems. The fix corrects a typo and updates the system to check for 'done' invoicing status instead of 'invoiced,' ensuring reliable data transfer between POS and the core Odoo system. This improves the overall accuracy of order information.
Original PR description
In this commit: - Update `read_pos_data` to check `done` state for invoicing instead of `invoiced` state - Load `account.move` model instead of `account_move` (fix typo) Task-5887318 Forward-Port-Of: odoo/enterprise#105839
This update fixes an issue where the Balance Sheet report's XLSX export was incorrectly including all accounts instead of the selected one when changing date filters. The fix removes a filtering step that was unintentionally introduced, ensuring the report accurately reflects the user's chosen account selection.
Original PR description
Steps: - Open Balance Sheet report and unfold lines - Open the General Ledger from a line with an account - On GL report, change date filter - Export XLSX report -> We export all accounts instead of the one selected in the search bar Cause: Since f8dceec74e44ffe4aef67655be8811c96da91eba we filter out the filter if a default account is defined in the context which is the case in the `caret_option_open_general_ledger` method Fix: Remove the filtering as the behavior that was fixed by the mentioned commit does not happen anymore. opw-6234427 Forward-Port-Of: odoo/enterprise#119156
This update resolves a visual bug where color selections within the HTML editor's collapsed mode weren't consistently applying. The fix adjusts how the selection is positioned, preventing the browser from reverting the color and ensuring accurate color application when editing text.
Original PR description
Steps to Reproduce: - Apply color on a collapsed selection in mobile - Type some text - Change color from the color picker Description of the issue: - The color picker closes, but the selected color is not applied. Cause: - The color was being applied correctly, but the selection was positioned at offset 0 of the newly created font node. As a result, the browser normalized the selection back to the previous font node, making it appear as though the color was not applied. Solution: - When applying color on a collapsed selection, set the selection offset to 1 instead of 0. This prevents browser normalization and keeps the cursor inside the newly created font tag, ensuring the color is applied correctly. task-6201171 Forward-Port-Of: odoo/odoo#265438
This update resolves an issue where lengthy address fields during credit card payments via Authorize.net caused error messages. The system now automatically truncates excessively long fields to comply with the Authorize.net API requirements, ensuring smooth payment processing. This improves payment reliability and prevents disruptions for our customers.
Original PR description
Steps to reproduce: - install payment_authorize module; - complete a credit card payment using Authorize.net with more than 60 characters on any other field than first name, last name or company; - confirm the payment. Issue: An error message appears. Cause: The Authorize.net API define the max length of information. It is possible that some information exceeds the maximum length. (https://apitest.authorize.net/xml/v1/schema/AnetApiSchema.xsd) Solution: Truncate information if the number of character is too large. opw-6141441 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#262154
1 change
Resolved issues and error corrections
This update fixes a bug that allowed internal transfer validations to proceed without scanning the destination location. Previously, deleting a line would cause validation to succeed even if the location wasn't scanned. The fix ensures validation only occurs after a destination location has been scanned, improving data accuracy and user experience.
Original PR description
Currently, when a user deletes a line and validates internal movement in the barcode system, the system allows validation even though specifying the destination location after each scan is required.…
Currently, when a user deletes a line and validates internal movement in the barcode system, the system allows validation even though specifying the destination location after each scan is required. ## Steps to produce: - Install the Inventory module - Go to Settings and enable Storage Locations. - Inventory > Configuration > Operation Types > Internal Transfers > Barcode App - Configure the Destination Location to require scanning after each product. - Create an Internal Transfer for Pedal Bin, demand 1. - Mark the transfer as To Do and open it in the Barcode app. - Add quantity using +1, then scan the barcode for the Pedal Bin(Barcode: 6016478556493). - Delete the newly added line and attempt to Validate. ## Observed Behavior: The system should prevent transfer validation when the destination location has not been scanned and display a notification to the user, similar to the behavior before user deleted the newly added line. ## Root cause: This issue occurs because when the delete button is pressed, the deleteLine function [1] removes the line, but the deleted line becomes the selected line due to [2] being triggered before the UI updates. As a result, the selected line is now undefined. Since the selected line is undefined, it fails to meet the condition at [3] during validation. This prevents notifications from being triggered and allows the transfer to be validated before the destination location has been scanned. [1]: https://github.com/odoo/enterprise/blob/3476d15bf8e75eb6530658dd623861b60963ab40/stock_barcode/static/src/models/barcode_model.js#L826-L836 [2] : https://github.com/odoo/enterprise/blob/327d4478128f33fb2e0c477533bd4983178abf17/stock_barcode/static/src/components/line.js#L129-L133 [3]: https://github.com/odoo/enterprise/blob/6ff158ca3a6d2d2b3d285a7f8317622844811688/stock_barcode/static/src/models/barcode_picking_model.js#L945-L948 ## Solution: We can prevent users from validating if any line has an unscanned destination location when destination-location scanning is mandatory after scanning each product. To enforce this behavior, we can track whether a line has been modified and whether a destination location has been scanned and applied to that line. This allows us to identify which lines still require destination location scanning before validation can proceed. However, line state information is currently discarded and recreated on every save. As a result, information about lines that were updated and already had their destination location scanned is lost. This may incorrectly require users to rescan the destination location, even though it was previously scanned. To address this, we preserve the destination-scanned and modified state by carrying it forward from existing lines to their corresponding newly created versions using a loop. This ensures that destination location scan status is retained and users are not asked to rescan unnecessarily. opw-6069614 Forward-Port-Of: odoo/enterprise#113618
15 changes
Resolved issues and error corrections
This update fixes a readability issue in appointment email templates when dark mode is enabled. The team adjusted background colors and simplified template code to ensure content is clearly visible for all users. This improves the overall user experience and consistency across Odoo.
Original PR description
This PR fixes and improves the display of the mail templates and also cleans their code. For this, several commits are needed: - Commit 1 sets the mails' background color to white because a dark custom color has been specified. Before this change, the content was not readable when the dark mode was enabled since the background and the font had similar colors. - Commit 2 adds default values to avoid displaying variables that users cannot understand inside the editor and replaces some t-attf-style by style, as they contain no variable. Community PR: https://github.com/odoo/odoo/pull/249102 Task-5886471
This update resolves an issue where users without sign permissions were unable to access records with sign request activities, resulting in an access error. The fix uses 'sudo' to ensure access and prevents actions that trigger the error, improving the sign request workflow for all users.
Original PR description
**Steps to reproduce** - Have user A with Sign admin rights and user B without Sign rights. - With user A, create a sign request activity on a record that user B can access. Send the signature…
**Steps to reproduce** - Have user A with Sign admin rights and user B without Sign rights. - With user A, create a sign request activity on a record that user B can access. Send the signature request. - With user B, try to access the record. -> AccessError when trying to fetch the chatter. **Cause** By default, users get access to all the activities associated to records they have access to (see `_search` of `mail.activity`). This is an issue since some of the fields added in `_store_activity_fields` for the sign request activity display might not be accessible for a user with access to the activity. **Change** Use `sudo` to be able to display the activity, even if the user doesn't have access to the sign request. Also, in that case, `can_write` should be `False` in order to hide the action buttons of the activity, which trigger access errors when trying to make operations on the sign request. Another related change is to create the activity for the user creating the sign request, this avoids falling back on the `user_id` of the record associated with the activity and makes sure the activity's user has access to the sign request. opw-6157455 Forward-Port-Of: odoo/enterprise#118555 Forward-Port-Of: odoo/enterprise#116540
This update adds a direct link within the Timesheets Assistant to its official documentation. This makes it easier for users to quickly find answers to their questions and understand how to use the Timesheets Assistant effectively. It’s a small change designed to improve user support and knowledge.
Original PR description
This commit adds documentation link in Timesheets Assistant to redirect the user to the documentation of Timesheets Assistant. task-6095833 Forward-Port-Of: odoo/enterprise#119022 Forward-Port-Of: odoo/enterprise#118754
This update resolves an issue where the system incorrectly flagged incoterm requirements for export invoices containing service products. Previously, the system demanded incoterm information even for services, which is not required by tax regulations. This change ensures accurate invoice export to the tax agency.
Original PR description
With l10n_gt_edi: - Create an invoice with a partner without a country (in l10n_gt this is considered an export invoice) and a service product. When trying to export the invoice to the tax agency, the following alert is triggered: Incoterm is required on export invoice with goods product but it's currently missing However, service products do not require incoterm configuration. opw-6170409 Forward-Port-Of: odoo/enterprise#115833
This update corrects a misunderstanding in the payment flow for orders with a price of zero. Previously, paying a sum through the 'customer account' method incorrectly treated it as a return. The fix now hides the 'pay_later' payment method when the order price is zero, aligning with business requirements and preventing incorrect accounting.
Original PR description
Step to reproduce: - install "pos_settle_due" - create a pos order, set order price = 0, select a customer - go to payment page, select "customer account" as payment method - here you can set any…
Step to reproduce: - install "pos_settle_due" - create a pos order, set order price = 0, select a customer - go to payment page, select "customer account" as payment method - here you can set any amount to pay, ex 100$ - fulfill the order. Observation: - the order amount is 0, if we pay 100$ using customer account, it is considered as change (which means we returned it to customer) - As per PO, this flow doesn't make sense Issue: - customer has 100$ due for this order, but he won't be able to settle this as fetch order to settle with amount != 0, after commit [1] - [1] https://github.com/odoo/enterprise/commit/12af23d5382e972facfaa999e4c5ab30c97e8d1f https://github.com/odoo/enterprise/blob/951e5f42884c898bc14d9c32ae6a8f08c31ff06d/pos_settle_due/static/src/app/screens/partner_list/partner_line/partner_line.js#L35 Fix: - we hide payment method of type "pay_later" in case of 0 price order opw-6123699 Forward-Port-Of: odoo/enterprise#118864 Forward-Port-Of: odoo/enterprise#116556
This update optimizes the styling of the Odoo Enterprise home menu by replacing inefficient CSS selectors with CSS variables. This change improves page loading speed and overall performance, leading to a smoother user experience. The update ensures the home menu remains responsive and fast.
Original PR description
Avoid selectors after `:hover` and `:active`, as they can impact performance. CSS variables are now used instead. Replace hex color values with "0 0 0" RGB syntax to ensure compatibility with CSS variable usage. Forward-Port-Of: odoo/enterprise#119082
This update fixes an issue where intercompany sales and purchases with multiple identical products resulted in incorrect stock reservation during receipt picking. The fix ensures that all units of a product are properly reserved when processing intercompany transactions, preventing discrepancies in inventory tracking. This improves the accuracy of stock management between companies.
Original PR description
…lit for same-product lines When doing an intercompany Sale->Purchase with multiple lines having the same products, the receipt picking would be incorrectly assigned: - Enable Inter-Company…
…lit for same-product lines
When doing an intercompany Sale->Purchase with multiple lines having the same products, the receipt picking would be incorrectly assigned:
- Enable Inter-Company Transactions on both companies (Create and validate)
- Create SO in company A to company B with 2 lines having the same product P, Confirm. => Delivery in company A, Purchase and Receipts in company will be created => The SO/PO/Delivery/Receipt will all have 2 lines
- Validate delivery => On the receipt, the 2 units of P are reserved on the 1st move, and the 2nd move is not reserved.
https://github.com/user-attachments/assets/b4816051-120e-4226-9228-fd552649d5ef
---
### Test result without fix:
```
2026-04-23 13:16:44,577 48027 INFO oes_test_18.0 odoo.addons.sale_purchase_stock_inter_company_rules.tests.test_inter_company_so_to_po: Starting TestInterCompanySaleToPurchaseWithStock.test_02_inter_company_multiple_lines_with_same_product ...
2026-04-23 13:16:44,949 48027 INFO oes_test_18.0 odoo.addons.sale_purchase_stock_inter_company_rules.tests.test_inter_company_so_to_po: ======================================================================
2026-04-23 13:16:44,949 48027 ERROR oes_test_18.0 odoo.addons.sale_purchase_stock_inter_company_rules.tests.test_inter_company_so_to_po: FAIL: TestInterCompanySaleToPurchaseWithStock.test_02_inter_company_multiple_lines_with_same_product
Traceback (most recent call last):
File "/home/odoo/Odoo/src/18.0/enterprise/sale_purchase_stock_inter_company_rules/tests/test_inter_company_so_to_po.py", line 109, in test_02_inter_company_multiple_lines_with_same_product
self.assertRecordValues(purchase_from_a.picking_ids.move_ids, [
File "/home/odoo/Odoo/src/18.0/odoo/odoo/tests/common.py", line 709, in assertRecordValues
self.assertSequenceEqual(expected_reformatted, record_reformatted, seq_type=list)
AssertionError: Lists differ: [{'pr[18 chars]0, 'quantity': 1.0}, {'product_uom_qty': 1.0, 'quantity': 1.0}] != [{'pr[18 chars]0, 'quantity': 2.0}, {'product_uom_qty': 1.0, 'quantity': 0.0}]
First differing element 0:
{'product_uom_qty': 1.0, 'quantity': 1.0}
{'product_uom_qty': 1.0, 'quantity': 2.0}
- [{'product_uom_qty': 1.0, 'quantity': 1.0},
? ^
+ [{'product_uom_qty': 1.0, 'quantity': 2.0},
? ^
- {'product_uom_qty': 1.0, 'quantity': 1.0}]
? ^
+ {'product_uom_qty': 1.0, 'quantity': 0.0}]
? ^
```
OPW-6145683
Forward-Port-Of: odoo/enterprise#118805
Forward-Port-Of: odoo/enterprise#114873This update fixes a problem where AI responses weren't being correctly delivered to embedded AI Livechat instances. The issue stemmed from how the system handled streaming data, and has been resolved by changing the way the AI response is delivered, ensuring proper functionality for embedded livechat experiences.
Original PR description
AI livechat embedded on another origin could not receive AI responses. The response stream is requested with fetch(), so it bypassed the livechat CORS routing that only wraps RPC calls. The matching CORS controller was also exposed as JSON-RPC, which cannot return the streamed HTTP response correctly. Expose the CORS endpoint as an HTTP stream, route the embedded fetch call to it, and pass the livechat guest token explicitly. task-id-6201054 Forward-Port-Of: odoo/enterprise#118916 Forward-Port-Of: odoo/enterprise#117535
This pull request resolves errors occurring when generating CFDI invoices for payslips including IMSS disability time off. The fix ensures the required 'Incapacidades' node is correctly declared in the XML, addressing a legal requirement for Mexican payroll reporting. It also corrects an incorrect calculation of the total amount due, ensuring accurate invoice generation.
Original PR description
Several error are logged in the chatter when signing a payslip that includes an IMSS disability time off. Steps to reproduce: * Install l10n_mx_hr_payroll_account modules * Switch to "INNOVACION…
Several error are logged in the chatter when signing a payslip that includes an IMSS disability time off.
Steps to reproduce:
* Install l10n_mx_hr_payroll_account modules
* Switch to "INNOVACION VALOR Y DESARROLLO SA SA" company
* Go to Employees and open Cesar Osbaldo Cruz Solorzano
* Click on "Time Off" smart button and create a new time off with "Disability due to illness (IMSS)" type for "02/01/2026"(Any date).
* Go to Payroll > Payslips > Payslips and create a new pay run
* Select Salary Structure 'Mexico: Regular Pay', Pay Schedule 'Monthly' and the Period '01/01/2026 -> 01/31/2026'
* Click on Continue, select Cesar and click on Select
* Open the payslip, click on "Validate" and "Ok"
* Mark as paid, open the "Journal Entry" from the smart button and click on "Post".
* Back to the payslip, and click on "Generate CFDI" button.
* An error is added to the chatter.
### Missing node to declare disabilities
Original message
```py
An error occurred while signing the CFDI document with the government:
Code : NOM111 Message : Error no clasificado. Extra Info : El nodo
"Incapacidades" se debera informar si se incluye en percepciones la
clave 014 "Subsidios por Incapacidad" o bien en deducciones la clave 006
"Descuento por incapacidad".
```
Translated message
```py
An error occurred while signing the CFDI document with the government:
Code: NOM111 Message: Unclassified error. Extra Info: The "Incapacidades"
(Disabilities) node must be reported if the perception key 014
"Subsidios por Incapacidad" (Disability Subsidies) is included, or if
the deduction key 006 "Descuento por incapacidad" (Disability Deduction)
is included.
```
Legal Context:
According to Mexican law, IMSS disabilities must be declared in a specific XML node.
There are two primary scenarios for reporting these amounts:
* Deduction (Type 006): The employer does not pay for these days, as the IMSS is responsible for the payment to the employee.
This is the most common scenario.
* Perception (Type 014): The employer pays for these days as a superior benefit. For example, by law, the IMSS does not pay for the first 3 days of a disability due to illness, and employers are not obligated to cover them either. However, companies offering superior benefits may choose to pay these days as a "Disability Subsidy."
Solution:
The chosen approach is to configure the Deduction node.
For the `l10n_mx_regular_pay_imss_disabilities` rule, the `l10n_mx_concept` has been set to `l10n_mx_concept_d6` (D06 - Disability Deduction). This ensures the required node is added.
### Missing "ImporteMonetario" attribute
Original message
```
An error occurred while signing the CFDI document with the government:
Code : NOM95 Message : El atributo Deduccion:Importe no es igual a la
suma de los nodos Incapacidad:ImporteMonetario, ya que la clave
expresada en Nomina.Deducciones.Deduccion.TipoDeduccion es "006".
```
Translated message
```
An error occurred while signing the CFDI document with the government:
Code: NOM95 Message: The attribute "Deduccion:Importe" does not match
the sum of the "Incapacidad:ImporteMonetario" nodes, as the key
expressed in "Nomina.Deducciones.Deduccion.TipoDeduccion" is "006".
```
Problem:
The "Incapacidades" node requires the "ImporteMonetario" attribute, which should represent the sum of the monetary value associated with the disabilities.
Solution:
Add the "ImporteMonetario" attribute and calculate its value using `l10n_mx_daily_salary`.
### Invalid "DiasIncapacidad" format
```py
An error occurred while signing the CFDI document with the government:
Code : 301 Message : XML mal formado Extra Info : Element
'{[http://www.sat.gob.mx/nomina12}Incapacidad](http://www.sat.gob.mx/nomina12%7DIncapacidad)', attribute
'DiasIncapacidad': '4.0' is not a valid value of the local atomic type.
```
Problem:
Altough the defaultdict where the values are sum up, `number_of_days` is
a float field, and when we get back the value, it is a float, adding for
example 4.0 instead of 4, which is not a valid value.
Solution:
Cast the value to int.
### Duplicate deduction on disabilities
```py
Wrong python code defined for:
- Employee: Cesar Osbaldo Cruz Solorzano
- Version: False
- Payslip: Salary Slip - Cesar Osbaldo Cruz Solorzano - 05/01/2026 - 05/15/2026
- Salary rule: ISR (Income Tax) (ISR)
- Error: TypeError('cannot unpack non-iterable NoneType object') while
evaluating
"
def find_rates(x, rates):
for low, high, fix, rate in rates:
if low <= x <= high:
return low, high, fix, rate
gross = categories['GROSS']
result = 0
if gross:
isr_table = payslip._rule_parameter('l10n_mx_isr_tables')[version.schedule_pay]
low, high, fix, rate = find_rates(gross, isr_table)
result = -((gross - low) * rate + fix)
period_factor = payslip._rule_parameter('l10n_mx_schedule_table')[version.schedule_pay]
if period_factor >= 15:
period_factor = (period_factor / 30) * (365 / 12)
min_wage = payslip._rule_parameter('l10n_mx_daily_min_wage') * period_factor
if gross <= min_wage:
result_qty = 0.0
"
```
Problem:
The IMSS disability amount is being deducted twice:
1. During "Worked Days" calculation, the IMSS disability is already not considered because the work entries belong to the "Unpaid Work Entry Types" of "Mexico: Regular Pay" structure.
2. During "Salary Computation", the `IMSS_DISABLE` salary rule deducts another time because it is in the `TAXABLE_ALW` category, and this one is deducted in the `NET` rule.
When the disability covers more than half of the period (e.g., 20 days in a monthly schedule), the double deduction causes the NET to become negative. This prevents the ISR rule from finding a correct stage in the tax tables, leading to a traceback.
Example: For a monthly wage of 30,000.0 and 5 disability days:
- The total amount in "Worked Days" is 25,000.0 (disabilities already deducted).
- The IMSS_DISABLE rule calculates -5,000.0, and when the NET rule is calculated, the disabilities are deducted again. Total NET becomes 16,843.84 instead of the expected 20,834.85.
Solution:
Change the rule category to `INTERMEDIARY_COMPUTATION` and avoid the double deduction when the `NET` is calculated, as it is already considered in the "Worked Days".
### Incorrect values in the XML
The signing process completes without errors, but some amounts in the generated XML are incorrect.
Problem:
The introduction of the Deduction 006 (Disability) directly impacts the calculation of the SubTotal and Total attributes in the Comprobante node.
For a monthly payslip with a wage of 30,000.00 (daily salary of 1,000.00) and 5 disability days (work risk), the values are calculated incorrectly as follows:
Attribute | Calculation | Actual Value | Correct Value
---------------------|----------------------------------|--------------|--------------
Comprobante:SubTotal | Sum of Perceptions (P01) | 25000.00 | 30000.00 (1)
Comprobante:Total | SubTotal - Total Deductions (2) | 15803.74 | 20803.74
(1) Must include the 5,000.00 from disabilities to balance the deduction.
(2) Total Deductions = D06 (5,000.00) + ISR (3,451.65) + IMSS (744.61) = 9,196.26.
The Total is currently undercalculated because the 5,000.00 is being
deducted from the SubTotal that already had those 5,000.00 excluded.
Solution:
Since the `SubTotal` is derived from Perceptions, and the "(P01)
Salaries, Wages, Stripes, and Day Labor" amount is driven by the
`GROSS_WITHOUT_HOLIDAY` rule, the disability amount must be added. This
balances the Deduction 006, ensuring `SubTotal` is correct.
### Absenteeism and Disabilities
By law, the calculation of IMSS contributions depends on these two types of unpaid days:
* Disabilities: Refers to medical leave issued by the Institute (IMSS).
* Absenteeism: Refers to unjustified leave; apply for periods of fewer than 8 days.
Source: [Artículo 31](https://www.imss.gob.mx/sites/all/statics/pdf/leyes/LSS.pdf)
Translated text:
Article 31. When wages are not paid due to the employee's absence from work, but the employment relationship persists, the monthly contribution shall be adjusted according to the following rules:
I. If the employee's absences are for periods of fewer than eight consecutive or non-consecutive days, contributions shall be calculated and paid for such periods only for the sickness and maternity insurance...
If the employee's absences are for periods of eight consecutive days or more, the employer shall be released from the payment of employer-employee contributions...
IV. In the case of absences covered by medical disabilities issued by the Institute, it shall not be mandatory to cover the employer-employee contributions, except regarding the retirement branch.
The following table summarizes the contribution requirements based on the type of absence:
Insurance Branch (RAMA) | Section I (Absenteeism) | Section IV (Disability)
--------------------------------|-------------------------|------------------------
Sickness and Maternity | Paid | Not Paid
Disability and Life | Not Paid | Not Paid
Severance and Old Age | Not Paid | Not Paid
Work Risk | Not Paid | Not Paid
Daycare and Social Benefits | Not Paid | Not Paid
INFONAVIT | Not Paid | Paid
Retirement | Not Paid | Paid
The type of unpaid day to be considered depends on the specific insurance branch being calculated within the employer-employee contributions.
### Add test for cfdi with disabilities.
target: 19.0
task-6066160
Forward-Port-Of: odoo/enterprise#116819This update resolves an error that occurred when opening payslips with multiple attachments. The fix prevents a data conflict that arose when deleting related documents, ensuring payslips can be opened and viewed correctly. It improves the stability of the payroll process.
Original PR description
Currently, an error occurs when a user opens a payslip. **Steps to Reproduce:** - Install the `documents_hr_payroll` module. - Go to `Payroll` > `Payslips` > `Payslips` and open an `existing payslip`…
Currently, an error occurs when a user opens a payslip. **Steps to Reproduce:** - Install the `documents_hr_payroll` module. - Go to `Payroll` > `Payslips` > `Payslips` and open an `existing payslip` or `create a new one`. - Add `two or more attachments` to the payslip. - Go to `Documents` and, in the left panel, navigate to `Company` > `Employees - YourCompany` > `Payroll YourCompany`, then `Move to Trash` all documents related to those `payslip attachments`. - Go back to `Payslips` and open the `same payslip` again. `ValueError: Expected singleton: hr.payslip(4, 4)` With [this commit], the attachment's "Add to Document" action allows creating a Document from a mail.thread record attachment. When the user deletes the documents related to the attachments and then opens the payslip again, the compute method runs to calculate the linked document ID for the payslip attachments and tries to retrieve attachments without documents [1]. The issue occurs when two or more attachments share the same payslip ID. While mapping the res_id of the attachments and grouping them by ID, the same payslip record is included multiple times for a single key [2] [3], which raises error here [4]. This commit ensures that the mapped res_id values are wrapped in a set, so duplicate IDs are removed and each payslip ID appears only once. [this commit]: https://github.com/odoo/enterprise/commit/5fa4b74a2345ddd4858585c5e9a780d1ca5add57 [1]- https://github.com/odoo/enterprise/blob/21477b333f7a33cb582cd806236e4f9f8346d022/documents/models/ir_attachment.py#L26 [2]- https://github.com/odoo/enterprise/blob/21477b333f7a33cb582cd806236e4f9f8346d022/documents/models/ir_attachment.py#L45 [3]- https://github.com/odoo/enterprise/blob/21477b333f7a33cb582cd806236e4f9f8346d022/documents/models/ir_attachment.py#L48 [4]- https://github.com/odoo/enterprise/blob/21477b333f7a33cb582cd806236e4f9f8346d022/documents_hr_payroll/models/hr_payslip.py#L74-L76 sentry-7494229711 Forward-Port-Of: odoo/enterprise#118033
This update resolves two minor bugs in the point-of-sale test suite. Specifically, it corrects how test results are evaluated and handles potential type mismatches, ensuring the tests accurately reflect the functionality of the POS system. This improves the reliability of the testing process.
Original PR description
..., l10n_es_pos, l10n_jo_edi_pos, l10n_br_edi_pos
---
Fix two bugs in the checkTicketData() test helper:
- Replace falsy check `!statement` with `!statement.length` to
correctly handle empty NodeList results from querySelectorAll,
as an empty NodeList is still truthy.
- Replace loose equality `ruleFound == rule.negation` with strict
equality `ruleFound === (rule.negation || false)` to avoid
unintended type coercion when `rule.negation` is undefined.
---
Task: https://www.odoo.com/odoo/project/1737/tasks/6147566
Forward-Port-Of: odoo/enterprise#118557
Forward-Port-Of: odoo/enterprise#114581This update resolves an error that prevented users from canceling draft POS orders. The issue stemmed from a recent code change that incorrectly returned order data. The fix removes this problematic code, restoring the ability to cancel draft orders as intended.
Original PR description
Currently an error is generated when the user tries to cancel a draft POS order as follows: - Install the `pos_enterprise` module with demo data - Open the register of `Furniture store` and select…
Currently an error is generated when the user tries to cancel a draft POS order as follows: - Install the `pos_enterprise` module with demo data - Open the register of `Furniture store` and select any product - Click on the `Upload` icon to save the draft order and go to the backend. - Navigate Orders > Orders > open Draft order - Click the `cog` icon and click `Cancel Order` >>> Error occurs This issue is caused by the recent refactor introduced in [1]. The `action_pos_order_cancel` action now returns the `order` (`pos.order` recordset) instead of default returning `None`. As a result, the `action` variable contains a `pos.order` recordset, and an error is raised at line [2] when `setdefault` is called on it, since `setdefault` expects a dictionary-like object. This commit fixes the above issue by removing the code that returns the `pos.order` object from the action. As a result, the action now behaves as expected and returns the default value (`None`). [1]: https://github.com/odoo/enterprise/commit/27f57036a1d0468efe6e68d7aceafe0f01b21f93 [2]: https://github.com/odoo/odoo/blob/48f93ca056633bd5cba36b66ee1008fb57ca666c/addons/web/controllers/utils.py#L24 Sentry-7354160052 Forward-Port-Of: odoo/enterprise#118035
This update resolves an issue caused by a recent change in the HR schedule layout. The update adjusts the view structure to ensure schedules display correctly within the new group layout. This improves the overall usability of the HR schedule feature.
Original PR description
Fixes the view breakdown caused by migrating the schedule separator to a group layout in the base hr view. Task: 6267822
This update allows users to efficiently edit analytics distribution data directly within asset records, mirroring the functionality available for journal items. This enhancement streamlines the process of analyzing asset performance and provides a more consistent user experience across Odoo Enterprise.
Original PR description
This commit fixes the multi-edit of analytics distribution field in assets form view. The multi-edit option was added to the analytics distribution widget, same as in the journal items. task-6218188 Forward-Port-Of: odoo/enterprise#119054 Forward-Port-Of: odoo/enterprise#118042
This update addresses a security vulnerability where test databases could incorrectly pass subscription checks on Odoo.com. The change adds a new verification step specifically for duplicated SAAS databases with a neutralized status, ensuring accurate subscription validation and preventing unauthorized access. This enhances the security and reliability of the Odoo Enterprise platform.
Original PR description
Odoo.com does not create a distinction between a production and duplicated SAAS database. This allows test databases to pass the check for subscription. This commit adds an additional check for duplicated SAAS databases with a neutralised status. task-6249752 Forward-Port-Of: odoo/enterprise#118281
3 changes
Resolved issues and error corrections
This update resolves a bug where the AI's search suggestions were incorrectly applied to multiple Odoo tabs. The fix ensures that AI-driven actions only affect the tab where they originated, preventing unexpected behavior across different views. This improves the stability and reliability of the AI feature.
Original PR description
[FIX] ai: scope AI_ADJUST_SEARCH bus event to originating session The AI_ADJUST_SEARCH handler did not check aiSessionIdentifier, so any browser tab subscribed to the bus would apply the AI's…
[FIX] ai: scope AI_ADJUST_SEARCH bus event to originating session
The AI_ADJUST_SEARCH handler did not check aiSessionIdentifier, so any
browser tab subscribed to the bus would apply the AI's resulting search
to its current view. When the view's model lacked a field referenced in
the response (e.g. an "Active or Queue" filter on stage_id leaking from
a project.task chat into a timesheet view), the view raised a KeyError.
Align it with the four AI_OPEN_MENU_* handlers, which already drop events
from other sessions since https://github.com/odoo/enterprise/commit/d85e17d9ccf70f9cfd51c7d6b2a5b52510807484.
Steps to reproduce:
- Run Odoo with the crm and contacts modules installed
- Open two tabs:
- Tab 1: navigate to CRM and ensure you are in List view
- Tab 2: navigate to Contacts and ensure you are also in List view
- In Tab 1 (CRM), open the Ask AI chat and type "Switch to Kanban view"
- CRM switches to Kanban view as expected
- Bug: Tab 2 (Contacts) also switches to Kanban view along with Tab 1,
even though you did not interact with itThis update resolves an issue where attached documents generated for Colombia were incorrectly using a generic line number instead of the required official document ID. This caused rejection by DIAN validation tools. The fix ensures the correct document ID is used, allowing the documents to pass validation and integrate correctly with external systems.
Original PR description
### Issue When generating the attached document (AttachedDocument) for Colombia, the parent document reference tag <cbc:ID> incorrectly exported a generic line counter instead of the actual document…
### Issue
When generating the attached document (AttachedDocument) for Colombia, the parent document reference tag <cbc:ID> incorrectly exported a generic line counter instead of the actual document identification number
While the DIAN platform itself accepted the file, this caused rejections in external validation tools and third-party software because they could not resolve the link back to the original invoice
DIAN Documentation: https://www.dian.gov.co/impuestos/factura-electronica/Documents/Anexo_tecnico_factura_electronica_vr_1_7_2020.pdf
On page 213 there is an example for ParentDocumentLineReference
On page 216 there is the specification that does not show any check
Example of the incorrect XML structure:
```xml
<cac:ParentDocumentLineReference>
<cbc:LineID>1</cbc:LineID>
<cac:DocumentReference>
<cbc:ID>1</cbc:ID>
</cac:DocumentReference>
</cac:ParentDocumentLineReference>
```
Expected XML structure:
```xml
<cac:ParentDocumentLineReference>
<cbc:LineID>1</cbc:LineID>
<cac:DocumentReference>
<cbc:ID>SETP990001021</cbc:ID>
</cac:DocumentReference>
</cac:ParentDocumentLineReference>
```
### Cause
In the template, the value for <cbc:ID> was retrieved using `parent_document.get('id')` which fetched the sequential loop index https://github.com/odoo/enterprise/blob/cd25713fd2c35737d98db29df72b2d07ae9146e8/l10n_co_dian/views/templates.xml#L272-L275
The dictionary parsing logic did not extract the true document identifier from the XML tree response or the original XML data https://github.com/odoo/enterprise/blob/13dc30679e382df5845993c880a97df600c39ed4/l10n_co_dian/models/l10n_co_dian_document.py#L429-L432
### Steps to reproduce
- Install `l10n_co_dian`
- Setup DIAN configuration
- Generate an attached document for a commercial event or invoice
- Open the generated XML file
Before the fix, the `<cac:ParentDocumentLineReference>/<cac:DocumentReference>/<cbc:ID>` tag contains a technical integer like "1" instead of the official document sequence number
opw-6164321This update resolves a problem where users couldn't correctly insert dynamic fields into SMS templates within Marketing Automation. The fix adds a necessary setting to ensure the system uses the correct data source (mailing_model_real) instead of defaulting to a different field, allowing users to build SMS campaigns with dynamic content. This ensures proper functionality for SMS marketing.
Original PR description
The SMS template form view in Marketing Automation was missing the `dynamic_placeholder_model_reference_field` option on the `body_plaintext` field. Without this option, the dynamic placeholder hook falls back to looking for a `model` field in the record data, but `mailing.mailing` uses `mailing_model_real` instead. Steps To Reproduce: - Install marketing_automation_sms and CRM modules (also activate Leads). - Start a new Campaign in Marketing Automation. - Set Target to Lead/Opportunity. - Add New Activity > Activity Type = SMS > SMS Template = create one. - In the SMS template dialog, click the "Insert Field" button. - Error appears: "You need to select a model before opening the dynamic placeholder selector." Ticket [link](https://www.odoo.com/odoo/project.task/5488849) opw-5488849 Forward-Port-Of: odoo/enterprise#104423
5 changes
Resolved issues and error corrections
This update ensures that refund flows work seamlessly when DIAN POS is enabled. Previously, a technical issue caused the customer label to appear blank and refund attempts to fail. This fix guarantees the correct customer data is loaded for all POS transactions using DIAN POS.
Original PR description
When DIAN POS is enabled, l10n_co_edi_pos auto-assigns the `Consumidor Final` partner to new POS orders. However, POS only preloads a limited partner set in frontend memory. If `Consumidor Final` is not part of that set, the order gets a partner id whose full partner data is not loaded in the UI. This causes the customer label to appear blank and refund flows to fail with "Can't change customer" mentioning `undefined`. To avoid this, always include the final consumer partner in `get_limited_partners_loading()`. This matches the approach already present in newer branches. opw-6238935
This update resolves an issue where spreadsheet formulas in the Account module were sending company IDs as strings, leading to server errors. The change ensures company IDs are converted to numbers, handling both numeric and null values correctly for accurate calculations. This improves spreadsheet stability and reliability.
Original PR description
Current behavior before PR: - The `ODOO.CREDIT`, `ODOO.DEBIT`, and `ODOO.BALANCE` formulas passed `companyId.value` directly to the server without converting it to a number. - If a user passed company_id as a string (e.g., '1' from a cell), it was sent to the server as a string, causing a server error. Desired behavior after PR is merged: - `companyId` is converted using toNumber() before being passed to the getter and the server, so '1' becomes 1. - null is preserved as-is (no company filter) while any non-null value is safely cast to an integer. Task: [6240005](https://www.odoo.com/odoo/project/2328/tasks/6240005) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#266009
This update fixes an issue where the 'Out of Office until...' date displayed in the Discuss chat was incorrect when users were in negative timezones. The fix ensures the date is always shown in UTC, resolving a display discrepancy and improving the accuracy of leave information for employees and managers.
Original PR description
Issue: ---------------------------------------- When in a negative timezone, the "Out of Office until..." text in discuss shows the day before. Steps to reproduce:…
Issue: ---------------------------------------- When in a negative timezone, the "Out of Office until..." text in discuss shows the day before. Steps to reproduce: ---------------------------------------- - Change the timezone of the user to "America/Toronto" for example - Have an employee currently on leave until tomorrow - Open discuss to chat with this employee - The "Out of Office until..." shows today's date Cause: ---------------------------------------- When calling `toLocaleString()` without a timezone specified in the options, the date is converted to local time (in the browser's timezone). Here `persona.out_of_office_date_end` is just a date, `deserializeDateTime()` converts it to a timestamp, so the same day at 0am. Then if the timezone is negative, the timestamp becomes an hour the previous day when calling `toLocaleString()`. The format we give `DateTime.DATE_MED` doesn't include hours, so we just display the previous date. Solution: ---------------------------------------- Add `timeZone:"UTC"` in the options to avoid the timezone conversion. opw-6252040 Forward-Port-Of: odoo/odoo#267479
This update reverts a recent change that was disrupting the process of reconciling bank statements with previous transactions. It ensures users can continue to accurately match current transactions with historical data. This change is a fix to improve usability and prevent workflow disruptions.
Original PR description
This reverts commit e2a9f3bfbb8a89533146f76509bf2785c085ebea as it disrupt workflow where users needs to reconcile with a previous bank transaction Enterprise PR: https://github.com/odoo/enterprise/pull/118169 opw-6230807 Forward-Port-Of: odoo/odoo#266057
This update addresses a problem where manual reconciliation operations were incorrectly being matched. It reverses a previous change that caused this issue, ensuring that reconciliation processes work as intended. This prevents potential data discrepancies and ensures accurate financial reporting.
Original PR description
This reverts commit 038f527793757c3148b775af1657c5a70a5abc66. opw-6230807 Forward-Port-Of: odoo/enterprise#118169