Friday, May 15, 2026
7 changes · saas-18.4
Resolved issues and error corrections
When users press Enter at the end of a styled heading, the new paragraph now starts clean instead of inheriting colors or other heading styles. This makes document editing more predictable and avoids unwanted formatting cleanup.
Original PR description
Problem: Pressing Enter at the end of a styled heading (e.g., with a color) creates a new paragraph that inherits the heading styles. This is no longer the expected behavior. The new paragraph should be empty and without inherited styles. Solution: When splitting a heading at its boundaries and creating a base container, fill it with a `br` instead of carrying over styles. Steps to reproduce: - Add a heading. - Apply a style (e.g., color). - Place the caret at the end of the heading. - Press Enter. - Observe that the new paragraph still has the heading color. task-6147897 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264369 Forward-Port-Of: odoo/odoo#262150
Fixed an issue where switching an event page into edit mode while a registration pop-up was open could crash the page. The pop-up is now cleaned up only after it fully closes, making event page editing more reliable.
Original PR description
Steps to reproduce: =================== 1. Go to Event, open an event page 2. Click "Register" & Select a ticket and confirm 3. Switch to edit mode => crash. Cause: ====== The cleanup callback called…
Steps to reproduce: =================== 1. Go to Event, open an event page 2. Click "Register" & Select a ticket and confirm 3. Switch to edit mode => crash. Cause: ====== The cleanup callback called `hide()` followed immediately by `dispose()`. Bootstrap's `hide()` is asynchronous — it registers a `transitionend` callback that fires `_hideModal()` after the CSS transition. `dispose()` nullifies `this._element` synchronously via `BaseComponent`, so when the `transitionend` fires and `_hideModal()` tries to access `this._element.style`, it crashes with: TypeError: Cannot read properties of null (reading 'style') This happened when switching to edit mode while the event registration modal was open: the `public.interactions` service stopped the interaction, triggering the cleanup. Solution: ========= Listen for `hidden.bs.modal` (fired at the end of `_hideModal`) and only `dispose()` inside that handler, ensuring `_element` is still valid throughout the transition. task-6133395
Fixes an issue where the Purchase Orders shortcut on an analytic account could disappear after changing that account's analytic plan. Users can now still see the related purchase orders regardless of which analytic plan the account belongs to, improving reporting consistency.
Original PR description
# How to reproduce - Enable the analytic accounting in the settings - Create a PO - Add a PO line - Set the Analytic Distribution of that PO line to an Analytic Account of your choice - Confirm the…
# How to reproduce
- Enable the analytic accounting in the settings
- Create a PO
- Add a PO line
- Set the Analytic Distribution of that PO line to an Analytic Account of your choice
- Confirm the PO
- Create a Vendor Bill from that PO and confirm the VB
- Go to the Analytic Account chosen before
- Change the Plan of that Analytic Account
# The problem
When the Plan is not set to the "Project Plan", the Purchase Orders smart button disappears
# Why
The Purchases Orders smart button is invisible if the variable purchase_order_count is equal to 0. That field is computed by a function that does a search with the following domain :
```py
[('order_line.invoice_lines.analytic_line_ids.account_id', '=', account.id)]
```
When we change the Plan of the Analytic Account, analytic_line_ids.account_id is set to NULL, so the search return nothing.
Why is that field set to NULL ?
Well, to reference its plan, an Analytic Line does not use a python-defined field. In fact, each time a new Analytic Plan is added to the database, a new column is added to the Analytic Line model. That column's name is x_plan{plan.id}_id or, for the specific case of the "Project Plan", it is account_id
When the Plan of an Analytic Account is changed, it takes every Analytic Line associated with that Plan and switch which column containing the id of the Analytic Account.
Take for exemple the following Analytic Line :
```
(account_id = NULL, x_plan2_id = NULL, x_plan3_id = 1)
```
When the associated Analytic Account's Plan is changed to the "Project Plan", it becomes :
```
(account_id = 1, x_plan2_id = NULL, x_plan3_id = NULL)
```
So, we need to adapt to search so that it uses the right plan's name.
opw-5897037
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#263330
Forward-Port-Of: odoo/odoo#248236This update adds coverage to ensure Saudi e-invoicing handles prepaid invoice taxes correctly when global rounding is enabled. It helps prevent small tax discrepancies on final invoices involving down payments, improving accuracy for compliant reporting.
Original PR description
### Steps to reproduce: - Download 'Sales', 'Accounting', and 'l10n_sa_edi' modules - Settings > Accounting > Rounding Method > Enable global rounding - Create sale order with 8 lines at 29.7 each…
### Steps to reproduce: - Download 'Sales', 'Accounting', and 'l10n_sa_edi' modules - Settings > Accounting > Rounding Method > Enable global rounding - Create sale order with 8 lines at 29.7 each with 15% taxes (triggers rounding precision issues) - Create and confirm 100% downpayment invoice - Deliver, then create final invoice with downpayment lines - Call `_l10n_sa_get_prepaid_amount()` on final invoice > Tax amount was calculated as 35.67 instead of correct 35.64 ### Cause of Issue: The prepaid amount calculation was summing pre-rounded `tax_amount_currency` values from individual downpayment lines (5.00 + 5.00 + 5.00... = 40.00), instead of summing unrounded `raw_tax_amount_currency` values (5.001 × 8 = 40.008 → 40.01 (after global rounding)) to calculate `tax_amount`. https://github.com/odoo/odoo/blob/27930ae41a5f03bd499983109de7f632472c3650/addons/l10n_sa_edi/models/account_edi_xml_ubl_21_zatca.py#L227-L240 This violates Odoo's [recent change](https://github.com/odoo/odoo/pull/180062) in `round_globally` pattern which states: https://github.com/odoo/odoo/blob/8a88756bed194910bc5a47e93f0e29610dbeee1f/addons/account/models/account_tax.py#L2208 ### Fix: Ensure cumulative rounding errors are avoided and correct global rounding is applied. opw-5881564 Note for v18.4 onwards: the bug isn't present anymore, only merging the test Forward-Port-Of: odoo/odoo#264093 Forward-Port-Of: odoo/odoo#261278
This fix ensures duplicated website snippets are correctly marked as changed when shared translated content is updated elsewhere. It helps editors see the true status of copied content and prevents unnoticed inconsistencies while editing multilingual pages.
Original PR description
Steps to reproduce: 1. Open the website editor 2. Add a snippet containing text content 3. Clone the snippet 4. Change the website language 5. Switch to translation mode 6. Modify the content of the original snippet => The cloned snippet reflects updates from the original snippet due to shared content, but is not marked as `o_dirty` and remains in a clean (yellow) state. Expected behavior: Cloned snippets should be marked as `o_dirty` when their content changes indirectly, ensuring the UI accurately reflects the modified state. This fix ensures duplicated snippets are flagged as `o_dirty` on indirect updates, preventing silent UI inconsistencies and improving state visibility. task-6176337
This update fixes an issue where CodaBox statements were sometimes incorrectly routed to the wrong bank journal due to differing currency settings. The system now prioritizes journals with explicit currency IDs, ensuring statements are accurately assigned to the correct currency-specific account. This improves financial reporting accuracy.
Original PR description
When several journals share the same IBAN but use different currencies, a CODA could land on the wrong journal instead of the currency-specific one. Split the lookup in two passes: first a journal with an explicit currency_id matching the CODA, then fall back to the no-currency journal (qualified by the company currency). Steps to reproduce: - Create 2 bank journals sharing the same IBAN; one without currency and one with USD. - Setup CodaBox connection and retrieve USD statements. - Before this fix: may land on the EUR journal. opw-6048931 Forward-Port-Of: odoo/enterprise#116426 Forward-Port-Of: odoo/enterprise#114590
This update fixes a reporting issue in the Profit & Loss report for Peruvian companies. Previously, depreciation entries were incorrectly categorized as 'Other Income.' The change ensures that depreciation entries (expenses) are now correctly classified in the 'Other Operating Expenses' section, improving report accuracy.
Original PR description
**Steps to reproduce:** - Install Accounting and l10n_pe_reports - Switch to a Peruvian company (e.g. PE Company) - Create a MISC journal entry with a line using a depreciation account (e.g. 6841000) and a debit value (e.g. 1000) - Post the entry - Check "Profit and Loss" report" **Issue:** The "Other operation income" section has an amount of 1000, even though a depreciation account (i.e. expense) was used. The amount should be in "Other operating expenses" section. **Cause:** A unique formula including accounts starting with 61, 66, 68, 71, 73, 74, 75, 76, 78, 79 and 99900 is used for "Other operation income" and "Other operating expenses" and depending on the sign of the sum, the result is reported in one of the section. **Solution:** Only report entries on "Income" accounts in "Other operation income" section and those on "Expense" accounts in "Other operating expenses". opw-6073666 Forward-Port-Of: odoo/enterprise#114362