Daily updates from Odoo
Wednesday, July 22, 2026
22 changes · 18.0
Enhancements to existing features
When the customer is located in Canary Islands, Ceuta or Melilla, the invoice falls under a different tax territory and the ClaveRegimenEspecialOTrascendencia should be 08. Previously this case was not checked and invoices were reported with the generic refime code. task-6372837 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Original PR description
When the customer is located in Canary Islands, Ceuta or Melilla, the invoice falls under a different tax territory and the ClaveRegimenEspecialOTrascendencia should be 08. Previously this case was not checked and invoices were reported with the generic refime code. task-6372837 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Resolved issues and error corrections
This fixes an error that could stop customer payment follow-up reports from being sent in databases that do not use the optional no-follow-up feature. The system now only applies that filtering when the related feature is available, improving reliability for accounting teams.
Original PR description
https://github.com/odoo/enterprise/commit/65008de60589fbda924041e35bb34e33d84eb13d introduced a filter based on the `no_followup` field that is not present in every databases, since it was introduced in stable alongside with the `account_no_followup` module. This lead to an AttributeError when trying to send the followup report. This commit adds helpers to be able to use this field only in account_no_followup opw-6310602
Uruguay electronic export invoices now handle full global discounts correctly, avoiding submission errors when the export total is zero. Discount lines with quantities other than one are also calculated accurately, improving invoice totals and compliance reporting.
Original PR description
* if 100% global discount will have an error because in Totales XML section because MntExpoyAsim is missing. We add the option that this one can be added even if it is 0. * If user use quantity different that 1 in the discount line we are wrongly computing the total of the discount. now we always multiply price unit with cuantity
Deleting product documents now also removes related background email aliases that were previously left behind. This prevents errors when users later create new aliases and keeps document-related records clean.
Original PR description
Steps to reproduce: 1. Install documents and sales 2. Check product document centralization from settings, and no alias should be set 3. Now go to setting>techinical>emial>aliases>remove default…
Steps to reproduce: 1. Install documents and sales 2. Check product document centralization from settings, and no alias should be set 3. Now go to setting>techinical>emial>aliases>remove default filter and check total count 4. Go to products and add a document from the smart button 5. Now again check the aliases total count (1 increased) 6. Delete the document on the product. 7. Alias is not deleted 8. Try to add an alias from the settings Issue: - When `documents_product` is installed and product document centralization is enabled, deleting a `product.document` can leave an orphan `mail.alias` resulting in an error while creating a new alias. Cause: - A product document owns an `ir.attachment`, and that attachment is mirrored as a `documents.document` for `product.product` / `product.template`. In 18.0, `documents.document` inherits `mail.alias.mixin`, so the mirrored document also owns a `mail.alias`. - Deleting `product.document` deletes its `ir.attachment`. The linked `documents.document` is then removed by SQL `ondelete='cascade'` on `attachment_id`, not through ORM `unlink()`. Because the document unlink logic does not run, the alias cleanup from the mail alias mixin is skipped. Why not reproducible in 19.0: - In 19.0, `documents.document` uses `mail.alias.mixin.optional` instead of `mail.alias.mixin`. Binary mirrored documents no longer create a `mail.alias` unless an `alias_name` is explicitly set, so product mirrored documents do not create aliases in the first place. Solution: - Override `ir.attachment.unlink()` in `documents`. before deleting attachment, collect linked document aliases then delete attachment. SQL cascade deletes linked documents.document rows and now we delete collected aliases. opw-6019294
This fixes an issue where accounting reports could fail to recognize that no report section had been opened yet. The change helps the report interface behave correctly when deciding whether saved section state is empty.
Original PR description
**Root Cause:**
At [1], the condition `this.lastOpenedSectionByReport === {}` always
return `false` because JavaScript compares objects by reference
rather than by value. As a result, the code never detects when
`lastOpenedSectionByReport` is empty.
**Fix:**
This commit ensures the code correctly detects an empty
`lastOpenedSectionByReport` object.
[1]:
https://github.com/odoo/enterprise/blob/ae4b461edb1d6b49c25d4e264380e7ae4b67f10c/account_reports/static/src/components/account_report/controller.js#L50
**No task ID**Document actions in Documents - Accounting now preserve open to-do activities instead of marking them as done automatically. This prevents accidental loss of activity tracking when users create invoices or run similar actions from a document.
Original PR description
Problem: Performing a server action on a document automatically marks all activities as done. Steps to reproduce: - Install 'Documents - Accounting'. - Select a document. - Add a To-do activity to that document. - Perform any action, such as 'Create Customer Invoice'. - The activity is automatically marked as done. Solution: Server actions were triggering `account_create_account_move` without the `skip_activities` parameter. This has been fixed by passing `skip_activities=True`, ensuring activities are no longer marked as done automatically. Task-5075307
This fix makes the automated barcode picking test wait until the transfer is actually valid before trying to validate it. It reduces random test failures, helping keep inventory-related releases and updates more dependable.
Original PR description
Make sure the validate button has the 'primary-btn' class as it means that the transfer is valid before clicking on it. runbot-939917
The barcode app now correctly keeps only one delivery line selected when switching between packaged and unpackaged products. This prevents confusion during warehouse picking operations where mixed package types are handled in the same delivery.
Original PR description
**Steps to reproduce:** - Enable "Move Entire Packages" setting on deliveries - Make a product A, that has a package P1, on hand qty of 1 - Make product B that don't have a package, but on hand qty…
**Steps to reproduce:** - Enable "Move Entire Packages" setting on deliveries - Make a product A, that has a package P1, on hand qty of 1 - Make product B that don't have a package, but on hand qty of 1 - Make a delivery that has both of those products, requested qty of 1 for both - Mark it as todo - Go to the barcode app, select the delivery - Select the line with product B - Select the line with product A --> The line with product B is not unselected **Why the fix:** When we have a mix of packaged products and products without a package on the same operation, they are handled separately. The products without a package are handled in https://github.com/odoo/enterprise/blob/98c79af3fb6cb354f46fd2f58e642a72a9271443/stock_barcode/static/src/models/barcode_model.js#L388-L392 that calls https://github.com/odoo/enterprise/blob/98c79af3fb6cb354f46fd2f58e642a72a9271443/stock_barcode/static/src/models/barcode_model.js#L1277-L1284 But as you can see, there are no mention of the selected package line, which is stored in **this.lastScanned.packageId**. As we do not touch this variable, the selected package line stays selected. The same is true for the other way around, when we select a package line we call https://github.com/odoo/enterprise/blob/98c79af3fb6cb354f46fd2f58e642a72a9271443/stock_barcode/static/src/models/barcode_model.js#L394-L398 This function does not care for the **selectedLineVirtualId** which represents the selected line without a package. To avoid this and make it so that only one line is selected even if they have different package, we now set the corresponding value to false to unselect the other line in all situation. This is basically how it's done in https://github.com/odoo/enterprise/blob/98c79af3fb6cb354f46fd2f58e642a72a9271443/stock_barcode/static/src/models/barcode_model.js#L1202-L1208 to unselect every line regardless of packages. opw-6266203 Forward-Port-Of: odoo/enterprise#122038
Fixes a navigation issue where opening Helpdesk tickets from an email alias could cause an error instead of showing the ticket list. The change helps users reach the expected Helpdesk view reliably, especially when using alias-related shortcuts in debug workflows.
Original PR description
### Steps to Reproduce: 1. In Debug mode, go to Aliases 2. Click on any active Alias, ex. customer-care 3. Click on "Open Parent Document" smart button 4. Click on "Tickets" smart button and observe…
### Steps to Reproduce: 1. In Debug mode, go to Aliases 2. Click on any active Alias, ex. customer-care 3. Click on "Open Parent Document" smart button 4. Click on "Tickets" smart button and observe error ### Description of the issue/feature this PR addresses: **Issue:** When navigating from an email alias to its parent document (e.g., a Helpdesk Team), the web client keeps the `active_id` and `active_model` of the alias in the context. The "Tickets" smart button action maps this incorrect `active_id` to `default_team_id`. **Solution:** Update `get_empty_list_help` in `helpdesk.ticket` to validate the context. We can check if the `active_model` is actually `helpdesk.team`. If it's not, we can safely ignore the invalid `default_team_id`. ### Current behavior before PR: The system blindly trusts the polluted `default_team_id` and attempts to look up a Helpdesk Team using the Alias's ID to generate the empty list help message. Because a team with that ID does not exist, it throws a MissingError. ### Desired behavior after PR: The system should be able to detect when there is incorrect context and clear the invalid ID before attempting the database lookup. Therefore, the empty tickets view will load correctly without crashing. opw-6395638
**Steps to reproduce:** * Install **l10n_fr_pdp** module. * Create two companies: one French (with PDP activated) and one in another country (e.g. Belgium). * Create a customer invoice in the **non-French company** for a **French customer**. * Open **Send & Print** and try to send via **email**. **Observed behavior:** * Sending fails with: `Errors occurred while creating the EDI document (format: France UBL 2.1 E-Invoicing Format):` `- The following partner's SIREN or SIRET is missing: <
Original PR description
**Steps to reproduce:** * Install **l10n_fr_pdp** module. * Create two companies: one French (with PDP activated) and one in another country (e.g. Belgium). * Create a customer invoice in the…
**Steps to reproduce:** * Install **l10n_fr_pdp** module. * Create two companies: one French (with PDP activated) and one in another country (e.g. Belgium). * Create a customer invoice in the **non-French company** for a **French customer**. * Open **Send & Print** and try to send via **email**. **Observed behavior:** * Sending fails with: `Errors occurred while creating the EDI document (format: France UBL 2.1 E-Invoicing Format):` `- The following partner's SIREN or SIRET is missing: <BE company name>` `- The following partner's PDP identifier is missing: <BE company name>` **Cause:** * `_get_suggested_invoice_edi_format()` on `res.partner` returned `'ubl_21_fr'` for any French B2B partner regardless of which company was sending the invoice. * This caused `ubl_21_fr` to be stored as the partner's `invoice_edi_format` and selected at send time, even when the sending company has no PDP registration. * The `ubl_21_fr` XML builder then validates that **both** supplier and customer have French PDP credentials (EAS 0225, SIREN/SIRET), which the non-French company cannot satisfy. **Fix:** * In `_get_suggested_invoice_edi_format()`, add a guard on `self.env.company._get_peppol_proxy_type() == 'pdp'` so that `'ubl_21_fr'` is only suggested when the active company is a PDP-registered French company. **Note:** * No test added — reproducing this bug requires two localization modules to be installed simultaneously (e.g. `l10n_fr_pdp` + `l10n_be`), which is not supported in the standard test framework. opw-6392253
Note: In odoo all date/datetime fields are stored and computed by default as UTC Before this commit, dates were called using local timezone getters. This caused the time returned from web to be shifted by the timezone as the dates returned would be treated as UTC. After this commit, dates are now called using UTC timzone getters. Now all web times are retrived as UTC and in sync with the rest of the odoo fields and computations. task-6271421 Forward-Port-Of: odoo/odoo#265250
Original PR description
Note: In odoo all date/datetime fields are stored and computed by default as UTC Before this commit, dates were called using local timezone getters. This caused the time returned from web to be shifted by the timezone as the dates returned would be treated as UTC. After this commit, dates are now called using UTC timzone getters. Now all web times are retrived as UTC and in sync with the rest of the odoo fields and computations. task-6271421 Forward-Port-Of: odoo/odoo#265250
**Steps to produce:** - Install the `sale_stock` and `sale_management` modules. - Create a product with the Invoicing Policy set to `Delivered quantities`. - Create a Sales Order for 5 units of the product, confirm it, and validate the delivery. - Create and post the customer invoice for the 5 units (SO status is now Fully Invoiced). - Return 3 units from the validated delivery, click on the `Return for Exchange` option, and validate the transfer. - Observe the Sales Order's invoice status
Original PR description
**Steps to produce:** - Install the `sale_stock` and `sale_management` modules. - Create a product with the Invoicing Policy set to `Delivered quantities`. - Create a Sales Order for 5 units of the…
**Steps to produce:** - Install the `sale_stock` and `sale_management` modules. - Create a product with the Invoicing Policy set to `Delivered quantities`. - Create a Sales Order for 5 units of the product, confirm it, and validate the delivery. - Create and post the customer invoice for the 5 units (SO status is now Fully Invoiced). - Return 3 units from the validated delivery, click on the `Return for Exchange` option, and validate the transfer. - Observe the Sales Order's invoice status from the list view. **Issue:** - The Sales Order status erroneously switches to `To Invoice` instead of remaining `Fully Invoiced`. **Root cause:** - When a return picking is validated with return exchange, the `qty_delivered` on the `sale.order.line` drops immediately. This causes `qty_to_invoice` (`qty_delivered - qty_invoiced`) to become negative from [1]. - And then from [2], the invoice status is set as `To invoice`. **Solution:** - Adjust the existing `_compute_invoice_status` override in `sale_stock` to account for pending replacement moves generated during exchange returns. If the replacement quantity offsets the negative `qty_to_invoice`, keep the order `Fully Invoiced` instead of marking it `To Invoice`. [1]https://github.com/odoo/odoo/blob/b0fc5668990c42f129432dd7eeeb24a042d4b153/addons/sale/models/sale_order_line.py#L1006 [2]https://github.com/odoo/odoo/blob/b0fc5668990c42f129432dd7eeeb24a042d4b153/addons/sale/models/sale_order_line.py#L1041 **opw-6299909** --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Before this commit, the journal and the memo of a payment linked to a company-paid expense report could be modified although such payments must be kept consistent with their expense report: a missing comma in the set of protected fields merged 'journal_id' and 'ref' into a single meaningless entry. The memo was also left editable because the set still referred to 'ref', which was renamed to 'memo'. Steps to reproduce: - submit, approve and post an expense paid by company - open the payment
Original PR description
Before this commit, the journal and the memo of a payment linked to a company-paid expense report could be modified although such payments must be kept consistent with their expense report: a missing comma in the set of protected fields merged 'journal_id' and 'ref' into a single meaningless entry. The memo was also left editable because the set still referred to 'ref', which was renamed to 'memo'. Steps to reproduce: - submit, approve and post an expense paid by company - open the payment created for the expense report - edit the memo or the journal and save, then try to edit the date Editing the date is refused with "You cannot do this modification since the payment is linked to an expense report", while the memo and journal changes are silently accepted. Solution: Restore the missing comma and protect the renamed memo field. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Clicking the translate button saves the form's root record before opening the translation dialog, since https://github.com/odoo/odoo/commit/9da52919a03dbcee5209430918195158c0652099. A record opened in an x2many form dialog keeps its changes for itself until the dialog is saved, see https://github.com/odoo/odoo/blob/242f6d3cf7288853f163ac6986a3b7aa4279efaf/addons/web/static/src/model/relational_model/static_list.js#L193. Its pending changes are not part of the root record changes, so saving the
Original PR description
Clicking the translate button saves the form's root record before opening the translation dialog, since https://github.com/odoo/odoo/commit/9da52919a03dbcee5209430918195158c0652099. A record opened…
Clicking the translate button saves the form's root record before opening the translation dialog, since https://github.com/odoo/odoo/commit/9da52919a03dbcee5209430918195158c0652099. A record opened in an x2many form dialog keeps its changes for itself until the dialog is saved, see https://github.com/odoo/odoo/blob/242f6d3cf7288853f163ac6986a3b7aa4279efaf/addons/web/static/src/model/relational_model/static_list.js#L193. Its pending changes are not part of the root record changes, so saving the root sends nothing to the server, and the translation dialog then shows the stored terms instead of the current content, or no terms at all when the stored value is empty. The fix changes openTranslationDialog in translation_button.js, the place that decides which record to save. When the record keeps its changes for itself (record._noUpdateParent), the record is saved directly, like the button did before the commit above. The root record is still saved in the other cases, so the editable list case that commit fixed keeps working. Steps to reproduce: 1. Activate a second language in Settings > Translations > Languages 2. Open the Surveys app, open a survey and click a question in the Questions tab 3. In the Description tab, change the description 4. Click the EN button on the description field => the translation dialog shows the terms of the previous description, not the current one Ticket [link](https://www.odoo.com/odoo/project.task/6237291) opw-6237291
## Steps to Reproduce: _(cryptography version > 43.0.0)_ 1. Install the `l10n_sa_edi` module. 2. Switch to SA Company. 3. Set the company name to an Arabic string between 32 and 64 characters. (e.g; `مجموعة النخبة العالمية للاستشارات الفنية`) 5. Accounting > Configuration > Journals. 6. Open a Sales type journal. 7. Click "Re-onboard" in the ZATCA tab. 8. Enter an OTP and click "Request". ## Error: `ValueError: Attribute's length must be >= 1 and <= 64, but it was 98` ## Caus
Original PR description
## Steps to Reproduce: _(cryptography version > 43.0.0)_ 1. Install the `l10n_sa_edi` module. 2. Switch to SA Company. 3. Set the company name to an Arabic string between 32 and 64 characters. (e.g;…
## Steps to Reproduce: _(cryptography version > 43.0.0)_
1. Install the `l10n_sa_edi` module.
2. Switch to SA Company.
3. Set the company name to an Arabic string between 32 and 64 characters.
(e.g; `مجموعة النخبة العالمية للاستشارات الفنية`)
5. Accounting > Configuration > Journals.
6. Open a Sales type journal.
7. Click "Re-onboard" in the ZATCA tab.
8. Enter an OTP and click "Request".
## Error:
`ValueError: Attribute's length must be >= 1 and <= 64, but it was 98`
## Cause:
The CSR validation checks the length of characters, if combined common_name (or other fields) are less than 64 characters, it passes the condition. - [1] But the cryptography library validates UTF-8 byte length for string values. Arabic characters take 2 bytes in UTF-8, causing the byte length to exceed the 64-byte limit enforced by the cryptography.
**Note:**
Starting with cryptography version 43.0.0, the library enforces the UTF-8 byte length limit for CSR string values during certificate creation. (Ref: https://github.com/pyca/cryptography/pull/11201)
## Fix:
Validate the UTF-8 encoded byte length instead of the character length.
[1] - https://github.com/odoo/odoo/blob/a66fedcaf555660e484a2becc49a9b7e602f5924/addons/l10n_sa_edi/models/certificate.py#L92
sentry-7608376856Stripe recommends connecting to a reader returned by the most recent discovery call. However, the POS Stripe interface discovered readers as soon as the Stripe Terminal object was created, during POS loading. This means a POS reload performed long before the first payment could populate `pos.discoveredReaders` with stale reader objects. If the first Stripe Terminal payment happens much later, the SDK may try to connect using outdated reader/credential state and fail with an expired Connection
Original PR description
Stripe recommends connecting to a reader returned by the most recent discovery call. However, the POS Stripe interface discovered readers as soon as the Stripe Terminal object was created, during POS loading. This means a POS reload performed long before the first payment could populate `pos.discoveredReaders` with stale reader objects. If the first Stripe Terminal payment happens much later, the SDK may try to connect using outdated reader/credential state and fail with an expired ConnectionToken. Move reader discovery to `connectReader()` so Odoo connects using fresh discovery results, and stop discovering readers eagerly when creating the Stripe Terminal instance. opw-6311626 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Before this commit, decreasing the quantity of a move whose move lines are expressed in another unit of measure removed the wrong quantity from the lines, because the two conversions between the move unit and the line unit converted a value to its own unit, hence did nothing. Steps to reproduce: - create a product in Units with available stock - create a delivery for 2 Dozen of it and mark it as todo - in the detailed operations, change the unit of the move line to Units (24) - lower the
Original PR description
Before this commit, decreasing the quantity of a move whose move lines are expressed in another unit of measure removed the wrong quantity from the lines, because the two conversions between the move…
Before this commit, decreasing the quantity of a move whose move lines are expressed in another unit of measure removed the wrong quantity from the lines, because the two conversions between the move unit and the line unit converted a value to its own unit, hence did nothing. Steps to reproduce: - create a product in Units with available stock - create a delivery for 2 Dozen of it and mark it as todo - in the detailed operations, change the unit of the move line to Units (24) - lower the move quantity from 2 to 1 Dozen The move line ends up with 23 Units instead of 12: the decrease of 1 Dozen is applied as 1 Unit on the line and considered fully processed. The remaining 11 units stay reserved and counted on the transfer. Convert the remaining decrease from the move unit to the line unit when taking it from a line, and the taken quantity back to the move unit when updating the remaining decrease. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#276774
Steps to reproduce the bug: - Install l10n_ke_edi_oscu_stock - Run Test_sale_mrp_kit_bom_cogs Problem: ```self.assertAlmostEqual(stock_out_aml.credit, 1.53, msg="Should not include the value of consumable component") AssertionError: 3.07 != 1.53 within 7 places (1.5399999999999998 difference) : Should not include the value of consumable component ``` The test delivered 1 whole unit of every component of Kit A regardless of the fractional quantity actually needed to produce a single kit
Original PR description
Steps to reproduce the bug: - Install l10n_ke_edi_oscu_stock - Run Test_sale_mrp_kit_bom_cogs Problem: ```self.assertAlmostEqual(stock_out_aml.credit, 1.53, msg="Should not include the value of…
Steps to reproduce the bug: - Install l10n_ke_edi_oscu_stock - Run Test_sale_mrp_kit_bom_cogs Problem: ```self.assertAlmostEqual(stock_out_aml.credit, 1.53, msg="Should not include the value of consumable component") AssertionError: 3.07 != 1.53 within 7 places (1.5399999999999998 difference) : Should not include the value of consumable component ``` The test delivered 1 whole unit of every component of Kit A regardless of the fractional quantity actually needed to produce a single kit (0.34/0.14/0.2 units for Component A/B/BB respectively). This went unnoticed under the default invoice_policy 'order', since qty_delivered never drives the invoiced quantity in that case. l10n_ke_edi_oscu_stock forces invoice_policy to 'delivery' for storable products that have no explicit company_id, which is the case for the products created in this test. With invoice_policy 'delivery', _compute_kit_quantities() correctly reads the over-delivered components as enough stock to form 2 complete kits (min ratio 2.94, floored to 2) instead of 1, doubling the invoiced quantity and the resulting COGS (3.07 instead of 1.53). runbot-243633
Firefox has a strict limit of ~640,000 characters for history state serialization and throws NS_ERROR_ILLEGAL_VALUE past it. Chrome and Safari throw DataCloneError past their own undocumented limits (~500MB and ~64MB respectively). When a debounced push() exceeded these limits, the error was unhandled and broke navigation. Catch these two specific errors and log them instead of crashing, while still resetting the push state and re-throwing any other unexpected error. opw-6182687
Original PR description
Firefox has a strict limit of ~640,000 characters for history state serialization and throws NS_ERROR_ILLEGAL_VALUE past it. Chrome and Safari throw DataCloneError past their own undocumented limits (~500MB and ~64MB respectively). When a debounced push() exceeded these limits, the error was unhandled and broke navigation. Catch these two specific errors and log them instead of crashing, while still resetting the push state and re-throwing any other unexpected error. opw-6182687
### Steps to Reproduce: 1. In Debug mode, go to Aliases 2. Click on any active Alias, ex. customer-care 3. Click on "Open Parent Document" smart button 4. Click on "Tickets" smart button and observe error ### Description of the issue/feature this PR addresses: **Issue:** When navigating from an email alias to its parent document, the context incorrectly retains the `active_id` and `active_model` of the alias. This causes subsequent smart button actions on the parent document to evaluate
Original PR description
### Steps to Reproduce: 1. In Debug mode, go to Aliases 2. Click on any active Alias, ex. customer-care 3. Click on "Open Parent Document" smart button 4. Click on "Tickets" smart button and observe…
### Steps to Reproduce: 1. In Debug mode, go to Aliases 2. Click on any active Alias, ex. customer-care 3. Click on "Open Parent Document" smart button 4. Click on "Tickets" smart button and observe error ### Description of the issue/feature this PR addresses: **Issue:** When navigating from an email alias to its parent document, the context incorrectly retains the `active_id` and `active_model` of the alias. This causes subsequent smart button actions on the parent document to evaluate using the wrong ID. **Solution:** Update the context dictionary returned by the `action_open_parent_document` method. We set `active_id` and `active_model` to match the parent document in order to ensure that the web client drops the outdated alias data. ### Current behavior before PR: Clicking a smart button (ex. "Tickets") on the parent document evaluates the action using the old alias ID. Because that ID does not actually belong to the target model, the database search fails and causes a MissingError. ### Desired behavior after PR: The context will accurately update with the parent document's ID and model upon navigation. All subsequent smart button actions should receive the correct ID, allowing the views to load normally without crashing. opw-6395638 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
### Steps to Reproduce: 1. In Debug mode, go to Aliases 2. Click on any active Alias, ex. customer-care 3. Click on "Open Parent Document" smart button 4. Click on "Tickets" smart button and observe error ### Description of the issue/feature this PR addresses: **Issue:** When navigating from an email alias to its parent document, the context incorrectly retains the `active_id` and `active_model` of the alias. This causes subsequent smart button actions on the parent document to evaluate
Original PR description
### Steps to Reproduce: 1. In Debug mode, go to Aliases 2. Click on any active Alias, ex. customer-care 3. Click on "Open Parent Document" smart button 4. Click on "Tickets" smart button and observe…
### Steps to Reproduce: 1. In Debug mode, go to Aliases 2. Click on any active Alias, ex. customer-care 3. Click on "Open Parent Document" smart button 4. Click on "Tickets" smart button and observe error ### Description of the issue/feature this PR addresses: **Issue:** When navigating from an email alias to its parent document, the context incorrectly retains the `active_id` and `active_model` of the alias. This causes subsequent smart button actions on the parent document to evaluate using the wrong ID. **Solution:** Update the context dictionary returned by the `action_open_parent_document` method. We set `active_id` and `active_model` to match the parent document in order to ensure that the web client drops the outdated alias data. ### Current behavior before PR: Clicking a smart button (ex. "Tickets") on the parent document evaluates the action using the old alias ID. Because that ID does not actually belong to the target model, the database search fails and causes a MissingError. ### Desired behavior after PR: The context will accurately update with the parent document's ID and model upon navigation. All subsequent smart button actions should receive the correct ID, allowing the views to load normally without crashing. opw-6395638 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The character-by-character HTML assertion in mass mailing tests fails on modern platforms using libxml2 >= 2.14/2.15 due to upstream updates that align HTML serialization, attribute quote management, and escaping rules more closely with the HTML5 specification. See upstream changes: - https://gitlab.gnome.org/GNOME/libxml2/-/releases/v2.14.0 (Attribute escaping optimization) - https://gitlab.gnome.org/GNOME/libxml2/-/releases/v2.15.0 (HTML5 spec compliant serialization) This commit fixes
Original PR description
The character-by-character HTML assertion in mass mailing tests fails on modern platforms using libxml2 >= 2.14/2.15 due to upstream updates that align HTML serialization, attribute quote management, and escaping rules more closely with the HTML5 specification. See upstream changes: - https://gitlab.gnome.org/GNOME/libxml2/-/releases/v2.14.0 (Attribute escaping optimization) - https://gitlab.gnome.org/GNOME/libxml2/-/releases/v2.15.0 (HTML5 spec compliant serialization) This commit fixes this by refactoring the assertions to treat the output HTML structure as a "black box", verifying data integrity and expected content conversions rather than brittle structural layout. runbot-938228 Forward-Port-Of: odoo/odoo#275959