Friday, July 24, 2026
18 changes · 19.0
Resolved issues and error corrections
The Italian localization now uses the correct acronym, “IC,” for reverse charge tax codes instead of the incorrect “CI.” This avoids confusion in tax setup and reporting labels for businesses using Italian accounting.
Original PR description
Reverse charge taxes (Inversione Contabile) should have the translated code ending with 'IC' (the acronym), not 'CI'. Suggested by partner: eLBati task-none Forward-Port-Of: odoo/odoo#277586 Forward-Port-Of: odoo/odoo#276270
Peruvian electronic invoices can now include the required district information in the address data. This helps businesses comply with local invoicing requirements and reduces the risk of rejected documents.
Original PR description
Allow to add the district node for the peruvian electronic invoicing. opw-6282314
This update makes mass mailing tests less sensitive to changes in underlying HTML processing tools. It helps keep automated checks stable on newer platforms without changing customer-facing email behavior.
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#277747 Forward-Port-Of: odoo/odoo#275959
Activities created in custom Studio apps now show a default placeholder icon when no matching app image is available. This prevents broken image text from appearing and gives users a cleaner, more consistent activity view.
Original PR description
When creating an activity in a custom app made with studio, no image is shown, and instead the alt text is shown with a missing image. This fixes the issue by showing a placeholder icon if no module is found for the activity group. opw-6282451 Previous behavior: <img width="1315" height="568" alt="image" src="https://github.com/user-attachments/assets/1e4fc1d5-3a35-4193-80fc-f6d161776e2e" /> New behavior: <img width="1315" height="568" alt="image" src="https://github.com/user-attachments/assets/6ed5ca8b-8481-470f-b7c6-dd59c616125e" /> (Original PR: https://github.com/odoo/odoo/pull/268957 Re-based on 17.0 as its the earliest version affected, so it can be forward-ported to future versions) Forward-Port-Of: odoo/odoo#269654
Changing a website's color palette now correctly refreshes background and image shape colors. This keeps edited pages visually consistent with the selected theme and avoids manual cleanup after palette changes.
Original PR description
[*] = html_builder Steps to reproduce: 1. Go to the Website app and drop any snippet. 2. Apply a background or image shape. 3. If a background shape is applied, click the **Flip Shape** option. 4. Go to the **Theme** tab and change the color palette. Issue: The shape color is not updated after changing the color palette. Reason: In the [commit](https://github.com/odoo/odoo/commit/aec8918018b92cbb5cb3dd761824d4), an edge case was left uncovered where applied background/image shapes were not re-rendered after changing the theme color palette, so its color was not refreshed to match newly selected palette. Forward-Port-Of: odoo/odoo#273337
A small typo was fixed so the website's Cloudflare Turnstile widget correctly follows its configured display mode. This ensures special links or settings that force the widget to show behave as intended, without changing other website behavior.
Original PR description
Stable forward-port source patch. Issue - The turnstile template uses a misspelled variable name in data-appearance: appeareance. - JS provides appearance. - Because of this mismatch, data-appearance always falls back to interaction-only and ?cf=show cannot force always mode. Fix - Replace appeareance with appearance in the turnstile template. Why stable-safe - One-line template fix. - No API/model/signature changes. - No behavior change outside the intended appearance selection. This is intended as the 17.0 source fix so forward-porting can propagate to upper versions. Related: odoo/odoo#273306 and odoo/odoo#273652 Forward-Port-Of: odoo/odoo#274976 Forward-Port-Of: odoo/odoo#273706
Mass mailing cleanup now removes the right outgoing email records instead of deleting related discussion messages directly. This helps preserve important chatter history for canceled notifications while still cleaning up mass mailing emails as expected.
Original PR description
It currently deleted the inner mail.message, while it should actually remove mail.mail records. Removing messages is managed at mail.mail unlink level using the 'is_notification' field. Indeed a mass_mailing email should remove the linked mail.message, while a canceled notification email should not remove the chatter message. Followup of odoo/odoo#209494
This fixes an editor error that could occur when users pressed the up or down arrow inside a code block placed in a list. The editor now safely finds the next navigation point or stays in place, preventing interruptions while editing content.
Original PR description
### Steps to reproduce: - Create a list (e.g. /list) - Inside the list item, create a code block (e.g. /code) - Write something inside the code block and press ArrowUp - A error occurs: 'Cannot read properties of null (reading nodeType)' ### Root cause: - When pressing ArrowUp or ArrowDown at the boundary of a code block, code tried to navigate to the previous or next element sibling of the code block. But if the code block is the only item inside a list item, there is no sibling, so it was null. ### Solution: - Instead of only checking the direct sibling, walk up the parent chain until finding a level with a sibling to navigate to. Stop at editable root to avoid leaving the editor. Return without navigating if no sibling is found. task-6358790 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forum users without enough karma now see the notification message displayed correctly when they try to mark a best answer. This prevents confusing, broken text and makes the forum guidance link readable.
Original PR description
Steps to reproduce ================== - Log in with the portal user (or any user without karma points). - Open a forum post. - Try to mark it as the best answer. Technical ========= From here https://github.com/odoo/odoo/pull/215145/changes/46e5ab20cb33536f0cf12d2fc3690beaa11697ee `htmlJoin` expects its first argument to be an iterable and its second argument separator to be a string. Passing the message string as the first argument causes it to be treated as an iterable of characters, while the guideline markup passed as the second argument is unintentionally used as the separator. As a result, the guideline link is inserted between every character of the message instead of being appended after it. Wrap the message and the additional guideline text in an array when calling `htmlJoin` so the notification is rendered correctly. Task-6302585
Fixes an issue where deleting text inside tables, banners, or columns placed within a toggle block could unexpectedly move the cursor outside the toggle and create extra content. This keeps editing behavior predictable and avoids accidental layout changes for users working with structured content.
Original PR description
Problem: When a table (or banner, or columns block) is placed inside a toggle block, deleting the last paragraph in a table cell creates a new block after the toggle block and moves the selection outside the table. Cause: `handleDeleteBackwardContentEnd` assumes the deleted block is always a direct child of the toggle content. However, the deleted block may be nested inside a table, banner, or columns block. Solution: Only create a new block after the toggle block when the selected block is a direct child of the toggle content. Steps to reproduce: - Add a toggle block. - Insert a table inside its content. - Add two paragraphs to a table cell. - Delete the last paragraph. - Observe that a new block is created after the toggle block and the selection moves outside the table. opw-6382058 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#277841 Forward-Port-Of: odoo/odoo#277194
This fixes a small display issue where project visibility options had an extra leading space. The labels now align correctly, making the project settings screen look cleaner and easier to read.
Original PR description
A space in the front, Trimmed away to left-align Thanks for reviewing See opw-6386651
Blockquotes in right-to-left content now display their visual border on the right instead of the left. This improves readability and layout consistency for users writing or viewing RTL languages in the HTML editor.
Original PR description
#### Description of the issue this PR addresses: - Blockquotes currently display their border on the left side. #### Desired behavior after PR is merged: - Update the styling so the border is displayed on the right side for RTL content. task-6296519 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269529
This fix prevents the HTML editor toolbar from trying to update after the editor has already been closed or removed. It improves reliability by avoiding a crash that could interrupt users while editing content.
Original PR description
A deferred toolbar update can still fire after the ToolbarPlugin has been destroyed. The global "mouseup" handler re-arms `updateToolbar` through a raw setTimeout that is not cancelled by `destroy`, so `_updateToolbar` runs on a plugin whose editable document has been detached. At that point `this.document.defaultView` is null and `getFilteredTargetedNodes` crashes with:
TypeError: Cannot read properties of null (reading 'getComputedStyle')
Cancelling the debounced updates in `destroy` is not enough: `cancel()` only clears the currently pending timer, it does not disable the debounced function, so the post-destroy `updateToolbar()` call re-schedules it.
Guard `_updateToolbar` with the plugin's `isDestroyed` flag instead, which covers every deferred entry point.This fixes how a custom product selection field is built in stock picking forms. As a result, configured filtering rules are correctly applied, helping users see the right product options during stock operations.
Original PR description
After https://github.com/odoo/odoo/issues/196785; the standard way to build a custom m2o field in JS is to call a method from the Many2one module, instead of extending an object from it. This commit solves issues regarding domain in the view not being passed to the widget opw-6399906 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Manually printed confirmed payslips now save the generated PDF to the payslip record, matching the automatic send flow. This helps payroll teams keep a complete document history in the employee payslip chatter without extra manual uploads.
Original PR description
Right now, manually printing a confirmed payslip from the list view downloads the pdf but never links it to the chatter, unlike the automatic generate and send flow. This backports the fix from the odoo/enterprise#94019 pull request, making the print controller also create the attachment on the payslip. taskid-6391358
Fixed a rounding issue that could show a tiny leftover amount instead of zero in exported Trial Balance reports. This prevents confusion when accounts are actually balanced and improves the reliability of financial report exports.
Original PR description
Steps to reproduce -------------------- - Install account_reports module; - Create a new account; - Create a miscellanous operation for the previous month using thenew account with a credit amount of $8.28; - Create a second MISC for the current month with two lines using the account : debit = 262.67 and credit = 254.39; - Open the trial balance report and filter the new account (end balance should be 0); - Export the report as XLSX; The end balance value is 2.84e-14 due to float rounding issues. opw-6369016 Forward-Port-Of: odoo/enterprise#123896
The Stripe expense cardholder field has been corrected so it uses the standard selection behavior. This ensures filters set in the view are properly applied, helping users see only the relevant cardholders when entering expenses.
Original PR description
After https://github.com/odoo/odoo/issues/196785; the standard way to build a custom m2o field in JS is to call a method from the Many2one module, instead of extending an object from it. This commit solves issues regarding domain in the view not being passed to the widget opw-6399906
This fix prevents a test helper for appointment CRM flows from affecting later steps unexpectedly. It keeps automated validation more reliable, reducing false failures or hidden side effects in quality checks.
Original PR description
Capturing `oldWriteText` at module import and relying on a subsequent tour step to restore it can cause state leakage if the subsequent step doesn't exactly target a resulting effect of the mocked `writeText` call. Refactor the tour step to capture `writeText` dynamically and restore the original method on first call. runbot-241004