Daily updates from Odoo
Saturday, August 1, 2026
21 changes
7 changes
Resolved issues and error corrections
Ecuadorian invoice printouts now include the company logo in the header again. The header layout was slightly adjusted so the logo fits properly within the existing printed invoice format.
Original PR description
### Issue: In 19.3, the EC invoice header completely replaces the standard header in `report_invoice_document` after commit `08d17cc49c` The company logo was not included in the custom header, leaving invoices without a logo ### Cause: The logo was simply missing from the header template ### Fix: The logo is added and some header elements are resized (`h5` → `h6`, reduced margin) to keep the layout within the existing paper format without requiring a new one ### Steps to reproduce: - Install `l10n_ec_edi` with demo data - Open and print any invoice Before the fix, the company logo is missing from the header opw-6377830 Forward-Port-Of: odoo/enterprise#125469
Audit reports now use the company selected for the report instead of defaulting to the user's main company. This prevents the wrong company address from appearing in accounting report headers when generating audit reports for another company.
Original PR description
When adding the accounting reports to the audit report, we browse the reports with the request's environment which is defaulting to the user's main company. As a result, the company's address displayed in the reports' header is not correct if we generate the audit report for any other company with a different address. https://github.com/odoo/enterprise/blob/aaab137897e6ad794247470e48d5ea91382577a3/account_reports/data/pdf_export_templates.xml#L85 We propose to inject the correct company in the report's environment. opw-6373956 Forward-Port-Of: odoo/enterprise#125125
The AutoComplete component wraps a text input that already renders its own suggestion dropdown, so the browser's native suggestions must stay out of the way. In 12/2024 in this commit [1] the input's autocomplete was switched from `off` to `new-password` on the premise that `off` is not respected by browsers. In 02/2025, in this commit [2] then made it the component default so many2x pickers stay clean. Chrome runs two independent suggestion mechanisms, and each attribute silences only
Original PR description
The AutoComplete component wraps a text input that already renders its own suggestion dropdown, so the browser's native suggestions must stay out of the way. In 12/2024 in this commit [1] the input's…
The AutoComplete component wraps a text input that already renders its own suggestion dropdown, so the browser's native suggestions must stay out of the way. In 12/2024 in this commit [1] the input's autocomplete was switched from `off` to `new-password` on the premise that `off` is not respected by browsers. In 02/2025, in this commit [2] then made it the component default so many2x pickers stay clean. Chrome runs two independent suggestion mechanisms, and each attribute silences only one of them: - `off` is ignored when the input has a name and Chrome holds autofill (address) data for it. - `new-password` is ignored when Chrome offers "frequently used values", i.e. the form-history dropdown. [3] So `new-password` does not always work. It only stays hidden while the field is ineligible for those suggestions. A field becomes eligible as soon as it gains an `id` and an associated `<label>`. On `saas-19.3` this is provable on commit [4] where adding a prefix icon gave the link popover URL input an `id` + `<label for>`, and the native dropdown resurfaced over the custom URL/page suggestions. This branch targets `saas-18.4`, where the regression is NOT reproducible because that URL input has no `id`/`label` yet. The fix is applied here anyway to avoid the gap that any later `label`/`id` addition re-exposes (as commit [4] proved), and the fix can be forward ported to `saas-19.3`. The website editor's URL field implements autocomplete without the `AutoComplete` component, so the default does not reach it. so `autocomplete="off"` is set directly on that input. [1]: https://github.com/odoo/odoo/commit/9c0f5612 [2]: https://github.com/odoo/odoo/commit/2980694b (opw-4551051) [3]: https://issues.chromium.org/issues/41163264#comment30 [4]: https://github.com/odoo/odoo/commit/2b4d04d1 (task-6034288) task-6370552 Forward-Port-Of: odoo/odoo#279560 Forward-Port-Of: odoo/odoo#277501
The discuss action's breadcrumb name is set asynchronously: a useEffect on the current thread's displayName calls setDisplayName after the OWL render. The tour clicked "Starred messages" then immediately clicked "View or join channels" (a sidebar category action that is always present, so there was no implicit wait). Under runbot load the starred render and its effect lagged, so the action was restored with the stale "Inbox" breadcrumb name and the ".breadcrumb-item:contains('Starred messages')"
Original PR description
The discuss action's breadcrumb name is set asynchronously: a useEffect on the current thread's displayName calls setDisplayName after the OWL render. The tour clicked "Starred messages" then immediately clicked "View or join channels" (a sidebar category action that is always present, so there was no implicit wait). Under runbot load the starred render and its effect lagged, so the action was restored with the stale "Inbox" breadcrumb name and the ".breadcrumb-item:contains('Starred messages')" step timed out.
This is a test-timing artifact: a real user always sees the starred view render before navigating away, so the breadcrumb is correct for them.
Wait for the starred thread to be displayed before opening the channels list, and assert the channels view opened via its "Public Channels" breadcrumb. Also use :text instead of :contains for the text selectors.
https://runbot.odoo.com/odoo/error/242893
Forward-Port-Of: odoo/odoo#279578
Forward-Port-Of: odoo/odoo#278909Steps to reproduce: - Enable the ZUGFeRD (or Factur-X) e-invoicing format on a German customer. - Create a sale order for that customer, confirm it, create an invoice with a down payment. - Confirm and send the invoice to generate the PDF/XML. - Validate the XML (e.g. on portinvoice.com): it is rejected because the invoice line is missing the mandatory ram:Name field, only ram:Description is present. Cause of the issue: a down payment invoice line created from a sale order no l
Original PR description
Steps to reproduce: - Enable the ZUGFeRD (or Factur-X) e-invoicing format on a German customer. - Create a sale order for that customer, confirm it, create an invoice with a down payment. - Confirm and send the invoice to generate the PDF/XML. - Validate the XML (e.g. on portinvoice.com): it is rejected because the invoice line is missing the mandatory ram:Name field, only ram:Description is present. Cause of the issue: a down payment invoice line created from a sale order no longer carries a product_id: it only has a free-text. The Factur-X/CII export template rendered ram:Name directly from line.product_id.name with no fallback. For a line without a product, this produced an empty ram:Name element, which cleanup_xml_node then stripped entirely from the XML, leaving only ram:Description. Solution: Fall back to the line's name when there is no product opw-6391121 Forward-Port-Of: odoo/odoo#277418
Issue: When clicking "Send & Print" on an Ecuadorian invoice and sending the email with both the PDF and XML attachments visible in the wizard, only the PDF attachment is sent Steps to reproduce: 1. Install l10n_ec_edi and enter EC Company 2. Create and post an invoice 3. Click "Send & Print" on the invoice 4. Notice that both the XML and PDF attachments show up on the wizard, but when clicking "Send", only the PDF attachment is attached to the email that gets sent out Cause: Before
Original PR description
Issue: When clicking "Send & Print" on an Ecuadorian invoice and sending the email with both the PDF and XML attachments visible in the wizard, only the PDF attachment is sent Steps to reproduce: 1.…
Issue: When clicking "Send & Print" on an Ecuadorian invoice and sending the email with both the PDF and XML attachments visible in the wizard, only the PDF attachment is sent Steps to reproduce: 1. Install l10n_ec_edi and enter EC Company 2. Create and post an invoice 3. Click "Send & Print" on the invoice 4. Notice that both the XML and PDF attachments show up on the wizard, but when clicking "Send", only the PDF attachment is attached to the email that gets sent out Cause: Before the "Send & Print" wizard opens, the XML is already created. When opening the "Send & Print" wizard, the XML is added to the wizard with a "skip: True" flag. This is used for the wizard dropdown to add already existing attachments on the invoice. When the attachment is not selected, it makes sense to not be sent. However, when the "Send & Print" wizard opens, the attachment is added by default and the attachments in the dropdown does not consider the attachments already attached to the wizard at the start. The duplicated attachment in the dropdown has the "skip: True" flag still so it will wrongly signal later on that the attachment should not need to be sent Solution: When loading invoice attachments into the wizard, skip any attachment that is already present in the wizard's attachment list, so that default send attachments are not accidentally duplicated with the skip flag opw-6351635 Forward-Port-Of: odoo/odoo#278985
When a PoS runs in a currency other than the company currency, product prices are loaded already converted to the PoS currency (`list_price`, `lst_price`, `standard_price` all go through `_convert_pos_data_currency`). The prices carried by combos were not: `product.combo.base_price` is computed in the combo currency (the company currency) and `product.combo.item.extra_price` is stored in the product currency, but neither was converted when loaded in the PoS. As a result, a product priced at 2
Original PR description
When a PoS runs in a currency other than the company currency, product prices are loaded already converted to the PoS currency (`list_price`, `lst_price`, `standard_price` all go through…
When a PoS runs in a currency other than the company currency, product prices are loaded already converted to the PoS currency (`list_price`, `lst_price`, `standard_price` all go through `_convert_pos_data_currency`). The prices carried by combos were not: `product.combo.base_price` is computed in the combo currency (the company currency) and `product.combo.item.extra_price` is stored in the product currency, but neither was converted when loaded in the PoS. As a result, a product priced at 2 USD (= 80 ZIG) was correctly shown as 80 ZIG on its own, yet appeared as 2 ZIG once it was part of a combo, since the raw amount was displayed as-is in the PoS currency. Convert `base_price` and `extra_price` from each record's own `currency_id` to the PoS currency at load time, mirroring what is already done for product prices. Steps to reproduce: - Set a product to 2 USD and a PoS to a ZIG pricelist (rate 40). - Open the PoS: the standalone product shows 80 ZIG. - Add the same product as a combo item: it shows 2 ZIG instead of 80 ZIG. opw-6410243 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#279253 Forward-Port-Of: odoo/odoo#278330
3 changes
Resolved issues and error corrections
Users can now change the company on asset depreciation models even when working with only one company. This fixes a case where the depreciation journal could become impossible to update because the company field was hidden and the visible journal placeholder was read-only.
Original PR description
When no company is set on a depreciation model, we only display the `journal_placeholder_id` field which is readonly. But in a single company environment, the 'company_id` field is hidden, therefore it becames impossible to change the journal for depreciation models. Fix: Always display the `company_id` field, but we remove the warning in the onchange when we are in a single company environment. opw-6299390
Needed by linked PR. task-id: 6438820 FW of this PR: https://github.com/odoo/odoo/pull/279778 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Original PR description
Needed by linked PR. task-id: 6438820 FW of this PR: https://github.com/odoo/odoo/pull/279778 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
When a PoS runs in a currency other than the company currency, product prices are loaded already converted to the PoS currency (`list_price`, `lst_price`, `standard_price` all go through `_convert_pos_data_currency`). The prices carried by combos were not: `product.combo.base_price` is computed in the combo currency (the company currency) and `product.combo.item.extra_price` is stored in the product currency, but neither was converted when loaded in the PoS. As a result, a product priced at 2
Original PR description
When a PoS runs in a currency other than the company currency, product prices are loaded already converted to the PoS currency (`list_price`, `lst_price`, `standard_price` all go through…
When a PoS runs in a currency other than the company currency, product prices are loaded already converted to the PoS currency (`list_price`, `lst_price`, `standard_price` all go through `_convert_pos_data_currency`). The prices carried by combos were not: `product.combo.base_price` is computed in the combo currency (the company currency) and `product.combo.item.extra_price` is stored in the product currency, but neither was converted when loaded in the PoS. As a result, a product priced at 2 USD (= 80 ZIG) was correctly shown as 80 ZIG on its own, yet appeared as 2 ZIG once it was part of a combo, since the raw amount was displayed as-is in the PoS currency. Convert `base_price` and `extra_price` from each record's own `currency_id` to the PoS currency at load time, mirroring what is already done for product prices. Steps to reproduce: - Set a product to 2 USD and a PoS to a ZIG pricelist (rate 40). - Open the PoS: the standalone product shows 80 ZIG. - Add the same product as a combo item: it shows 2 ZIG instead of 80 ZIG. opw-6410243 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#279253 Forward-Port-Of: odoo/odoo#278330
1 change
Enhancements to existing features
Steps to reproduce: 1. Create a sales order. 2. Confirm or cancel the order. 3. Share the quotation link. 4. Open the quotation from an incognito window or the customer portal. Issue: - A 'Quotation Viewed by Customer' notification is sent even though the document is no longer an active quotation. Fix: - Only send the notification while the order is in quotation or quotation sent state. opw-6419364 Forward-Port-Of: odoo/odoo#278633
Original PR description
Steps to reproduce: 1. Create a sales order. 2. Confirm or cancel the order. 3. Share the quotation link. 4. Open the quotation from an incognito window or the customer portal. Issue: - A 'Quotation Viewed by Customer' notification is sent even though the document is no longer an active quotation. Fix: - Only send the notification while the order is in quotation or quotation sent state. opw-6419364 Forward-Port-Of: odoo/odoo#278633
4 changes
Resolved issues and error corrections
The AI call debrief timeline now correctly accepts transcript line data after a framework update changed how screen data is defined. This prevents missing transcript details in call summaries and keeps the AI-assisted debrief view working as intended.
Original PR description
Prior to this commit, the CallDebriefTimeline component in mail defined its props schema inside setup() using OWL 3's props() hook. However, the AI override in enterprise still used the legacy OWL 2 static class property format to extend the schema with the 'transcriptLines' prop. Because of that new prop was simply skipped. This commit refactors the CallDebriefTimeline in odoo to export its props schema as 'callDebriefTimelineProps'. The AI patch in enterprise now imports and expands it. task-6376518 **community counter part https://github.com/odoo/odoo/pull/275355**
The timesheet grid now safely handles away-time entries when no unmatched activity group is available. This prevents an error from interrupting users while reviewing or processing timesheet assistant events.
Original PR description
Before this commit, when the unmatched group is not found in events before processing afk event, a traceback occurs saying `Cannot read properties of undefined (reading 'Away (afk status 1)')` This commit moves the code checking the group key exists in `this.state.grouped` after processing afk event and before adding the afk event in unmatched group. Forward-Port-Of: odoo/enterprise#124251 Forward-Port-Of: odoo/enterprise#123452
This change removes a previous fix that was only relevant to an older Odoo version and should not have been carried forward. It helps avoid unexpected errors when users use quick create during bank reconciliation in the Accounting app.
Original PR description
This commit https://github.com/odoo/enterprise/commit/e559d9f5acbd176792db0dedc4e1f0cad7271457 fixed a problem only happening in 19.0. The commit shouldn't have been forward ported. no task id Forward-Port-Of: odoo/enterprise#126039
Audit reports now use the company selected for the report instead of defaulting to the user's main company. This ensures the correct company address appears in accounting report headers when generating audit reports for multiple companies.
Original PR description
When adding the accounting reports to the audit report, we browse the reports with the request's environment which is defaulting to the user's main company. As a result, the company's address displayed in the reports' header is not correct if we generate the audit report for any other company with a different address. https://github.com/odoo/enterprise/blob/aaab137897e6ad794247470e48d5ea91382577a3/account_reports/data/pdf_export_templates.xml#L85 We propose to inject the correct company in the report's environment. opw-6373956 Forward-Port-Of: odoo/enterprise#125125
1 change
Resolved issues and error corrections
Basic users can now open the spreadsheet creation dialog in Documents even when they do not have access to spreadsheet templates. This removes an inconsistent limitation and lets them create empty spreadsheets from the kanban view like other document types.
Original PR description
A basic user can access the document app and create all types of documents from the kanban view except for the spreadsheets because it requires an access to the templates. While the user cannot interact with the templates, they should have the possibility to create an empty spreadsheet. Note that it can already be done coming from the view of a spreadsheet! This revision ensures that the user can indeed access the spreadsheet creation modal even if they don't have access to the spreadsheet templates. Task-6364964 Forward-Port-Of: odoo/enterprise#126231 Forward-Port-Of: odoo/enterprise#123003
5 changes
Resolved issues and error corrections
By default event notifications are configured with positive integers to state how many minutes/hours/days they should be triggered before an event starts. This works fine in within Odoo. But in an ICS file a TRIGGER with such positive integer means it starts after the event. For example ICS file generated by Odoo contains TRIGGER;related=START:PT15M but it should be negative: TRIGGER;related=START:-PT15M (note the minus) in order to trigger before the event. See [here](https://icalendar.org/iCal
Original PR description
By default event notifications are configured with positive integers to state how many minutes/hours/days they should be triggered before an event starts. This works fine in within Odoo. But in an ICS file a TRIGGER with such positive integer means it starts after the event. For example ICS file generated by Odoo contains TRIGGER;related=START:PT15M but it should be negative: TRIGGER;related=START:-PT15M (note the minus) in order to trigger before the event. See [here](https://icalendar.org/iCalendar-RFC-5545/3-8-6-3-trigger.html) for reference. Current behavior before PR: The reminder is triggered AFTER the event start Desired behavior after PR is merged: The reminder is triggered BEFORE the event start Closes #245052. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
- Added the BolloVirtuale in the Simplified invoice template - Now it's possible to force the Simplified format on exported invoice when the `l10n_it_document_type` is set to a simplified one - Factored the Italian partner recognition (_l10n_it_edi_is_italian) - Added a check on the invoice, no simplified format for non-domestic / PA partners Task [link](https://www.odoo.com/odoo/project.task/6226436) task-6226436
Original PR description
- Added the BolloVirtuale in the Simplified invoice template - Now it's possible to force the Simplified format on exported invoice when the `l10n_it_document_type` is set to a simplified one - Factored the Italian partner recognition (_l10n_it_edi_is_italian) - Added a check on the invoice, no simplified format for non-domestic / PA partners Task [link](https://www.odoo.com/odoo/project.task/6226436) task-6226436
The AEAT provides different endpoints depending on the type of digital certificate you use. A personal certificate or a seal certificate. The module used always the standard endpoint regardless of the certificate type. Causing authentication failures when a sello certificate was configured. This fix detects the certificate type by checking for the presence of a GIVEN_NAME attribute. task-6169935 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-p
Original PR description
The AEAT provides different endpoints depending on the type of digital certificate you use. A personal certificate or a seal certificate. The module used always the standard endpoint regardless of the certificate type. Causing authentication failures when a sello certificate was configured. This fix detects the certificate type by checking for the presence of a GIVEN_NAME attribute. task-6169935 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#271080
Many users were receiving duplicate vendor bills. The issue was that duplicates were never detected in the receiving flow. Every incoming message returned by the proxy was processed and turned into a new `account.move`, even if it had already been imported previously. This commit filters out messages whose UUID already matches an existing `account.move` before processing them, and acknowledges those duplicates on the IAP side so they are not received again on the next run. task-5930116
Original PR description
Many users were receiving duplicate vendor bills. The issue was that duplicates were never detected in the receiving flow. Every incoming message returned by the proxy was processed and turned into a new `account.move`, even if it had already been imported previously. This commit filters out messages whose UUID already matches an existing `account.move` before processing them, and acknowledges those duplicates on the IAP side so they are not received again on the next run. task-5930116 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#274963
Description of the issue/feature this PR addresses: Fixes #279931. `initElementForEdition()` ([`html_editor/static/src/utils/sanitize.js`](https://github.com/odoo/odoo/blob/18.0/addons/html_editor/static/src/utils/sanitize.js#L20-L31)) removes the `width`/`height` attributes of every `<img>` in the editable and replaces them with an inline pixel style. Its comment says *"The attributes will be re-applied on save"*, and for the pipeline it was written for that is true: `convert_inline` re-adds
Original PR description
Description of the issue/feature this PR addresses: Fixes #279931. `initElementForEdition()`…
Description of the issue/feature this PR addresses: Fixes #279931. `initElementForEdition()` ([`html_editor/static/src/utils/sanitize.js`](https://github.com/odoo/odoo/blob/18.0/addons/html_editor/static/src/utils/sanitize.js#L20-L31)) removes the `width`/`height` attributes of every `<img>` in the editable and replaces them with an inline pixel style. Its comment says *"The attributes will be re-applied on save"*, and for the pipeline it was written for that is true: `convert_inline` re-adds `width` from `style.width` when it inlines a body for email. But `initElementForEdition()` is called unconditionally from [`editor.js`](https://github.com/odoo/odoo/blob/18.0/addons/html_editor/static/src/editor.js#L109), on every editor start, for every editable — website pages, blog posts, any `html` field on `html_editor`. Outside the mail path nothing re-applies the attributes. This was added by #213786 (`opw-4863515`, forward-ported as #216958 / #216986 / #217002 / #217017 / #217023) to fix a real problem in the *email template* editor, where `convert_inline` had added `width`/`height` for email-client compatibility and those attributes then prevented resizing an image back to its default. That fix is right for that path. This PR only narrows where it applies. Current behavior before PR: Open any editable containing an image with intrinsic dimensions, type one character, save. The stored markup is permanently rewritten: ``` before <img src="…" alt="x" width="960" height="540" loading="lazy"> after <img src="…" alt="x" loading="lazy" style="width: 960px; height: 540px;"> ``` There is no way back — on the next edit `img[width]` no longer matches, so the inline style stays. It is not cosmetic. Intrinsic `width`/`height` is how a browser reserves the box before an image loads, and an inline `width` beats the stylesheet rule that keeps the image responsive. Measured at a 375px viewport with a 960×540 image in a 319px column, after one keystroke and a save: * the image renders 960×540 — **641px of overflow**, and the document's `scrollWidth` goes from 375 to 1153, so the page scrolls sideways; * the derived `aspect-ratio` becomes `auto`, so a `loading="lazy"` image below the fold lays out at **zero height** until it decodes — the CLS the attributes exist to prevent; * where a stylesheet sets an explicit `aspect-ratio`, an explicit `width` **and** `height` together decide the used size, so the declared ratio goes inert and the crop is lost. Desired behavior after PR is merged: The rewrite becomes opt-in through a `removeForcedImageDimensions` config flag — following the existing `allowInlineAtRoot` precedent, which is threaded the same way — and is set in `HtmlMailField.getConfig()`, the field whose `getEditorContent()` runs `toInline()`. That is the one path that puts the attributes back, and `HtmlComposerMessageField` inherits it. Every other editable keeps the author's markup. Behaviour in the email-template editor, which `opw-4863515` was about, is unchanged. Adds `html_editor/static/tests/utils/sanitize.test.js` covering both directions: with the flag the attributes still move into an inline style; without it they are left alone; an image with no dimensions is untouched either way. Targeting **18.0** as the oldest affected branch — #213786 targeted 18.0 and the block is byte-identical on `18.0`, `saas-18.4`, `19.0`, `saas-19.1` and `master`. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr