Daily updates from Odoo
Wednesday, August 19, 2026
13 changes · saas-19.3
Resolved issues and error corrections
Fixed an issue where switching to a pivot view through the AI agent could cause the view to crash or open without selected measures. The update waits for the pivot view to finish loading before applying AI changes and keeps default measures when none are requested, improving reliability for users working with AI-assisted reporting.
Original PR description
When the AI agent switched from another view to a pivot view, the pivot view could crash or open without any active measures. The AI controller patch applies the agent's adjustments upon receiving…
When the AI agent switched from another view to a pivot view, the pivot view could crash or open without any active measures. The AI controller patch applies the agent's adjustments upon receiving the `APPLY_AI_ADJUST_MODEL` bus event. However, the event could be processed while the pivot model was still executing `_loadData()`. In that case, the following sequence occurred: * `_loadData()` started and awaited. * The controller patch was executed. * The patch called `toggleMeasures()`. * `toggleMeasures()` waited for `_loadData()` to complete. * `_loadData()` finished and updated the metadata with the available measures. * `toggleMeasures()` resumed and wrote back the metadata snapshot it had taken before waiting. Since `toggleMeasures()` operates on a snapshot of the metadata, the measures populated by `_loadData()` were lost when the snapshot replaced the current metadata, leaving the pivot model without its `measures` metadata and causing the view to crash. Prevent this race condition by waiting for the pivot model initialization to complete before applying the AI adjustments. Also preserve the default active measures when the AI agent does not explicitly request any measures instead of clearing them and opening an empty pivot view. task-6384368 Forward-Port-Of: odoo/enterprise#125897
Salary contract benefits can now use all relevant contract benefit fields, including fields provided by local payroll modules. This prevents missing options and fixes an error that could occur when saving the public field selection.
Original PR description
1- The benefit fields related to the hr.version have a domain that limits them to the whitelisted fields used to copy values from a template, which does not always include benefit fields. The…
1- The benefit fields related to the hr.version have a domain that limits them to the whitelisted fields used to copy values from a template, which does not always include benefit fields. The advantage of the whitelist is that it factored in for the allowed countries, so instead of duplicating this logic to benefit fields and implementing it in every l10n, we can check which module the field comes from.
example:
The field [`company_car_total_depreciated_cost`](https://github.com/odoo/enterprise/blob/ce691cd6aaacfb86cd866698d2fcc3fe930912cb/l10n_be_hr_payroll_fleet/models/hr_version.py#L62) cannot be selected as `res_field_id` when it should be possible as we see in the [data](https://github.com/odoo/enterprise/blob/ce691cd6aaacfb86cd866698d2fcc3fe930912cb/l10n_be_hr_contract_salary/data/hr_contract_salary_benefit_data.xml#L6), it is not whitelisted because we dont want to copy its value from a template.
2- Another fix is the inverse of the public field, there's a traceback because the selection field is always converted to a string and cannot be used to browse as is.
```py
File "/data/build/enterprise/hr_contract_salary/models/hr_contract_salary_benefit.py", line 238, in _inverse_res_field_public
record.res_field_id = self.sudo().env['ir.model.fields'].browse(record.res_field_public)
^^^^^^^^^^^^^^^^^^^
File "/data/build/odoo/odoo/orm/fields.py", line 1890, in __set__
write_value = self.convert_to_write(value, records)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/build/odoo/odoo/orm/fields_relational.py", line 387, in convert_to_write
return value.id
^^^^^^^^
File "/data/build/odoo/odoo/orm/fields_misc.py", line 115, in __get__
raise ValueError("Expected singleton: %s" % record) from None
ValueError: Expected singleton: ir.model.fields('1', '7', '3', '8', '4')
```
Forward-Port-Of: odoo/enterprise#127743Fixed an issue that could prevent customers from opening their cart after a rental product order was changed into a regular sales order. The cart now only shows rental period details when the order still has an active rental period, avoiding a checkout-blocking error.
Original PR description
Currently, an error occurs when a user adds a rental product to the cart, opens the corresponding sales order, removes the rental period, and then opens the cart again. Steps to replicate: - Install…
Currently, an error occurs when a user adds a rental product to the cart, opens the corresponding sales order, removes the rental period, and then opens the cart again. Steps to replicate: - Install `website_sale_renting` with demo. - Open website > shop > add the product named `Projector`. - Click Ecommerce in the menu bar > Orders . - Remove the `Confirmed` filter > Click on the top order (should be containing the projector product.) - Remove the `Rental Period` and go to the cart. Error: ``` QWebError: Error while rendering the template: AttributeError: 'bool' object has no attribute 'time' Template: website_sale.shorter_cart_summary ``` Cause: - When the user removes the rental period (`rental_start_date` and `rental_end_date`), both fields are set to `False`. When the cart is opened again, these values trigger the error in [line]. - Since the rental period has been removed from the order, the order is converted to a regular Sales Order (see [PR] and its [task]). Therefore, the Rental Period should no longer be displayed. Solution: - Use `is_rental_order` to determine whether to render the rental period instead of `has_rentable_lines`, since `has_rentable_lines `only checks whether the product is rentable [1], which is determined by the product's `rental_periodicity` [2]. - `is_rental_order` is a better check here because it indicates whether the rental period is actually defined on the order [3]. [line]: https://github.com/odoo/enterprise/blob/7c80c9ffa9e7812267f2ac285e3a3fc5ca501814/website_sale_renting/views/templates.xml#L207 [task]: https://www.odoo.com/odoo/all-tasks/6003684 [PR]: https://github.com/odoo/enterprise/pull/106381/commits/56ec41d81f7536f047a1586a12ea6f6e8414b844 [1]: https://github.com/odoo/enterprise/blob/f23ef9c604d8ce6be152d5e5bf6f72bd68b31451/sale_renting/models/sale_order.py#L140-L143 [2]: https://github.com/odoo/enterprise/blob/f23ef9c604d8ce6be152d5e5bf6f72bd68b31451/sale_renting/models/sale_order_line.py#L61-L64 [3]: https://github.com/odoo/enterprise/blob/f23ef9c604d8ce6be152d5e5bf6f72bd68b31451/sale_renting/models/sale_order.py#L135-L138 sentry-7663524549
Fixed an issue where a customer manually assigned to a planning shift could be removed when the worker signed in or completed the shift. This keeps shift customer information stable even when the shift is linked to a sales order.
Original PR description
Before this commit, when `sale_planning` module is installed after `planning_field_service` and the user sets a customer onto a shift, the customer could be removed when the user signs in or complete the shift. This issue is because `sale_planning` module defined `partner_id` field as a related field `related="sale_order_id.partner"` and `planning_field_service` module stores the field and so the field will always follows the partner set on the SO linked even if the user sets a customer on the shift. This commit removes the related attribute to replace it by a compute and a search method to have the exact same behavior but the search method will be short-circuited if the partner_id field is stored. task-5264800 Forward-Port-Of: odoo/enterprise#122034
DIN 5008 business documents now consistently show dates in the expected day.month.year format for Germany, Austria, and Switzerland, regardless of the user's language setting. This prevents confusing or non-compliant date displays on invoices, quotations, purchase orders, follow-ups, and field service documents.
Original PR description
* = din5008_account_followup, din5008_industry_fsm **Steps to reproduce:** * Install the **Germany - Accounting** (`l10n_de`) module (which pulls in `l10n_din5008`) * Set the document layout to **DIN…
* = din5008_account_followup, din5008_industry_fsm
**Steps to reproduce:**
* Install the **Germany - Accounting** (`l10n_de`) module (which pulls in `l10n_din5008`)
* Set the document layout to **DIN 5008** and generate any PDF report (invoice, quotation, purchase order, etc.).
**Observed behavior (date format):**
* All dates in the information block (Invoice Date, Due Date, Delivery Date, Order Date, etc.) are rendered in `yyyy-mm-dd` format instead of the expected `dd.MM.yyyy` format used in DE, AT, and CH.
**Cause (date format):**
* All `t-options="{'widget': 'date'}"` directives across the DIN 5008 template family rely on the active user's language locale for date formatting. If the user language is not `de_DE`, dates render in the locale's default format (e.g. `yyyy-mm-dd` for `en_US`).
**Fix (date format):**
* Add `'format': 'dd.MM.yyyy'` explicitly to all `t-options` date widgets across all DIN 5008 report templates (`l10n_din5008`, `l10n_din5008_sale`, `l10n_din5008_purchase`, `l10n_din5008_sale_subscription`, `l10n_din5008_repair`, `l10n_din5008_account_followup`, `l10n_din5008_industry_fsm`).
* This is correct for all three countries using DIN 5008 (DE, AT, CH), which all follow the `dd.MM.yyyy` convention.
opw-6392649
Forward-Port-Of: odoo/enterprise#128209
Forward-Port-Of: odoo/enterprise#126006ISO 20022 payment files now include the beneficiary's state or province and second address line when available. This helps prevent banks, especially in North America, from rejecting vendor wire transfers because required address details are missing.
Original PR description
The PstlAdr block written into pain.001 files never contains the partner's state/province nor the second street line, even when they are set on the record: _get_all_addr() now returns them, but…
The PstlAdr block written into pain.001 files never contains the partner's state/province nor the second street line, even when they are set on the record: _get_all_addr() now returns them, but _get_PstlAdr() also needs to write them out. Some North American banks reject wire transfers whose beneficiary address lacks the state/province, so those payments fail regardless of how complete the vendor record is. Emit CtrySubDvsn when the address has a state, before Ctry as required by the element order of the PostalAddress schema, and append street2 to the street address line. Steps to reproduce: - Install Accounting and enable a generic ISO 20022 payment method on a bank journal - Create a vendor located in the US or Canada with a complete address, including the state and a second street line - Register a vendor payment, add it to a batch and generate the pain.001 file - The creditor PstlAdr has no state/province, and its street line only carries the first street field: the street2 part is dropped Requires odoo/odoo#282518, which makes _get_all_addr() return the state and street2. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/enterprise#128021 Forward-Port-Of: odoo/enterprise#127958
Payment files now include the state or province and second address line from vendor or employee address records. This helps prevent bank transfer rejections, especially in countries like the US and Canada where state or province details are often required.
Original PR description
_get_all_addr() feeds the postal address block of generated pain.001 payment files, but does not return the partner's state nor the second street line. The beneficiary state/province and street…
_get_all_addr() feeds the postal address block of generated pain.001 payment files, but does not return the partner's state nor the second street line. The beneficiary state/province and street complement (suite, unit, ...) therefore never appear in the generated file, even when they are set on the partner, and there is no way to fix it from the record. Some North American banks reject wire transfers whose beneficiary address lacks the state/province, so those payments fail regardless of how complete the vendor record is. Return the state code and street2 alongside the other address components, from the partner for the base implementation and from the employee private address for the hr one, so the payment engine can write them in the PstlAdr block. Steps to reproduce: - Install Accounting and enable a generic ISO 20022 payment method on a bank journal - Create a vendor located in the US or Canada with a complete address, including the state and a second street line - Register a vendor payment, add it to a batch and generate the pain.001 file - The creditor PstlAdr has no state/province, and its street line only carries the first street field: the street2 part is dropped Companion enterprise PR emitting the state in the generated file: odoo/enterprise#127958 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#282620 Forward-Port-Of: odoo/odoo#282518
Store pickup locations are no longer shown as selectable delivery addresses during checkout. This prevents shoppers from accidentally choosing an internal pickup-point record instead of their own delivery address, keeping the checkout flow clearer and less error-prone.
Original PR description
Steps to produce: --- - Install `website_sale_collect` module. - Create and publish a product. - Add it to the cart and proceed to checkout. - Fill in the address and confirm. - Select a `pick-up in…
Steps to produce: --- - Install `website_sale_collect` module. - Create and publish a product. - Add it to the cart and proceed to checkout. - Fill in the address and confirm. - Select a `pick-up in store` delivery method. - Click the edit icon on the contact details. - Confirm without making any changes. Issue: --- - The pick-up point address appears as a selectable delivery address in the contact details list, which it should not. Root cause: --- - When a pick-up point is selected, `set_pickup_location` calls `_address_from_json` ([1]), which creates a child `res.partner` record with `type='delivery'` and sets `pickup_delivery_method_id` to identify it as a pick-up point address. Later, when the user returns to the address page, `_prepare_address_data` calls `_get_delivery_address_domain` ([2]) from `portal`. This method returns all child partners with `type='delivery'` without distinguishing between user-created delivery addresses and the auto-generated pick-up point addresses As a result, the pick-up point address incorrectly appears in the checkout address list. Solution: --- - As specified in [task], partners created through this flow should be archived. However, in the referenced [commit], the `active=False` flag was removed when creating the partner, causing newly created partners to remain active. Override `_get_delivery_address_domain` to exclude pick-up point addresses. Since auto-generated pick-up point addresses always have `pickup_delivery_method_id` set, they are filtered out from the checkout address list, while manually created delivery addresses remain unaffected. [1]https://github.com/odoo/odoo/blob/fb6298e50a7c8ded2800254e8715336eeb37deb5/addons/website_sale_stock/models/res_partner.py#L16-L72 [2]https://github.com/odoo/odoo/blob/fb6298e50a7c8ded2800254e8715336eeb37deb5/addons/portal/models/res_partner.py#L51-L55 [task]: https://www.odoo.com/odoo/project/49/tasks/3645144 [commit]: https://github.com/odoo/odoo/commit/fb74a371407ee19c6b1a3ab9f5a7b314978cb5cb opw-6356778 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
DIN 5008 business documents now show dates in the expected German, Austrian, and Swiss format regardless of the user’s language settings. Company footers also use the appropriate country-aware commercial register label, avoiding misleading German-specific text for Austrian and Swiss companies.
Original PR description
* = de, din5008, din5008_purchase, din5008_repair, din5008_sale **Steps to reproduce:** * Install the **Germany - Accounting** (`l10n_de`) module (which pulls in `l10n_din5008`) * Set the document…
* = de, din5008, din5008_purchase, din5008_repair, din5008_sale
**Steps to reproduce:**
* Install the **Germany - Accounting** (`l10n_de`) module (which pulls in `l10n_din5008`)
* Set the document layout to **DIN 5008** and generate any PDF report (invoice, quotation, purchase order, etc.).
**Observed behavior (date format):**
* All dates in the information block (Invoice Date, Due Date, Delivery Date, Order Date, etc.) are rendered in `yyyy-mm-dd` format instead of the expected `dd.MM.yyyy` format used in DE, AT, and CH.
**Observed behavior (commercial register):**
* The footer always shows `HRB-Nr.:` regardless of whether the company has a commercial register entry.
* The abbreviation `HRB-Nr.:` appears even for Austrian and Swiss companies, where the commercial register number is a German-specific concept.
* In the company form view, the field is labeled generically as "Company ID" instead of "Commercial Register Number" for German companies.
**Cause (date format):**
* All `t-options="{'widget': 'date'}"` directives across the DIN 5008 template family rely on the active user's language locale for date formatting. If the user language is not `de_DE`, dates render in the locale's default format (e.g. `yyyy-mm-dd` for `en_US`).
**Cause (commercial register):**
* The footer renders `company.company_registry` unconditionally with no country guard and no label.
**Fix (date format):**
* Add `'format': 'dd.MM.yyyy'` explicitly to all `t-options` date widgets across all DIN 5008 report templates (`l10n_din5008`, `l10n_din5008_sale`, `l10n_din5008_purchase`, `l10n_din5008_sale_subscription`, `l10n_din5008_repair`, `l10n_din5008_account_followup`, `l10n_din5008_industry_fsm`).
* This is correct for all three countries using DIN 5008 (DE, AT, CH), which all follow the `dd.MM.yyyy` convention.
**Fix (commercial register):**
* Remove the hardcoded `HRB-Nr.:` label from the footer and instead render `company.partner_id.company_registry_label` (which is country-aware).
* Update the duplicate contact warning message to use the country-aware label via `company.partner_id.company_registry_label`, backed by a new `_get_company_registry_labels` override in l10n_de that registers `Commercial Register Number` for `DE`.
* In the company form view (`l10n_de`), hide the generic "Company ID" field for German companies and show a relabeled instance with `string="Commercial Register Number"` instead.
opw-6392649
Forward-Port-Of: odoo/odoo#282964
Forward-Port-Of: odoo/odoo#279085This update makes the product variant setting available when only Point of Sale is installed. It ensures businesses on the OAF plan can access the same variant option seen in other areas, so the setup matches expected behavior and can be configured when needed.
Original PR description
If only PoS is installed (if you are on the OAF plan). The variants settings is unavailable and cannot be activated. Steps to reproduce: ------------------- * Install only PoS * Look for variant in settings > Observation: The option is not showing up Why the fix: ------------ The setting is just a copy of the other places where the settings is available. opw-6378568
This change corrects how self-order validates combo products, making sure each combo item is linked to the right parent combo line. It prevents incorrect combinations from being accepted and helps avoid order entry mistakes for customers using self-order kiosks.
Original PR description
Be sure that combo product of the current line belong to its combo parent line. Forward-Port-Of: odoo/odoo#282809 Forward-Port-Of: odoo/odoo#281741
Fixed an issue where clicking a suggested mention could keep the typed search text instead of inserting the selected name. This makes mention and autocomplete selections more reliable, especially when the list changes quickly while typing.
Original PR description
Before this commit, clicking a composer suggestion could leave the composer with the typed search instead of the selected name, as in the test "Mention a partner with special character (e.g. apostrophe ')" on runbot: Failed to find 1 of ".o-mail-Composer-input" with value "..." (Timeout of 10 seconds). Found 0 instead. This happens because NavigableList looks up the clicked option by index in its current props, while the item clicked comes from the last render. Typing "@" lists the two members of the channel and typing "Pyn" drops one of them: owl assigns the filtered options one frame before it patches the list, so a click in between looks up index 1 in a list of one option, finds nothing and returns. This commit passes the rendered option to the click handler, keeping the index lookup as a fallback so that the signature stays the same on a stable version. https://runbot.odoo.com/odoo/error/946154 Forward-Port-Of: odoo/odoo#282897
The shop now uses the same searchable product fields for both result matching and filter counts. This avoids cases where hidden HTML or technical text caused too many products to be processed, making search and filters more reliable for shoppers.
Original PR description
The `/shop` product results and facets use different search fields. In particular, facets search raw `website_description` HTML, causing terms such as `weight` to match CSS like `font-weight` and process far more products than are displayed. Use one shared field list for both paths: - `name` - `variants_default_code` - `description_sale` - `description_ecommerce` Stop searching `default_code`, internal `description`, and raw `website_description`. opw-6391984 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#280720