Tuesday, September 22, 2026
72 changes · master
Enhancements to existing features
Users editing follower subscriptions can now switch all notification categories on or off with a single “All Notifications” option. This reduces repetitive clicking and makes managing subscription preferences faster and less frustrating.
Original PR description
Before this commit, people could choice to which subtype to suscribe, through the "Edit Subscriptions" dialog in the Follower menu. There are 10 items, and it's quite exhausting to select all the items by clicking on each checkbox by hand. This commit adds a "All Notifications" that eases toggle all items on and off. Task-6592809 https://github.com/user-attachments/assets/c302870f-4d59-4131-a8de-8ac9fb4483a0 Forward-Port-Of: odoo/odoo#289948
The project and task Kanban cards have been visually adjusted to better present the "Budget on track" button. This improves clarity and consistency for users reviewing project budget status at a glance.
Original PR description
This PR fine-tunes the "Budget on track" button based on the design review of the project and task Kanban cards. task-3462435 Requires: - https://github.com/odoo/odoo/pull/288893 Forward-Port-Of: odoo/enterprise#131938
Project and task Kanban cards have been visually refined so information is more consistently aligned and easier to scan. Priority star spacing was also adjusted to work better across desktop and touch devices, improving day-to-day usability without changing workflows.
Original PR description
*: hr_timesheet, mail, project, web ### Fine-tune kanban cards Prior to this PR, elements in project and task Kanban cards could have different styles and layouts, resulting in inconsistent card…
*: hr_timesheet, mail, project, web ### Fine-tune kanban cards Prior to this PR, elements in project and task Kanban cards could have different styles and layouts, resulting in inconsistent card appearances. This PR fine-tunes the card layouts and aligns their elements to improve visual consistency and readability. ### Review spacing in priority field Prior to this PR, the gap between stars was too large on desktop but was necessary for proper interaction on touch devices. This PR adjusts the gap between stars specifically for touch devices. Requires: - https://github.com/odoo/enterprise/pull/131938 | Before | After | |--------|--------| | <img width="404" height="540" alt="Screenshot 2026-09-18 at 09 45 10" src="https://github.com/user-attachments/assets/a35de006-7cbd-4b5e-9d9a-72f4e63d34a3" /> | <img width="435" height="597" alt="Screenshot 2026-09-18 at 09 28 11" src="https://github.com/user-attachments/assets/d6ac9d4c-64ba-434a-b2f8-5e926c1bb566" /> | | <img width="385" height="197" alt="Screenshot 2026-09-18 at 09 54 46" src="https://github.com/user-attachments/assets/644c17b2-5311-4aa0-b8c3-af64610c2dcc" /> | <img width="394" height="219" alt="Screenshot 2026-09-18 at 09 54 40" src="https://github.com/user-attachments/assets/a25f3f0a-a0d6-4be6-84b4-752844e52b7c" /> | --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#288893
The GitHub issue template has been updated to align with the upcoming Odoo 20 release. This helps people report issues with the right release context, improving triage quality without changing product behavior.
Original PR description
😊 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#289847
General ledger reports now hide ledger columns that were not selected in the horizontal group-by filters. This avoids showing empty columns filled with zeroes, making financial reports easier to read and focus on relevant data.
Original PR description
Since there won't be any data because of the filters, there is no need to display a column full of zeroes. task-6532155 Forward-Port-Of: odoo/enterprise#132391
The timesheet and attendance popover has been visually refined so primary actions stand out while secondary options are less distracting. This makes it easier for users to focus on creating time entries or starting work sessions without confusing links or overly prominent end-session buttons.
Original PR description
The timesheet systray popover gave its side actions as much weight as the timer form it exists for. Ending the session was a full-width warning button with an icon: it read like an alert and competed…
The timesheet systray popover gave its side actions as much weight as the timer form it exists for. Ending the session was a full-width warning button with an icon: it read like an alert and competed with Create, the main action of the popover. The Assistant link sat between the Timesheets and Attendance tabs in bold link style, so it looked like a third tab although it closes the popover to open another screen. This commit gives each element the weight of its role: - The tab bar gets a light background, setting the navigation apart from the content. - Assistant moves to the end of the tab bar, after a vertical divider, as a small secondary button. Its "open in new" icon tells that it leaves the popover, and a vertical margin gives the bar some room. - The divider takes the border color (text-300) at full opacity, as `.vr` paints its text color at 25% opacity, which would not match the border under the tabs. - End Session and Check out become secondary buttons, sized to their label and without icon. Start Session and Check in keep their primary style and icon, as they remain the main action when nothing is being recorded. - The timer popover keeps its 400px width in every state. Without Attendance, nothing sized its checked-out view, which reuses the att_container class: it shrank to its content and widened as soon as a session started. The Check out button of the Attendance tab is defined in hr_attendance. The override only restyles it when both tabs are displayed, so users without the Timesheets tab keep the full-width warning button of the attendance popover. As the override replaces the whole class expression of the button, it restates flex-grow-1 for those states. task-6579209 Forward-Port-Of: odoo/enterprise#132337
This update replaces confusing directional arrow icons with clearer navigation arrows across several Odoo screens. It also improves the spacing and alignment of link arrows in fields, making mobile form interactions easier to read and use.
Original PR description
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 Forward-Port-Of: odoo/odoo#289817
A new shared helper makes it easier and more consistent for Odoo features to connect to IAP services. It centralizes required request details, error handling, and deprecation warnings, which can reduce maintenance effort and improve reliability for future integrations.
Original PR description
Util to call IAP route with required args, taking care of errors, and deprecation warnings Checkout equivalent on IAP: `iap_route`
Usage:
```py
result = iap_tools.iap_request(
env=self.env,
endpoint=IrConfigParameter.get_str('my_module.iap_endpoint'),
route='/my-module/1/my-route',
json={"param1": value1, "param2": value2},
)
```
task-6391762
IAP: https://github.com/odoo/iap-apps/pull/1899Brussels is now available in the Belgian states list used for address entry. This makes Belgian address forms clearer for users who expect to select Brussels, even though it is a region rather than a province.
Original PR description
Brussels is a region and not a province, but it is confusing for users not to find it in the states list when filling out Belgian addresses. This adds Brussels to the list of Belgian states. Task-6584223 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The website blog module has been tidied up by removing page templates that are no longer used after the blog redesign. This reduces maintenance overhead and keeps the blog code aligned with the updated design, with tests adjusted accordingly.
Original PR description
As a follow-up of the blogs redesign [1], this commit removes the templates that are not needed anymore. An upgrade script will make the needed adaptations (see linked PR). [1]: https://github.com/odoo/odoo/pull/216148 Related to task-3083656
Brussels communes are now correctly associated with the Brussels state in Belgian payroll data. This improves address and regional payroll data accuracy for organizations operating in Brussels.
Original PR description
Communes from the Brussels region were missing their state association. This maps all Brussels communes to the newly added Brussels state. Task-6584223 See odoo/odoo#289142
Mail-related record lists now handle common searches and reads more directly, avoiding unnecessary copying behind the scenes. This improves performance for operations on large mail relationships, especially when a match is found early, without changing user-facing behavior.
Original PR description
Before this commit, an array read method that RecordList does not implement is served by proxyGet, which spreads the whole list into an array of proxies and calls the Array method on that copy, so every map, filter or some over a relation allocates a copy of the relation first, and a search that matches the first record builds that copy all the same. This commit implements those methods on the list: they read the records from the list and hand the callback the same proxies, and the compute of a lazy relation now runs from one place. This makes a search stop on the record it matches: measured in Chrome, a some() on the first record of a relation takes 0.5us whatever the size of the relation, where it took 1.6us on 5 records and 105us on 500. A map() reads every record either way and only drops the copy, 14.4us instead of 15.7us on 50 records.
This update links companies more directly with their employees so payroll-related checks can better identify the right people. It helps reduce unnecessary pay run warnings, making payroll administration cleaner and less distracting.
Original PR description
Adding O2M `employee_ids` on `res.company` inverse of `employee.company_id` Task: 6366409
The manufacturing order screen now shows the packages smart button with the newer package icon. This small visual update makes the button clearer and keeps the interface more consistent for users.
Original PR description
The smart button for packages now uses the package_2 icon. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#289567
This update adds extra automated checks for the Intercompany Comparison Report. It helps ensure the report continues to behave correctly, reducing the risk of reporting issues for finance teams.
Original PR description
Task : https://www.odoo.com/odoo/project/967/tasks/6567355 No Community modifications.
The accounting firm settings text has been reworded to make it easier for users to understand. This improves clarity in the accounting setup experience without changing how the feature works.
Original PR description
changing the wording for the account firm settings text. task-6578290
This update adds test coverage to ensure message posting data is properly cleaned before use. It helps reduce the risk of unsafe or unexpected content reaching mail-related workflows, improving reliability and protection without changing normal user behavior.
Resolved issues and error corrections
Fixes a display issue where social media icons using the circle style could become hard to see on dark website sections. This ensures icons keep a contrasting color, improving page readability and visual consistency for website visitors.
Original PR description
Steps to reproduce: - Select a dark website color palette. - Drag and drop a snippet with a dark background onto the page. - Drag and drop a "Social Media" snippet inside it. - Disable the "Color" option. - Select the "Circle" layout. => The icons are not visible against the dark background. Before this commit, the shaped icon fallback introduced by [1] had higher specificity than the `rounded-empty-circle` color reset. It forced a dark color onto icons placed on a dark background. After this commit, `:where()` keeps the fallback selector specificity low, so empty circle icons inherit a contrasting color. [1]: https://github.com/odoo/odoo/commit/cc02feec060a9469f3e4af6b40fb291266beca99 Forward-Port-Of: odoo/odoo#289855
Features or functions removed from Odoo
Odoo now avoids searching relationships that depend on calculated, non-saved links, which could be slow or unreliable. This keeps searches more predictable and encourages using purpose-built calculated relationship fields when needed.
Original PR description
The inverse field should be stored (`_field_to_sql`) on the one2many. We should not support and try to find the values of non-stored inverses. This could be a performance issue and the alternative is to create a computed one2many field. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Code cleanup and technical improvements
Spreadsheet-related components were updated to align with the latest spreadsheet engine changes. This keeps document spreadsheets and dashboards more reliable and easier to maintain, with no major visible change expected for end users.
Documentation and clarification updates
A contributor added their signed Contributor License Agreement confirmation. This is an administrative legal step that allows their future contributions to be accepted under Odoo's contribution rules.
Original PR description
Hi! I would really like to help contributing at Odoo. BTW Thanks for such product, when I studied at university we used Odoo for laboratory works. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes an unstable automated test related to call recording messages in Discuss. It helps keep the mail and communication features' quality checks reliable, reducing false failures during development.
Original PR description
Before this commit, the test "active call with a recording shows a processing link" fails at random:
2. [toBe] Failed to find 1 of ".o-mail-NotificationMessage div:text('A recording is being processed and will be available here.')" (Timeout of 10 seconds). Found 0 instead.
This happens because the test inserts its message in the store right after `openDiscuss`, which returns before the messages of the channel are fetched. The thread loads around the new message separator, and `loadAround` replaces the message list with the fetched messages, so the inserted message is dropped and the link never renders.
This commit fixes the issue by creating the message and its call history on the server, so the link renders from the messages of the channel.
https://runbot.odoo.com/odoo/error/947250
Forward-Port-Of: odoo/odoo#289924Odoo now keeps lot, serial, and expiration controls hidden for products that are not tracked, even when other apps show information in the same Inventory section. This prevents users from seeing unrelated stock settings and keeps product forms clearer and more accurate.
Original PR description
The lot and serial controls relied on the visibility and access rules of their parent Traceability group. Modules such as PLM relax those rules to display their own fields, which also exposed…
The lot and serial controls relied on the visibility and access rules of their parent Traceability group. Modules such as PLM relax those rules to display their own fields, which also exposed unrelated stock options. Apply the tracking and access restrictions directly to the stock and expiration controls while retaining the parent rules that hide an empty Traceability section. Steps to reproduce: 1. Install Inventory and PLM. 2. Open a product that is not tracked by lot or serial. 3. Open its Inventory tab. Before this commit: The Custom Lot/Serial controls could remain visible because PLM made the shared Traceability group visible. After this commit: The shared section can display PLM information while lot, serial, and expiration controls remain limited to tracked products and authorized users. 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 Forward-Port-Of: odoo/odoo#289124
Avatar popups in the Mail app now show a single clean border instead of an overlapping double border. This small visual fix improves polish and readability without changing any behavior.
Original PR description
PR https://github.com/odoo/odoo/pull/289526 introduced a double border, the border of the popover and the border of the card overlapped. This PR disable the border of the card (but keep the "roundness"). Before <img width="540" height="439" alt="image" src="https://github.com/user-attachments/assets/5443318e-8a3f-42ed-8f68-bafc1357004c" /> After <img width="359" height="167" alt="image" src="https://github.com/user-attachments/assets/eb74f130-c911-4e1e-9e54-92c01ac764cb" /> Forward-Port-Of: odoo/odoo#289934
A recent styling change unintentionally affected how kanban cards interacted with other visual rules, which could make some card indicators display incorrectly. This fix limits the change to the intended placeholder background behavior, restoring the expected appearance of kanban records without changing functionality.
Original PR description
Commit[^1] excluded `.o_kanban_ghost` from the whole `.o_kanban_record` block so that ghosts stop receiving the background added in Commit[^2]. Putting the `:not()` on the root selector raised the…
Commit[^1] excluded `.o_kanban_ghost` from the whole `.o_kanban_record` block so that ghosts stop receiving the background added in Commit[^2]. Putting the `:not()` on the root selector raised the specificity of every nested rule, so they now win over overrides that relied on equal specificity and load order, e.g. the kanban color border of `.o_card_record.o_kanban_color_N::after` in web_enterprise. This commit scopes the exclusion to the `background-color` declaration only, as it is the only style of the block that applies to a ghost: - the nested rules require a class a ghost never has (`o_kanban_global_click`, `o-kanban-button-new`, `o_record_selected`, `o_kanban_color_N`) or target children, and a ghost is empty; - `&:first-of-type` matches the first ghost (records are `<article>`, ghosts are `<div>`), but the ghost's `my-0` overrides its margin. [^1]: 416512eac0e2 [^2]: d20c062bf8e9 task-6593149 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#289967
The search menu has been visually adjusted to align with Odoo's new Frost design. This improves consistency and polish in the user interface without changing core search behavior.
Original PR description
This commit adapts the search_bar_menu to better match the new Frost design. task-6588108 | Before | After | |--------|--------| | <img width="831" height="642" alt="Screenshot 2026-09-22 at 10 49 27" src="https://github.com/user-attachments/assets/1f620b2a-73b8-4541-9ad5-2a16bbffedd2" /> | <img width="783" height="643" alt="Screenshot 2026-09-22 at 10 49 15" src="https://github.com/user-attachments/assets/5ff2b567-32f2-445c-9993-505ec0f9c02e" /> | | <img width="312" height="228" alt="Screenshot 2026-09-22 at 10 49 56" src="https://github.com/user-attachments/assets/f649da4a-0d8b-4f1a-a8d0-7ca8413aea40" /> | <img width="310" height="238" alt="Screenshot 2026-09-22 at 10 48 39" src="https://github.com/user-attachments/assets/c2774e53-c576-476e-96e4-1bb8a99bd0ca" /> | --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#289632
The expense dashboard now has clearer spacing between the top dashboard bar and the expense cards. This small visual fix makes the expense overview easier to read and less cramped.
Original PR description
Before this commit, the kanban cards were stuck against the dashboard bar, with no space in between. This commit adds some spacing. task-6584235 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#289164
Fixed a visual issue where a settings checkbox could show an incorrect white patch on small screens. This keeps Helpdesk settings pages looking consistent and polished across mobile and narrow layouts.
Original PR description
The boolean of a setting box floats over the `border-left` of `o_setting_right_pane` and needs an opaque background to mask it. That background was hardcoded to `$o-view-background-color` on…
The boolean of a setting box floats over the `border-left` of `o_setting_right_pane` and needs an opaque background to mask it. That background was hardcoded to `$o-view-background-color` on `o_setting_left_pane`, so it was only correct where the setting happens to sit on a white surface. `o_form_sheet` paints `$o-view-background-color` only from `md` up, so below that breakpoint a setting in a regular form sits on `--body-bg` and the hardcoded white showed through as a patch. Move the background onto the boolean field, keeping `$o-view-background-color` as its default and falling back to `--body-bg` only below `md` and outside `o_setting_container`, whose `.settings` panel stays white at every width. Steps to reproduce: * Open Helpdesk on a small screen (below the `md` breakpoint) * Open the manage menu of a team kanban card * Click `Settings` * The boolean's checkbox shows a white patch on the gray sheet => BUG --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#289840
This fixes the placement of call action buttons in Discuss on mobile screens, especially when picture-in-picture or compact layouts hide the meeting clock. Users should see a cleaner, more predictable call interface on phones and small devices.
Original PR description
This comes from `.ms-auto` that assumes the Meeting clock was shown but it's only present in non-PiP and in desktop. <img width="1109" height="793" alt="Screenshot 2026-09-22 at 10 37 09" src="https://github.com/user-attachments/assets/f8aaf72f-2795-44b1-ba2e-5f9a2197f84b" /> Forward-Port-Of: odoo/odoo#289843
Questions sent through the AI ask-user tool now keep their intended formatting after the user replies. This prevents visible HTML code from appearing in chats, making conversations clearer and more professional.
Original PR description
Questions from the ask user question tool are properly formatted while waiting for the user's answer. However, once answered, they are posted in the chat with their HTML tags displayed as text. This happens because the question body is stored as a string and, unlike confirmation prompts, is not converted back to markup before being posted. This commit fixes it by sanitizing all user input request prompts before posting them. Task-6591790 Forward-Port-Of: odoo/enterprise#132538
The Discuss call context menu now uses the available screen width better and provides more spacing between menu items. This makes call controls easier to see and tap, especially on touch devices.
Original PR description
- was not taking the whole width of screen - items need more spacing for touch interaction <img width="1104" height="826" alt="Screenshot 2026-09-22 at 11 00 06" src="https://github.com/user-attachments/assets/35f982f3-aa3d-47d7-aa49-3f9562e6aca0" /> Forward-Port-Of: odoo/odoo#289848
The emoji picker now displays with rounded corners that align with its surrounding popover. This fixes a small visual inconsistency, making the interface look cleaner and more polished.
Original PR description
Before this commit, emoji picker had cut corners. This come from the `rounded-3` that mismatch the roundness of popover. This commit fixes the issue by matching the roundness of EmojiPicker component when inside the popover. <img width="802" height="550" alt="Screenshot 2026-09-22 at 12 10 14" src="https://github.com/user-attachments/assets/59dc9c87-7a52-4280-9e95-b142140d73a3" /> Forward-Port-Of: odoo/odoo#289868
The eCommerce product image cards have been refreshed with softer rounded corners and improved spacing to match the latest visual design. Color labels now adapt better across light and dark display modes, providing a more consistent shopping and editing experience.
Original PR description
This PR adapts the eCommerce image cards design to make it match the latest redesign by adding roundness and padding. It also makes dynamic the basic colors of `.o_field_many2many_tags_color_dot .o_tag`, which are used in these cards. task-6588121 | Before | After | |--------|--------| | <img width="1079" height="464" alt="Screenshot 2026-09-21 at 16 05 20" src="https://github.com/user-attachments/assets/69bc07fc-c501-49dd-882a-4b5ccb40e5d5" /> | <img width="1082" height="514" alt="Screenshot 2026-09-21 at 19 34 54" src="https://github.com/user-attachments/assets/a8206325-e336-4cd6-a21d-fe0bc50957be" /> | --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#289611
This update fixes an internal accounting test by using a valid sample PDF instead of invalid placeholder content. It helps keep automated quality checks reliable, reducing false failures during development without changing user-facing behavior.
Original PR description
Use PDF_RAW from base.tests.files instead of fake (and invalid) PDF content, like the other tests needing a PDF attachment. runbot-946577 Forward-Port-Of: odoo/enterprise#132471 Forward-Port-Of: odoo/enterprise#131746
In Discuss, users can now hold Shift while choosing emojis from the quick reaction menu to add multiple reactions without reopening the picker each time. This restores the expected behavior and makes adding several reactions faster and less disruptive.
Original PR description
When adding a reaction to a message in Discuss, selecting an emoji adds the reaction and closes the emoji picker. This can be inconvenient when adding multiple reactions in a row, as the picker has to be reopened every time. To address this problem, the emoji picker remains open when the user holds Shift while selecting an emoji. However, this behavior was overlooked when implementing the Quick Reaction Menu, which therefore closes the emoji picker upon emoji selection, regardless of whether Shift is pressed. This commit fixes the Quick Reaction Menu so that holding Shift while selecting an emoji once again prevents the emoji picker from closing. [Task-6575382](https://www.odoo.com/odoo/project/1519/tasks/6575382) Forward-Port-Of: odoo/odoo#289466 Forward-Port-Of: odoo/odoo#288336
The Tax ID field now displays correctly on mobile-sized screens in contact and company forms. This prevents label overlap and keeps the add button positioned properly, making contact details easier to view and edit on smaller devices.
Original PR description
Small screens lay every field out as an outlined box carrying its label on the top border. The Tax ID was left out of it: a0d97b315151 moved its value into a `vat_div` that is no cell of the form…
Small screens lay every field out as an outlined box carrying its label on the top border. The Tax ID was left out of it: a0d97b315151 moved its value into a `vat_div` that is no cell of the form grid, so the label floated onto an input that had no box to float onto, and the '+' dropdown now sharing that row grew to half of the field, drawing itself in its middle. `o_outlined` is the class custom markup opts in with to be laid out as a field box, and the value is left to grow alone in the row, as is already done for the booleans and the priority. Steps to reproduce: - Resize the browser window under 768px wide - Open the Contacts app - Click on any contact => The "Tax ID" label overlaps the input below it, that input has no outlined box while the Address and Job Position ones do, and its '+' button stands in the middle of the field instead of at its end task-6522832 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 Forward-Port-Of: odoo/odoo#289551
The calendar event popover has been adjusted to match the updated Frost design, fixing spacing, rounded corners, icon alignment, and attendee badge display. This makes calendar details easier to read and gives users a cleaner, more consistent experience.
Original PR description
Before this PR, the calendar event popover was not revisited after Frost. Several of its elements were still positioned and coloured against the pre-Frost container, so the popover looked visually…
Before this PR, the calendar event popover was not revisited after Frost. Several of its elements were still positioned and coloured against the pre-Frost container, so the popover looked visually broken: - the close button didn't have margins - the icons were a bit too faded and vertically centred against their value, so on a multi-line value they drifted to the middle instead of lining up with the first line; - the header's top corners were square and overflowed the popover's own radius; - the attendee status badge was cut off, and its border was drawn in the view background colour on a popover background. | Before | After | |--------|--------| | <img width="475" height="459" alt="Screenshot 2026-09-10 at 15 26 30" src="https://github.com/user-attachments/assets/389e6ab1-2f56-4796-aab5-36587d051eff" /> | <img width="475" height="457" alt="Screenshot 2026-09-10 at 15 25 48" src="https://github.com/user-attachments/assets/49136aba-d3cf-4f87-a4e7-323ce27cbfb5" /> | task-6545870 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#287657
This fixes a randomly failing automated test for calendar attendee filters by allowing the attendee search results enough time to load before selection. It helps keep calendar quality checks stable and reduces false failures during development.
Original PR description
Purpose ======= Fix the attendee filters test which is failing randomly because not finding "Partner 2" when activating the filter in the side panel. Specification ============= When filling the input, only 'animationFrame' is called before clicking on the element. 'animationFrame' might not be enough time elapsed for the autocomplete to perform the 'name_search' and update the input before the 'click' fires. Replacing 'animationFrame' by 'runAllTimers' to make sure the search input has the time to update its content between the 'fill' and the 'click'. Error-947211 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#289495
Fixes a crash that occurred when users opened the report settings form from the report editor in debug mode. This makes report configuration more reliable for users who need to adjust or inspect report setup.
Original PR description
On the report editor in debug mode, click on the cog to open the ir.action.report form view Before this commit, there was a crash After this commit, there is no crash task-6531172 Forward-Port-Of: odoo/enterprise#131987
Marketing automations can now only use message-based activities, such as email, SMS, or WhatsApp, as triggers. This prevents users from selecting unsupported options like internal notes, avoiding automations that would never run as expected.
Original PR description
This commit adapts the api.constrains on triggering_activity_id so as to reduce the allowed activity_types allowed to be set for this field. Before, a user could've set a log_note activity as a triggering_activity_id, which doesn't make sense. We never process any event for this activity_type. Now the constrains, blocks the user from setting anything else than a mail, sms or whatsapp activity as a triggering one. task-6587863 Forward-Port-Of: odoo/enterprise#132324
The VoIP permission dialog button labels now follow sentence-case wording for consistency with Odoo's interface style. This is a small visual text adjustment that makes the dialog feel more polished and consistent for users.
Original PR description
Following odoo/odoo#282764, align the permission dialog buttons with the sentence-case convention. task-6464811 Forward-Port-Of: odoo/enterprise#131553
Gantt chart group titles now remain readable when users scroll horizontally. This prevents overlapping headings from obscuring schedule information and makes planning views easier to use.
Original PR description
When scrolling horizontally, two column group titles could overlap and become unreadable. This commit adds a background to these titles, so they don't conflict with each other. `bg-opacity-100` resets the bg opacity that the title inherits from its parent. task-6589119 | Before | After | |--------|--------| | <img width="468" height="210" alt="Screenshot 2026-09-21 at 17 02 17" src="https://github.com/user-attachments/assets/d5985dc6-0a3a-4c0b-9fd6-95d3971e2924" /> | <img width="386" height="203" alt="Screenshot 2026-09-21 at 17 01 36" src="https://github.com/user-attachments/assets/b1aa749c-1e6c-4c63-b344-ef960e56ecfd" /> | Forward-Port-Of: odoo/enterprise#132427
The Belgian payroll employee form no longer shows the same worker status fields twice. This reduces confusion for HR users and makes employee records easier to review and maintain.
Original PR description
Remove duplicate fields in `hr.employee` form view in belgian payroll module which are `l10n_be_worker_status` and `available_l10n_be_worker_status`. task-6565809
Users can now customize the Inventory Overview by removing graph cards without causing the page to crash. This makes Studio customizations safer and keeps the inventory dashboard accessible even when optional graph fields are hidden.
Original PR description
Steps to reproduce:
- Go to Inventory > Overview
- Enable Studio, delete a kanban card that contains the "picking_type_dashboard_graph" widget (field kanban_dashboard_graph)
> UncaughtPromiseError > OwlError
> TypeError: Cannot read properties of undefined (reading 'includes')
at StockKanbanRenderer.getGroupsOrRecords
Cause of the issue:
`StockKanbanRenderer.getGroupsOrRecords` assumes the field `kanban_dashboard_graph` is always present on every record to detect if all Inventory Overview graphs are sample data and, if so, replace them with randomized values.
By removing the card with studio, we remove the field from the fields fetched for the record, and so `r.data.kanban_dashboard_graph` is `undefined`.
Fix by ignoring records for which the field isn't fetched instead of assuming it's always there.
opw-6512743
Forward-Port-Of: odoo/odoo#285593Email template editors now correctly block video embeds, such as YouTube videos, before they can be added. This prevents videos from being stripped out during saving and avoids broken or empty content in outgoing email templates.
Original PR description
Steps to reproduce: 1. Go to Settings > Technical > Email Templates. 2. Open any email template. 3. In the Body editor, either paste a YouTube URL and select Embed YouTube Video from the popup, or…
Steps to reproduce: 1. Go to Settings > Technical > Email Templates. 2. Open any email template. 3. In the Body editor, either paste a YouTube URL and select Embed YouTube Video from the popup, or type `/media` and open the 'Videos' tab in the Media dialog. 4. Select a video or embed a YouTube video. 5. Save the email template. Issue: - The YT URL is converted into an `<iframe>` video element in the email template. However, the `<iframe>` element is removed when the template is saved because it is not supported by the email HTML sanitization. - This leaves the surrounding content empty and can result in broken HTML in the email template. The `body_html` field was configured with `allowCommandVideo: false` to prevent video embedding, but this option is not recognized by the HTML field and is therefore ignored. Solution - Use the supported `allowVideo: false` option on the `body_html` field of email templates to disable video embedding in the editor as [this PR](https://github.com/odoo/odoo/pull/219288) has changed the html_field components's attribute. Expected behavior - Video embedding should be disabled in email templates, preventing users from inserting YouTube videos and avoiding `<iframe>` elements that are later removed by HTML sanitization. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#286133
Odoo now prevents users from creating API keys that are already expired. This helps avoid accidental setup mistakes, such as copying example dates from documentation, and ensures newly created keys are usable when created.
Original PR description
Prevent creating API keys that are already expired. One typical case is when you copy/paste the documentation and end up creating keys that are already expired, without noticing. Forward-Port-Of: odoo/odoo#289302 Forward-Port-Of: odoo/odoo#286548
This fixes an issue that could prevent AI-powered similar document matching from working correctly when model information was missing. The change helps keep document recommendations reliable and avoids errors caused by using the wrong model reference.
Original PR description
This commit fixes an issue with the `_get_similar_documents` where, in case of missing `query_model` or `target_model` would return a default `self.env[query_model]`. This is incorrect since `query_model` is a recordset, not a string. Therefore, the fix passes `query_model._name` instead. Forward-Port-Of: odoo/enterprise#132372
This update removes a leftover reference to an order preparation tracking item that no longer exists. It helps keep the self-ordering point-of-sale workflow aligned with recent changes and avoids unnecessary checks in related tests.
Original PR description
Remove last reference to `last_order_preparation_change` that was removed here. https://github.com/odoo/odoo/pull/250692 Forward-Port-Of: odoo/enterprise#132116
Turkish e-invoice and e-dispatch documents now count only actual product lines when reporting the line total, instead of including tax, note, or accounting lines. This helps ensure exported documents match official requirements and reduces the risk of validation issues.
Original PR description
*: einvoice, edispatch Currently, the LineCountNumeric node is filled as the length of `line_ids` which includes all the journal items on that move, including product lines, tax lines, note lines etc. The documentation explains that the node's value should be the number of product lines instead. This commit uses the base lines count as the value for the node. task-6584840 Forward-Port-Of: odoo/enterprise#132150
Corrected minor English wording issues in the Peppol activation flow. This helps the activation experience feel more polished and trustworthy for English-speaking users.
Original PR description
There were some minor English mistakes on the Peppol activation wizard that might make Odoo look cheap and untrustworthy to English-speaking audiences. This commit fixes these english mistakes. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#285462
This update prevents French e-invoicing tests from failing when an optional French PDP component is not installed. It aligns test expectations with the installed modules, improving reliability of automated checks without changing business functionality.
Original PR description
### Issue: Tests in `TestCIIFR` fail when run without `l10n_fr_pdp` installed The expected XML files contain `PMT`, `PMD` and `AAB` notes that are only generated when `l10n_fr_pdp` is installed ### Cause: The note generation for FR e-invoicing lives in `l10n_fr_pdp` When it is not installed, the notes are absent from the generated XML but still present in the expected test files When `l10n_fr_pdp` is not installed, the expected tree is stripped of `PMT`, `PMD` and `AAB` notes before comparison ### Steps to reproduce: - Install `l10n_fr_account` without `l10n_fr_pdp` - Run `TestCIIFR` from `l10n_account_edi_ubl_cii_tests/tests/test_xml_cii_fr.py` Before the fix, the affected tests fail on the `cbc:Note` comparison runbot-945999 Forward-Port-Of: odoo/odoo#284661
Generic demo leave types no longer carry a specific country, preventing them from blocking company country changes in demo or development databases. This keeps country checks in place for real business leave data while making demo setups easier to configure.
Original PR description
_check_country_change_holidays constraint blocks writes to res.company.country_id whenever hr.leave/hr.leave.allocation records exist whose leave type country differs from the new company country. Unset country_id on the generic holiday_status_* demo leave types they are not meant to represent a specific country's holiday policy, so they should not carry a country at all. With country_id set to False, they no longer participate in the country-change constraint. The constraint keeps protecting real country changes on business data, while no longer blocking legitimate demo installs where we configure the main company with our country but rely on demo data for dev instances. Related to https://github.com/odoo/odoo/pull/277346 Forward-Port-Of: odoo/odoo#288983 Forward-Port-Of: odoo/odoo#278749
This fix ensures access rules created through Odoo Studio are not incorrectly marked as read-only. This helps administrators continue adjusting Studio-created permissions without unexpected restrictions.
Original PR description
task-6481613 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 Forward-Port-Of: odoo/odoo#289480
The project overview now shows the upcoming milestone based on its deadline instead of when it was created. This keeps the project list consistent with the milestone list and helps users see the correct next delivery point.
Original PR description
Issue: The project list could display the first created unreached milestone as the next milestone, even when another milestone had an earlier deadline. This made the project overview inconsistent…
Issue: The project list could display the first created unreached milestone as the next milestone, even when another milestone had an earlier deadline. This made the project overview inconsistent with the milestone list. Steps to reproduce: - Create a project with milestones enabled. - Create MS1, then MS2. - Give MS1 a later deadline than MS2. - Open the project list and display the Next Milestone column. Cause: `_compute_next_milestone_id()` aggregated unreached milestones as an `id:recordset` and selected its first element. The ORM orders that aggregate by database ID, so creation order was used instead of the milestone model's deadline order. https://github.com/odoo/odoo/blob/765174be270813442df6c497456fe2864517da0b/addons/project/models/project_project.py#L209-L218 https://github.com/odoo/odoo/blob/765174be270813442df6c497456fe2864517da0b/odoo/models.py#L364-L377 Solution: Retrieve unreached milestones through their normal ordered search before grouping them per project. This preserves batched computation while ensuring that the selected record follows the established milestone order. opw-6496938 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#287810 Forward-Port-Of: odoo/odoo#285933
Fiscal positions are now sorted with a reliable fallback when records share the same priority. This prevents inconsistent tax/accounting rule selection after imports, helping businesses get repeatable accounting behavior.
Original PR description
The algorithm to find the right fiscal position works on top of deterministically ordered fiscal position records. This invariant is not enforced by the functional code. Importing data without explicit sequence number results in multiple records ending up with the same value in this column. Sorting by column 'sequence' is not good enough to have repetitive results in this case. The fiscal position algorithm can return a different record due to database implementation details. Adding field "id" to the default ordering ensures the order of fiscal position records remains deterministic. This is because insertion order is preserved and locked into order-preserving id-values when importing data. runbot-945738 Forward-Port-Of: odoo/odoo#289546 Forward-Port-Of: odoo/odoo#289242
The invoice sending wizard now correctly shows the template selector again. This lets users choose reminder templates when sending accounting documents, avoiding extra manual work or missed reminder messaging.
Original PR description
Currently the template selector is not displayed on the move send wizard. I.e. this makes it impossible to select the reminder templates. The issue is that the template selector widget uses a field that is not in the view. This is fixed in this commit by adding the field as invisible field to the view. task-None Forward-Port-Of: odoo/odoo#288464
FedEx shipping labels in ZPLII format now download with a printer-friendly .zpl file extension instead of being renamed by the browser as a text file. This prevents confusion and helps warehouse or shipping teams use downloaded labels directly with compatible label printers.
Original PR description
TL;DR When downloading a `.zplii` shipping label from the chatter on a Delivery Order (using FedEx), the browser automatically adds .txt to the end of the filename, saving it as `.zplii.txt` Step to…
TL;DR
When downloading a `.zplii` shipping label from the chatter on a Delivery Order
(using FedEx), the browser automatically adds .txt to the end of the filename,
saving it as `.zplii.txt`
Step to reproduce:
- install `delivery_fedex_rest` with demo
- open shipping method menu -> Fedex Us -> label format = `zplii` -> save
- create a SO, click on 'Add Shipping",
- select fedex as shipping method -> get rate -> add -> confirm SO
- go to delivery and validate
- notice, in thread, a attachment with ZPLII extension appears
- download (.txt is appended to file)
Issue:
- `fedex_rest_send_shipping` post message with documents with extension as
`fedex_rest_label_file_type` i.e. `ZPLII`
https://github.com/odoo/enterprise/blob/735490d7ba9bdc6d0df7a0bd07c0d4e36d1ed2d4/delivery_fedex_rest/models/delivery_fedex.py#L193-L195
- when the attachment is created for this document , it's mimetype is computed
to be `text/plain` from [guess_mimetype](https://github.com/odoo/odoo/blob/5de4a5f6caee09881e7e147062f9eab9f8916a61/odoo/tools/mimetypes.py#L192) method, as data is plain ASCII code
- moreover, when downloading, [_get_stream_from](https://github.com/odoo/odoo/blob/5de4a5f6caee09881e7e147062f9eab9f8916a61/odoo/addons/base/models/ir_binary.py#L89) tries to guess extension
using [get_extension](https://github.com/odoo/odoo/blob/5de4a5f6caee09881e7e147062f9eab9f8916a61/odoo/tools/mimetypes.py#L210) which return `None` as len('zplii') > 4, [see](https://github.com/odoo/odoo/blob/5de4a5f6caee09881e7e147062f9eab9f8916a61/odoo/tools/mimetypes.py#L221)
- finally, as we got `None`, and mimetype is `text/plain`, `.txt` is appended [here](https://github.com/odoo/odoo/blob/5de4a5f6caee09881e7e147062f9eab9f8916a61/odoo/addons/base/models/ir_binary.py#L149)
Fix:
- we use `zpl` as extension for file instead of `zplii` as there is not
difference between them from printing perspective
- as length of 'zpl' is <=4 , `get_extension` will considered it as valid
opw-6410968
Forward-Port-Of: odoo/enterprise#126620Guatemala electronic invoicing now applies fiscal positions in a consistent order. This prevents random invoice tax selection errors and makes related accounting tests and invoice behavior more reliable.
Original PR description
Test TestGtFlow.test_gt_edi_basic_invoice nondeterministically fails, but the reported error has always the same values. Turns out the code is picking the wrong fiscal position to apply taxes on the prices of the invoice. `res.partner._get_fiscal_position()` searches auto_apply fiscal positions without explicit order, so it relies on the model's default order-by sequence. `account.fiscal.position-gt.csv` carries two records into the database without sequence number, so the order they are returned in is nondeterministic. The resultset is afterwards stable sorted (no tie-breaker between equal sequence numbers) and filtered, so the wrong/unexpected tax can be applied randomly. Explicit sequence numbers are added to account.fiscal.position-gt.csv so the fiscal positions are always returned in-order (domestic first). This approach matches the convention of the other fiscal-position CSVs. runbot-945738 Forward-Port-Of: odoo/enterprise#132377 Forward-Port-Of: odoo/enterprise#131587
This fixes an issue where access rules created through Odoo Studio were incorrectly treated as read-only. Businesses using Studio can now manage these permissions as expected, reducing friction when configuring custom apps and security settings.
Original PR description
task-6481613 Forward-Port-Of: odoo/enterprise#132330
Vendor bill users can now search purchase order lines using the related purchase order name, not just the line description. This makes it easier to select the right purchase order line when entering vendor bills and reduces manual lookup work.
Original PR description
Issue: ------------------------------------- When creating a vendor bill, the Purchase Order Line field on the bill line allows selecting a purchase order line. However, the search only matches the…
Issue: ------------------------------------- When creating a vendor bill, the Purchase Order Line field on the bill line allows selecting a purchase order line. However, the search only matches the POL name and does not allow searching by the purchase order name. Steps to reproduce: ------------------------------------- 1. Install the `purchase` module. 2. Go to Vendor Bills, click New, and select a vendor. 3. Add the Purchase Order field to the bill line using the optional fields. 4. Click Add a line and open the Purchase Order selection. 5. Try to search for the line using the purchase order name. The purchase order line cannot be found. Cause of the issue: ------------------------------------- The `purchase.order.line` model does not define `_rec_names_search`, so the record search only considers the purchase order line's `name` field. Solution: ------------------------------------- Define `_rec_names_search` with both `name` and `order_id` so that POLs can also be searched using their related purchase order name. Forward-Port-Of: odoo/odoo#288541
Creating a Saudi Arabia contact and choosing Tax Identification Number no longer causes an error when no VAT number has been entered. The system now simply leaves the Saudi TIN blank in that case, allowing users to continue creating or editing contacts normally.
Original PR description
## Steps to Reproduce: - Install the `l10n_sa` and `contacts` modules. - Create a new contact and set the country to **Saudi Arabia**. - Click the "**+**" sign next to the TIN field. - Select "**Tax Identification Number**". ## Error: `TypeError: 'NoneType' object is not subscriptable` ## Cause: The onchange method tries to extract the SA TIN from the VAT even when the VAT is not set. This causes an error when slicing the None value. ## Fix: Skip populating the SA TIN when the VAT is not set. sentry-7716910106 Forward-Port-Of: odoo/odoo#287217
The Indian localization settings now require the GST registration type only when the selected company country is India. This avoids unnecessary setup blockers for companies using other localizations while keeping Indian compliance requirements intact.
Original PR description
add condition only required when country is India --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#289610
Time off warning messages now show remaining allocation balances using the correct unit from the time off type, rather than the unit used in an individual request. This prevents confusing or inconsistent balance information for employees and HR users when requests and allocations use different time units.
Original PR description
When the unit of measure of a time off type doesn't match the unit of a request -approved and based on an allocation-, the time remaining on the allocation incorrectly holds the unit of the request rather than the time-off type. It thus displays inconsistent information. The dependency of the computation is now set to `work_entry_type_id.unit_of_measure` rather than `work_entry_type_request_unit` to correctly reflect the remaining duration of the allocated time. task-id: 6545527 Forward-Port-Of: odoo/odoo#289226
This fixes remaining references to outdated leave time codes after a prior naming update. It helps ensure HR leave data continues to match the expected Partena payroll format and avoids inconsistencies in related work entry records.
Original PR description
Follow-up of the renaming of the time type codes to the Partena format: some references to the old codes were left behind. Forward-Port-Of: odoo/odoo#289128
Employees requesting a shift swap in Field Service Planning now trigger the expected replacement request notification. This ensures managers and relevant staff are informed promptly, avoiding missed staffing changes caused by the previous detection logic.
Original PR description
Post the replacement request notification when an employee requests to switch their shift. The previous logic checked `request_to_switch`, which is now a computed field and is not available in `vals`. Use the `switch_employee_ids` update to trigger the notification instead. Forward-Port-Of: odoo/enterprise#132140
This fixes remaining Belgian payroll references that still used outdated time type codes after a prior rename to the Partena format. The correction helps keep payroll calculations, leave handling, overtime, and declaration validations aligned with the updated coding standard.
Original PR description
Follow-up of the renaming of the time type codes to the Partena format: some references to the old codes were left behind. Forward-Port-Of: odoo/enterprise#132118
This fixes where the UrbanPiper product list view is shown by removing a setting that made it appear in unintended areas. Business users should see a cleaner, more predictable product management experience without unrelated UrbanPiper views showing up elsewhere.
Original PR description
Remove the priority from the UrbanPiper product list view, which causes the view to appear in unintended places. Task-6455770 Forward-Port-Of: odoo/enterprise#132350
Sales orders now prevent users from changing quantities on optional Services and Materials upsell lines. This keeps optional upsell items aligned with their intended behavior and avoids incorrect ordered quantities when lines are added at the end of an order.
Original PR description
When the last section in a sale order is optional, adding a line from the Services and Materials view appends it at the end of the order. This allows users to edit the ordered quantity of the newly added upsell line, even though upsell lines should not have an ordered quantity. Prevent editing the quantity of optional upsell lines. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#289630
The intercompany comparison report now hides tax lines by default, reducing noise when teams reconcile balances between companies. Users can still choose to show those lines, and their preference continues to be saved across reloads.
Original PR description
The interco comparison report lists the tax lines of the intercompany moves along with their base lines, which is noise when reconciling balances between companies: the counterpart of a tax line is not booked in the other company. The filter hiding them now defaults to on. Only the default changes, so a user who wants to see those lines can still untick it, and the choice is kept across reloads as before. task-6589446 Forward-Port-Of: odoo/enterprise#132428
This fixes missing add and remove icons in customer address forms after the country is changed. Users can continue managing additional identifiers without confusion or broken-looking form controls.
Original PR description
Changing the country of an address rebuilds the additional identifier block in JavaScript, which still used Font Awesome classes for the "Add identifier" and remove icons. Font Awesome is no longer loaded on the frontend, so both icons vanished after any country change while the server-rendered form showed them. task-none Forward-Port-Of: odoo/odoo#289390
The Belgian payroll setup no longer includes the separate “Remuneration” salary rule category, which could be confused with “Remuneration Base.” This simplifies payroll configuration and reduces the risk of selecting or reporting against the wrong category, while related payroll and accounting test data has been updated accordingly.
Original PR description
There exists 2 salary rule categories that could be easily mixed up: - Remuneration - Remuneration Base This commits remove the 'Remuneration' category task: 6531651
This change removes an outdated payroll process for reporting negative net amounts, now that the newer net amount recovery approach is in place. It helps keep payroll logic simpler and reduces the chance of confusion from maintaining two overlapping flows.
Original PR description
After development of Net Amount to recover from [task-6413612](https://www.odoo.com/odoo/project/1251/tasks/6413612), we are no longer need negative_net_to_report anymore. This PR expected to remove all the old methods and fields related to the old `negative_net_to_report`. task-6484528