Tuesday, September 22, 2026
135 changes · master
Security fixes and vulnerability patches
This update keeps an internal Colombian electronic invoicing status calculation from being accessed through external integration channels. It reduces unintended exposure while preserving the same invoice status behavior for users.
Original PR description
- Make the EDI states compute method private to avoid exposing it through XML-RPC. - Rename `compute_l10n_co_edi_states` to `_compute_l10n_co_edi_states` and update its field references accordingly. Commit cherry-picked from https://github.com/odoo/enterprise/pull/131963 to continue that part of the fw-port. Forward-Port-Of: odoo/enterprise#132381
This update restores user validation for IoT websocket requests, matching the previous expected behavior. It helps ensure IoT communications are only handled for appropriate users, reducing the risk of unauthorized access or incorrect device interactions.
Original PR description
Restore to pre 19.0 behaviour by checking user. Forward-Port-Of: odoo/enterprise#132399 Forward-Port-Of: odoo/enterprise#132098
New functionality added to Odoo
Swiss payroll now supports special daily allowance entries for employers who guarantee an employee's usual net pay during events such as sickness, accident, maternity, military service, disability, or loss of earnings. When used, the payslip automatically calculates the employer adjustment needed so the employee receives the same net amount while keeping the related accounting consistent.
Original PR description
Daily allowances paid by an insurance (sickness, accident, maternity, military service, disability, loss of earnings) are entered as third party payments: the automatic 2050 line deducts them from…
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
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
Daily allowances paid by an insurance (sickness, accident, maternity, military service, disability, loss of earnings) are entered as third party payments: the automatic 2050 line deducts them from the payslip so the employee is not paid twice, and takes them out of the insurance bases. Because that insurance money is free of social contributions, the deductions no longer match a normal month and the final net drifts away from what the employee normally receives. Some employers promise the employee the exact same net as if nothing had happened. This commit adds a "(Net compensation)" variant of each daily allowance wage type to express that promise: when one of them is used, the payslip computes wage type 4900 (Net/Gross compensation) on its own, with the amount that brings the final net back to exactly what it would be without the allowance lines. The employer takes over, or gets back, the whole difference in contributions and source tax. There is no direct formula for that amount, since the 4900 line changes its own deductions (source tax brackets, insurance ceilings, 5 cents rounding). The payslip is therefore recomputed a few times with different amounts until the net matches, each attempt running inside a database savepoint that is rolled back afterwards, so nothing of those attempts is kept. A manual 4900 input keeps priority over the automatic computation, the same way a manual 2050 input does. The new wage types get the same accounting mapping as their normal counterparts. Forward-Port-Of: odoo/enterprise#128243
Adds reporting for Belgian Pillar 3 mobility budgets across rolling 12-month periods, helping payroll teams track employee budget usage beyond a single year. This improves compliance visibility and makes it easier to manage mobility budget balances and related payroll processing.
Original PR description
Implements a reporting system for Belgian mobility budgets (Pillar 3), handling rolling 12-month cycles. Task: 4680555
This update adds automated tests for the intercompany comparison report to help ensure accounting comparisons remain reliable. It also includes several small fixes and maintenance updates across business apps, reducing errors in payroll, planning, manufacturing, appointments, and document workflows.
Original PR description
Adding tests for interco comparison report. No Community changes - Task : https://www.odoo.com/odoo/project/967/tasks/6567355
A new Indirect Cash Flow Statement report has been added to help businesses analyze cash movements using the indirect method. This gives finance teams another standard reporting view for understanding operating cash flow and supporting financial review processes.
Original PR description
Adding a new report: The Indirect Cash Flow Statement report. task-5151878
Marketing campaign users can now open a settings view from the Global Reply Path node to control reply-related campaign behavior. This makes it easier to decide whether the main automation flow should stop when a participant responds through channels such as email, SMS, or WhatsApp.
Original PR description
This PR introduces a new configuration view accessible via the "Global Reply Path" node. This allows users to manage campaign settings and specify if the main workflow should stop upon receiving a participant reply (e.g., via Email, SMS, or WhatsApp). Task-6559148 Forward-Port-Of: odoo/enterprise#132007
User and contact access status is now recalculated in bulk instead of one record at a time. This reduces memory usage and speeds up group and permission changes, especially on large databases.
Original PR description
Recomputing `res.users.share` and `res.partner.partner_share` through standard ORM recordsets during group structure or implication changes causes high memory overhead and O(N) performance bottlenecks. This commit completes the recomputation by executing set-based SQL updates: - Update `res_users.share` directly using `_get_internal_group_ids()`. - Update `res_partner.partner_share` based on linked non-share users. - Invalidate the ORM model cache for `share` and `partner_share` to ensure environment consistency. This avoids memory cache spikes and speeds up group assignment operations. Forward-Port-Of: odoo/odoo#289571
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
Marketing automation webhooks are now easier to configure and test, with clearer examples, more helpful error messages, and better log details. The update also fixes a dialog issue that could block users from opening records or changing views after checking webhook logs.
Original PR description
Testing the webhook feature has revealed a number of pitfalls and gotchas in the way it's presented to the user. As such, we want to improve helpers and error messages to make the feature easier to understand and use. This commit makes the following changes to marketing campaign webhooks: - Clarify webhook helper labels by making them into valid JSON objects - Webhook routes are now properly defined as json2 - Through the test URL, error messages will invite users to check for malformed JSON and argument presence - Webhook URL now has the value of the test route when not in Running state - If logging is enabled, logs now include IDs of fetched records In addition, we fix a bug where consulting webhook logs would keep a "ghost dialog" open that would prevent opening records or switching view modes. task-6580774 Forward-Port-Of: odoo/enterprise#131707
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
This update refreshes PayPal live environment identifiers used during payment onboarding and processing. It helps ensure merchants connecting PayPal in Odoo use the correct production partner and client configuration, reducing setup issues for live payments.
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#289590
Users can now manage IAP-related settings, credit purchases, low-balance warnings, auto-refill, and SMS-related options from a single IAP page. This reduces settings clutter and makes it easier for businesses to control paid Odoo services in one place.
Original PR description
See commit Task: https://www.odoo.com/odoo/967/tasks/6128821 Community: https://github.com/odoo/odoo/pull/269021 Enterprise: https://github.com/odoo/enterprise/pull/119818 Upgrade: https://github.com/odoo/upgrade/pull/10439 IAP: https://github.com/odoo/iap-apps/pull/1309 Internal: https://github.com/odoo/internal/pull/3954
Dark mode colors have been refined across several Odoo apps to look more consistent and easier to read. Subtle gradients return where helpful, while problematic backgrounds are removed or corrected, including more accurate time-off card coloring from configuration settings.
Original PR description
This PR adjusts certain elements of dark mode: - It updates the dark color variables that were "hardcoded" - The gradient has been reintroduced more subtly; however, it was removed in certain cases where it was unnecessary or problematic. - Certain colors have been corrected to ensure better compatibility with dark mode. It also changes the background color assignment for time-off cards, which should actually use the color defined in the configurations. *: account, api_doc, hr_holidays, html_builder, html_editor, mail, mass_mailing, sale, spreadsheet, stock task-6522638 ent-PR: https://github.com/odoo/enterprise/pull/129944 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#285859
Users can now manage IAP credits, balance alerts, and auto-refill from one dedicated IAP page instead of scattered settings. This simplifies administration and reduces clutter in app configuration screens for services such as document extraction, Sign, and VoIP.
Original PR description
See commit Task: https://www.odoo.com/odoo/967/tasks/6128821 Community: https://github.com/odoo/odoo/pull/269021 Enterprise: https://github.com/odoo/enterprise/pull/119818 Upgrade: https://github.com/odoo/upgrade/pull/10439 IAP: https://github.com/odoo/iap-apps/pull/1309 Internal: https://github.com/odoo/internal/pull/3954
Dark mode styling has been refined across VoIP, Enterprise web screens, and Studio to improve contrast and make colors easier to distinguish. Gradients and tag or badge colors were adjusted so the interface remains clear and visually consistent in low-light themes.
Original PR description
This PR adjusts certain elements of dark mode: - The gray palette has been adjusted, with particular attention paid to the initial variations to ensure sufficient contrast between the different shades. - The gradient has been reintroduced more subtly; however, it was removed in certain cases where it was unnecessary or problematic. - Certain colors have been corrected to ensure better compatibility with dark mode. *: web_enterprise, web_studio task-6522638 commu-PR: https://github.com/odoo/odoo/pull/285859 Forward-Port-Of: odoo/enterprise#129944
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
The self-invoicing validation screen has been simplified with a cleaner layout and easier access to the sign-in action from the header. This makes the checkout invoicing flow clearer for customers and staff using localized Point of Sale setups in Argentina, Malaysia, and Peru.
Original PR description
`l10n_ar_pos`, `l10n_my_edi_pos`, `l10n_pe_pos` In this commit: = - Simplify the self-invoicing validation screen by improving the layout, moving the sign-in action to the header. Related: = - task: 6366362 - enterprise: https://github.com/odoo/enterprise/pull/125687
Indonesian QRIS payment credentials are now easier to find in a dedicated Payment QR Settings tab, with a direct link to relevant documentation. The shared company QR setting also makes the setup more consistent across accounting and localization features.
Original PR description
In this PR: - Move the company_qr_code related field from account_qr_code_emv to account, which already defines res.company.qr_code. - Move the QRIS credentials to a Payment QR Settings tab and add a link to the Indonesian localization documentation. Upgrade PR: https://github.com/odoo/upgrade/pull/11327 task-6518698
The Ecuador POS self-invoicing validation screen has been simplified with a clearer layout. Moving the sign-in action to the header makes the flow easier for users to understand and complete.
Original PR description
In this commit: = - Simplify the self-invoicing validation screen by improving the layout, moving the sign-in action to the header. Related: = - task: 6366362 - community: https://github.com/odoo/odoo/pull/278653
The employee referral app has been visually refreshed with updated illustrations, backgrounds, and reward images. It also fixes small navigation and visibility issues, making the referral dashboard and job search areas clearer and more polished for users.
Original PR description
This PR is a quick refresh of the now very outdated hr_referral. **llustrations** New characters and background illustrations New rewards pictures **CSS cleanup** Replaced most of the custom SCSS with Bootstrap/Odoo utility classes in the templates. Dropped hardcoded colors in favor of theme variables where possible. **Fixes** The "Back to" breadcrumb showed "Unnamed" when leaving the dashboard — missing displayName has been added. Job Positions' search panel was invisible over the custom company background — added bg-view. Onboarding image fields in the backend were invisible since adding a white background to the field. task-6573529 Forward-Port-Of: odoo/enterprise#131522
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 spreadsheet engine has been updated to a newer version, bringing internal improvements that support a more reliable and maintainable spreadsheet experience. This also includes updates to how spreadsheet notifications and shared spreadsheet components are handled, helping keep dashboards and spreadsheet actions stable as the product evolves.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/b6b207303a [REL] 20.1.0-alpha.3 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/b6b207303a [REL] 20.1.0-alpha.3 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/b051f3ac9c [REF] spreadsheet: add `NotificationPlugin` [Task: 6542121](https://www.odoo.com/odoo/2328/tasks/6542121) https://github.com/odoo/o-spreadsheet/commit/4858a3a72d [REF] spreadsheet: Add `SpreadsheetActionEnv` [Task: 6542121](https://www.odoo.com/odoo/2328/tasks/6542121) https://github.com/odoo/o-spreadsheet/commit/0e25178ba3 [REF] spreadsheet: Add `OSComponent` [Task: 6542121](https://www.odoo.com/odoo/2328/tasks/6542121) https://github.com/odoo/o-spreadsheet/commit/27cc52d306 [FIX] rolldown: prevent const replacement in bundle [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> Co-authored-by: Anthony Hendrickx (anhe) <anhe@odoo.com> Co-authored-by: Alexis Lacroix (laa) <laa@odoo.com> Co-authored-by: Lucas Lefèvre (lul) <lul@odoo.com> Co-authored-by: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya (rmbh) <rmbh@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@odoo.com> Co-authored-by: Rémi Rahir (rar) <rar@odoo.com> Co-authored-by: Pierre Rousseau (pro) <pro@odoo.com> Co-authored-by: Vincent Schippefilt (vsc) <vsc@odoo.com> Co-authored-by: Marceline Thomas (matho) <matho@odoo.com>
Manufacturing work order cards now show the product and quantity being made, helping teams quickly see what is being produced. Scheduling defaults now better use available buffer time, and delayed draft manufacturing orders are included correctly in delayed production views.
Original PR description
The workorder kanban now displays the products and quantities being manufactured for a certain workorder instead of the workorder name. This conveys more useful information to the user since they want to know what is actually being produced. Additionally the auto rescheduling default is now set to use buffer allowing delayed tasks to fill buffer space. This commit also fixes a bug where manufacturing orders in draft state and past deadline were not displayed when applying the "Delayed Productions" filter. **Enterprise PR:** odoo/enterprise#130960 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#287412
Workorder planning cards now show the product being manufactured and the quantity, helping teams quickly see what is being produced. Scheduling behavior is also improved by using buffer time by default, and delayed draft manufacturing orders are now included in the delayed productions filter.
Original PR description
The workorder kanban now displays the products and quantities being manufactured for a certain workorder instead of the workorder name. This conveys more useful information to the user since they want to know what is actually being produced. Additionally the auto rescheduling default is now set to use buffer allowing delayed tasks to fill buffe> This commit also fixes a bug where manufacturing orders in draft state and past deadline were not displayed when applying the "Delayed Productions" filter. **Community PR:** odoo/odoo#287412 Forward-Port-Of: odoo/enterprise#130960
Employee departure records will no longer automatically set an archive action date based on the departure date. This reduces the risk of employees being archived unintentionally and gives users more explicit control over the process.
Original PR description
[IMP] hr_employee_departure: default computed value for action_date set to empty Automatic computed value for action_date implies automatically archiving by default. This can be disturbing to users and prone to errors. This field was computed with two outcomes: - If no value yet: computed to the first day of the month following departure_date - If value set already: ignore and do not overwrite Since the first case needs to be removed, the second one doesn't make sense anymore as it doesn't need to be compute nor re-computed. task-6526610 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Users will now see a persistent notification when Odoo's IAP service is down. This makes service interruptions clearer, reducing confusion when paid or connected services cannot be reached.
Original PR description
We wanted to let the user know when the IAP server is down with a sticky notification. Task-6570098 Forward-Port-Of: odoo/odoo#289599 Forward-Port-Of: odoo/odoo#288098
Invoice forms now keep the amount due in sync with the invoice total even before the user saves changes. Applying outstanding credit also saves pending invoice line edits first, preventing unsaved lines from disappearing.
Original PR description
Before this commit, the account.move amount due field would only update on record saving (as it depended on line_ids). This caused a temporary out of sync situation between the total and the amount due on the move form view. This commit ensures that the amount due is computed even before saving the record so that out-of-sync situation is avoided. It also solves the following bug: Repro steps: 1) Create a new invoice 2) Add a customer and save the record 3) Add some invoice lines 4) without saving, add a payment from the outstanding credit Issue: The added (unsaved) invoice lines are removed Solution: This commit forces a record save before assigning outstanding credit task-6534794 Forward-Port-Of: odoo/odoo#288894
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
The Time Off Gantt view now includes overtime hours when showing worked hour totals. This gives payroll and HR teams a more accurate view of employee time, reducing confusion when reviewing schedules and pay-related time balances.
Original PR description
The number of hours displayed in the Time Off gantt view was not reflecting the overtime hours into account. It was added to the counter the hours from the category 'EXTRA_HOURS' (previously 'Added to Monthly Pay'). task-6528360
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 accounting tags that prepare Odoo for a new Indirect Cash Flow Statement report. These tags help classify accounts consistently so future cash flow reporting can be generated more accurately across accounting setups.
Original PR description
Add some accounting tags that will be used in the new Indirect Cash Flow Statement report. task-5151878 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
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.
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
Fixes mobile display issues in the customer portal so reviews have proper spacing and delivered sale orders keep return actions accessible. This improves the mobile experience for customers viewing products, courses, and orders.
Original PR description
Before this commit, the reviews block on the product and course pages was pulled to the left / missing some padding. The chatter is shifted to compensate for the spacing it puts around its own content, but the reviews layout has no such spacing, so there was nothing to compensate. On the sale order, the return button was also out of reach: the sidebar is hidden on mobile and its actions moved to a fixed bottom bar, but the return stayed behind. That bar only showed up when the order could be signed, paid or reordered, so without eCommerce a delivered order had no bar at all. This commit applies the shift only when the reviews layout is off, and contributes the return to the bar, which is now also displayed when a return is possible. It also aligns the reorder icon with the sidebar one. task-6590673 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#289769
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
Website editors now correctly see options to update or remove the theme already in use, instead of being prompted to apply it again. This prevents confusion and restores the intended theme management actions for current website themes.
Original PR description
Steps to reproduce: - Apply a theme on a website, for example Bistro - Enter website edit mode and open the Theme tab - Click Switch Theme - Hover the card of Bistro (the theme currently in use) -…
Steps to reproduce: - Apply a theme on a website, for example Bistro - Enter website edit mode and open the Theme tab - Click Switch Theme - Hover the card of Bistro (the theme currently in use) - "Use this theme" button appears like every other card - It should show "Update theme" and "Remove theme" instead Since [1], `self.env.website` only reads `website_id` from the context, and that key is stripped on a non-website route, where the resolved website is moved to `host_id` instead. The theme kanban is read through a plain ORM call, so `_compute_is_installed_on_current_website` resolved no website and no card was ever flagged as the one in use. This commit falls back on `host_id` to resolve the current website. `button_refresh_theme` and `button_remove_theme` get the same fallback: they resolved the website the same way and acted on an empty one, which went unnoticed only because the buttons triggering them were never displayed. task-6575727 [1]: https://github.com/odoo/odoo/commit/9d97e0e919a953e4f86e42e32ca24d9790840f68 Forward-Port-Of: odoo/odoo#288383
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 fix ensures Peruvian exchange rates imported through SUNAT are dated correctly so Odoo uses the same official rate expected by SUNAT. It prevents new daily rates from being mismatched after a recent exchange-rate handling change, reducing reporting and compliance discrepancies for Peru localization users.
Original PR description
In this commit https://github.com/odoo/odoo/pull/231948 the base functionality of exchange rate fetching was changed in order to have a consistent exchange rate value per day. The problem is that in l10n_pe, SUNAT already does this, setting each day's official exchange rate to be the closing rate of the previous day. Because SUNAT expects the exchange rate being sent to it to be the same as the one generated in the morning, the new logic is defaulting to a mismatched rate instead. This commit changes how new currency rates are stored through SUNAT by dating them one day in the past to align with the new architecture. This will not realign existing currency rates that do not work with the change. This is a mirror of a similar adjustment that was made for Banxico in Mexico here: https://github.com/odoo/enterprise/pull/118999 opw-6468065 Forward-Port-Of: odoo/enterprise#131483
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
Odoo now keeps ISC tax amounts out of the taxable base columns in Peruvian PLE sales and purchase ledgers. This prevents ISC from being reported twice and keeps ledger values aligned with the electronic invoice sent to SUNAT.
Original PR description
When a tax affects the base of the subsequent ones — `include_base_amount`, which is how the ISC is set up in Peru — Odoo links the tax line it generates to those subsequent taxes, so the ISC tax…
When a tax affects the base of the subsequent ones — `include_base_amount`, which is how the ISC is set up in Peru — Odoo links the tax line it generates to those subsequent taxes, so the ISC tax line ends up carrying the IGV in its `tax_ids`. The PLE ledgers build their base columns by summing every move line related to a given tax group, so that ISC tax line was added to `base_igv` as well and the ISC ended up reported twice: once inside the taxable base and once in its own column. A line of 1000.00 with 100.00 of ISC and 198.00 of IGV was declared with a base of 1100.00 instead of 1000.00. `l10n_pe_edi` already subtracts the ISC from the `cbc:TaxableAmount` of the CPE sent to SUNAT, so the electronic invoice and the ledger disagreed on the very same document. ### What changed The base taxes are now joined only for base lines, instead of repeating the condition on each of the twelve `base_*` columns. Besides keeping tax lines out of the base columns, this also stops a tax line from being counted once per subsequent tax: an ISC followed by both the IGV and the ICBPER produced two rows in the join, and its own column was reported twice. ### Scope `_get_ple_report_data` is shared, so this covers the sales ledger 14.1 and the purchase ledgers 8.1 and 8.2. A configuration where no tax affects the base of a later one is unaffected: the standard Peruvian chart template has no purchase ISC, so ordinary IGV-only purchases report exactly the same values as before. ### Tests - `test_sale_report_isc_base`: an ISC preceding the IGV, on an invoice and on a credit note; the base column excludes the ISC. - `test_sale_report_isc_reported_once`: an ISC followed by the IGV and the ICBPER is reported once. Both fail without the fix. Supersedes odoo/enterprise#128300, which targeted 19.0. Forward-Port-Of: odoo/enterprise#132106 Forward-Port-Of: odoo/enterprise#131475
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
Fixes an issue where users could be blocked from completing a manufacturing order after generating a lot number and increasing the production quantity. This ensures valid production changes can be finished without an incorrect lot/serial number error.
Original PR description
Currently, when the user tries to produce a Manufacturing Order after generating a lot and increasing the quantity, they get a user error stating that a lot must be assigned. ## Steps to produce: -…
Currently, when the user tries to produce a Manufacturing Order after generating a lot and increasing the quantity, they get a user error stating that a lot must be assigned. ## Steps to produce: - Install Manufacturing - Go to the setting enable Lots & Serial Numbers and Storage Locations - Create a product 'Soda can' which is tracked by lots - Create a bill of material for Soda can with component as 'Metal sheet' - Create a storage location called 'Fridge' with parent location WH/Stock - Create a Putaway rule for the Soda can to be stored in the fridge when it arrives in WH/Stock. - Create and confirm a Manufacturing Order for soda can - Click 'Generate Lot' - Increase the total quantity to be produced from 1 -> 2 - Click 'Produce All' ## Observed Behaviour: ``` Invalid Operation: You need to supply a Lot/Serial Number for product: - Soda can ``` ## Root cause: When the user confirms the Manufacturing Order, `_apply_putaway_strategy` is called through: ``action_confirm -> _action_assign -> _apply_putaway_strategy`` This happens for both finished-product move lines and component-product move lines. It updates the finished product move lines' destination location to `WH/Stock/Fridge` at: https://github.com/odoo/odoo/blob/fd06c4df5889e23cfb701c12d743b5652141a111/addons/stock/models/stock_move_line.py#L288-L292 However, the `move_finished_ids` destination location remains` WH/Stock`. After the user generates a lot and increases the production quantity using the wizard, `change_prod_qty()` updates the finished move's demand and re-reserves it through `_update_finished_moves()`: https://github.com/odoo/odoo/blob/f586c1dad0b9a7653c45d1f82a9c3989a287c641/addons/mrp/wizard/change_production_qty.py#L77 This calls `_action_assign` on the finished move: https://github.com/odoo/odoo/blob/f586c1dad0b9a7653c45d1f82a9c3989a287c641/addons/mrp/wizard/change_production_qty.py#L49 Within `_action_assign` because finished moves originate from the production location, they bypass the normal reservation logic at: https://github.com/odoo/odoo/blob/708e5ebcd8b3338d3ce2c092aafadfe0f941aa56/addons/stock/models/stock_move.py#L2086 So `_action_assign() `then tries to reuse an existing move line. However, it only searches for move lines whose `location_dest_id` matches the move's destination location (WH/Stock): https://github.com/odoo/odoo/blob/708e5ebcd8b3338d3ce2c092aafadfe0f941aa56/addons/stock/models/stock_move.py#L2108-L2117 The existing move line has `WH/Stock/Fridge` as its destination, so it does not match. As a result, a new move line is created for the finished move: https://github.com/odoo/odoo/blob/708e5ebcd8b3338d3ce2c092aafadfe0f941aa56/addons/stock/models/stock_move.py#L2182 The new move line gets the lot value from the Manufacturing Order: https://github.com/odoo/odoo/blob/f586c1dad0b9a7653c45d1f82a9c3989a287c641/addons/mrp/models/stock_move.py#L557 Later, when Produce All is triggered,` button_mark_done()` calls` _post_inventory()`: https://github.com/odoo/odoo/blob/708e5ebcd8b3338d3ce2c092aafadfe0f941aa56/addons/mrp/models/mrp_production.py#L2236 Because the finished move already has a `lot_id`, the condition below is not satisfied: https://github.com/odoo/odoo/blob/708e5ebcd8b3338d3ce2c092aafadfe0f941aa56/addons/mrp/models/mrp_production.py#L1929-L1933 Therefore, the `lot_id` is not assigned to the move line that was created earlier. When `button_mark_done()` validates the finished move lines, it finds that one move line has no lot assigned and raises an 'Invalid Operation' error. ## Solution: Allow the user to produce the Manufacturing Order after changing the quantity. Increasing the quantity is a valid operation, so the user should not be blocked from completing the production afterward. opw-6563498 Forward-Port-Of: odoo/odoo#289725 Forward-Port-Of: odoo/odoo#289171
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
Return-related screens now refresh properly after users complete return steps or save audit findings. This ensures check views, return cards, and chatter show the latest information without users needing to manually reload or risk seeing outdated status.
Original PR description
The action_return_refresh client action emits return_reload_model, which the return renderers listen to for reloading their views. However, the action and renderers use separate EventBus instances, so the notification never reaches those listeners. Use GlobalBusPlugin to share the bus between the action and renderers. This restores check, return card, and chatter updates after operations such as completing a return or saving audit findings, while following the OWL3 plugin migration. Forward-Port-Of: odoo/enterprise#132527
The US accounting tax report now includes taxes even when they do not have a jurisdiction type assigned. This prevents mismatches between tax reports and tax returns, helping businesses produce more accurate filing data.
Original PR description
Problem: Currently, the tax report for the US does not include taxes without a jurisdiction type. The issue is that when processing the tax return, the values between the report and the return are mismatched. task-6576448 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#289670
US tax reports now include taxes that do not have a jurisdiction type assigned. This prevents mismatches between tax reports and tax returns, helping businesses file more accurate tax information.
Original PR description
Problem: Currently, the tax report for the US does not include taxes without a jurisdiction type. The issue is that when processing the tax return, the values between the report and the return are mismatched. task-6576448 Forward-Port-Of: odoo/enterprise#131804
PINT electronic invoices are now generated through the newer UBL export path instead of the legacy BIS 2.0 process. This helps standardize invoice exports and supports the gradual removal of older e-invoicing logic, reducing future maintenance risk.
Original PR description
Problem --------- Currently, PINT uses the old BIS2.0 export. Objective --------- Decouple the exports as an effort to remove the old BIS implementation. no-task --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#289573 Forward-Port-Of: odoo/odoo#283585
Dropshipped purchases are now excluded from average cost calculations so they do not distort inventory valuation. This prevents misleading negative stock valuation balances when products are later sold from regular inventory.
Original PR description
stock_*: *stock_account, stock_dropshipping, stock_landed_costs, sale_stock_margin **Problem:** dropship moves impact the average cost of products which can lead to negative balance in stock…
stock_*: *stock_account, stock_dropshipping, stock_landed_costs, sale_stock_margin **Problem:** dropship moves impact the average cost of products which can lead to negative balance in stock valuation account **Steps to reproduce:** On a new db with no demo data and stock_dropshipping, sale_management and accountant module installed (bug also reproducible in runbot with same steps, but it's easier to see the negative impact on accounting on a new db) : 1) enable dropshipping 2) create a storable product with average perpetual category 3) in the purchase tab set a vendor with a price of 10 4) in the inventory tab select the dropship route 5) create PO for 1 unit @ 5, validate receipt and confirm bill 6) confirm a SO for 1 unit of the product 7) confirm linked PO and validate dropship move 8) confirm invoice and vendor bill -> see how the standard price is now 7.5 9) remove dropship route from the inventory tab of the product 10) confirm a SO for 1 unit of the product 11) validate delivery and confirm invoice 12) open 'inventory valuation' view **Current behavior:** the initial balance of stock valuation is -2.5 **Expected behavior:** it should be 0 (there shouldn't be a negative initial balance if all invoices and bills are confirmed) **Cause of the issue:** The issue happens after step 8) The problem is that the dropship has an impact on the average price of the product but not on the accounting. Before the dropship we have 1 unit in stock @ 5 and the stock valuation account has a balance of 5 (from the bill), so all is good. The dropship then changes the standard price to 7.5. That's because currently, in _run_average_batch() the dropship move first impacts average cost like an incoming move with a value of 10 (at this point we have 1 move @ 10 and 1 @ 5 so average cost is 7.5) https://github.com/odoo/odoo/blob/bcaa8b6b00fa1f16513d680c5187fd424bc7cf8c/addons/stock_account/models/product.py#L493-L500 https://github.com/odoo/odoo/blob/bcaa8b6b00fa1f16513d680c5187fd424bc7cf8c/addons/stock_account/models/product.py#L505-L510 and then it impacts the value as a regular outgoing move (meaning it leaves the inventory at the average cost of 7.5) and does not impact the average cost (which is the basic behaviour of outgoing moves) https://github.com/odoo/odoo/blob/bcaa8b6b00fa1f16513d680c5187fd424bc7cf8c/addons/stock_account/models/product.py#L515-L517 https://github.com/odoo/odoo/blob/60b5b99d569dbe183ef9c980217ccfe9bf243756/addons/stock_account/models/product.py#L522 Therefore after step 8), the standard price is 7.5 and we have a unit in stock so, in the inventory valuation view the ending stock is 7.5$. But the dropship did not impact the stock valuation account so the initial balance is still 5$ and we have lines with credits and debits of 2.5$ in the the stock variation section. After steps 9 to 12, both the initial balance and ending stock decrease by 7.5 (which is expected), leading to a negative initial balance in stock valuation. **fix:** We don't take into account the stock move from dropships in the avco computation In master we also revert this commit https://github.com/odoo/odoo/commit/64163799f491f1f97c0448a4a703d27e2caf31de the stay consistent **tests:** The fix requires modifications in a few tests: - test_dropship_bill_standard_price_update checks that the bill of a dropship move impacts the standard price, so we delete this test - test_lot_normal_3, the asserts on the total_value still make sense but not those on standard_price - test_dropship_kit_bom_updates_component_standard_price test_average_cost_dropship_in_negative_quantity, test_out_move_validate_as_stock_user: standard price should not be impacted by dropship Task 6515358 Forward-Port-Of: odoo/odoo#287320 Forward-Port-Of: odoo/odoo#285576
This fix ensures manufacturing costs use stock movement data only from the current company. It prevents costs from another company being incorrectly applied when FIFO costing is used, improving accuracy in multi-company inventory valuation.
Original PR description
**Problem**: In a multi-company environment, while manufacturing a product, if the component of the product is visible for both company and there is no last_in stock move for the component in the current company, then the last_in stock move of the other company is used to compute the cost of the component. This only happens when the costing method of the product is FIFO **Steps to reproduce:** 1. Create company A and company B. 1. Create a product A and set FIFO costing method to it. 2. Make a purchase order of product A in company A and receive it. 3. Create a product B with product A as its BOM material. 4. Create a MO of product B in company B and produce it. 5. The unit cost of product A in company B is using the unit cost from the purchase order of product A in company A. **Fix**: Add a company domain to the last_in stock move search to prevent cross-company last_in stock move search. opw-6411216 Forward-Port-Of: odoo/odoo#289643 Forward-Port-Of: odoo/odoo#280074
This fix ensures customers browsing the online shop can open all visible product category links, even when some related categories are hidden from public users. It prevents dead links in the shop sidebar, improving navigation for logged-out visitors.
Original PR description
# How to reproduce - Create the following categories : - Category A - Category B, Child of Category A - Category X - Category Y, Child of Category X - Category Z, Child of Category X - Create a…
# How to reproduce - Create the following categories : - Category A - Category B, Child of Category A - Category X - Category Y, Child of Category X - Category Z, Child of Category X - Create a published product for category B & Z - Go to the Shop page - Enable the Sidebar Categories - Log out - Go to the Shop page # The issue The link for the Category Z is broken and clicking the Category does nothing. # Cause When rendering the recursive template for the categories : https://github.com/odoo/odoo/blob/8cefaf36e2b4ce6db869dba63874c933060b702b/addons/website_sale/templates/shop_page_templates.xml#L1291 https://github.com/odoo/odoo/blob/8cefaf36e2b4ce6db869dba63874c933060b702b/addons/website_sale/templates/shop_page_templates.xml#L1310 The rendering engine will fetch the values for the `website_url` field for every `child_id` of every Category because of the prefetch mechanism, even the one public users dont have access to : https://github.com/odoo/odoo/blob/ceae1f02580601bf179fc36e449112a88c3dff8d/addons/website_sale/security/ir.access.csv#L16 During the compute of that field, the records will be ordered in this way : 1) Category B => User has read access 2) Category Y => User does NOT have read access, because no product 3) Category Z => User has read access So an access error will be raised here for the 2nd Category : https://github.com/odoo/odoo/blob/ceae1f02580601bf179fc36e449112a88c3dff8d/addons/website_sale/models/product_public_category.py#L149 Which will be intercepted by the fallback of the getter, that retries the compute with only the first record. This will succeed because the user has access to that record : https://github.com/odoo/odoo/blob/ceae1f02580601bf179fc36e449112a88c3dff8d/odoo/orm/fields.py#L1827-L1828 The issue is that the call to `super()` at the start of the compute already assigned a value to all the records, so all Categories have a value in the cache for `website_url`, even after the fail of the compute : https://github.com/odoo/odoo/blob/8cefaf36e2b4ce6db869dba63874c933060b702b/addons/website/models/mixins.py#L255-L258 So when trying to access Category's Z `website_url`, we'll get '#', without any recomputation being done because of the cache value opw-6481175 Forward-Port-Of: odoo/odoo#284673
The Point of Sale now makes exceeded customer credit limits more visible. The customer button turns orange and always shows the warning icon, helping cashiers spot payment risk without hovering or relying on customer name length.
Original PR description
Before this commit, if the credit limit of a partner was exceeded in the pos, it was not clearly indicated. It was only visible if the user hover the partner button. Now the partner button is orange and the warning icon is displayed whatever the partner name length. Forward-Port-Of: odoo/enterprise#131601
Customer credit limit checks now count confirmed sales orders even when delivery has not happened yet. This helps businesses prevent customers from exceeding credit limits through orders that are committed but not yet invoiceable.
Original PR description
### Steps to reproduce Set a credit limit of 1.000 on a customer, then: 1. Create a Sale Order for a product with Invoice Policy on **Delivered Quantities**, over that amount → the warning shows.…
### Steps to reproduce
Set a credit limit of 1.000 on a customer, then:
1. Create a Sale Order for a product with Invoice Policy on **Delivered Quantities**, over that amount → the warning shows. Good.
2. Confirm it, and deliver nothing.
3. Create a second order for the same customer → the warning never shows, even though the customer is already over the limit.
### Solution
The ordered quantity is what the customer committed to, delivered or not. Using `qty_to_invoice` instead of `uom_qty_to_consider` or `qty_delivered`
Introducing invoice_status in sales domain for `_compute_credit_to_invoice`: `untaxed_amount_to_invoice` still follows the invoicing policy, while `amount_to_invoice` no longer does. On a confirmed order for a delivery-based product with nothing delivered:
```
line.untaxed_amount_to_invoice = 0 # still gated by qty_delivered
line.invoice_status = 'no'
order.amount_to_invoice = 2000 # fixed by this PR
```
The domain filters on the first one, so the order is dropped from the search before its amount is ever read and `credit_to_invoice` stays at 0.`'no'` is the stored marker for a confirmed line that is not invoiceable yet, which is exactly what the first clause misses.
ticket: [6480211](https://www.odoo.com/odoo/project/967/tasks/6480211)
Forward-Port-Of: odoo/odoo#289305
Forward-Port-Of: odoo/odoo#285578The 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
Users who type a date or date and time directly into a field and press Enter will now have that value saved correctly. This prevents silent data loss when updating date fields without opening the calendar picker.
Original PR description
Example of steps: - open any form view with a date field - navigate to this date field with tab - For example clicking on the previous field and pressing tab - type another date press enter (without…
Example of steps: - open any form view with a date field - navigate to this date field with tab - For example clicking on the previous field and pressing tab - type another date press enter (without opening the picker) - save => The change has not been saved. `onInputKeydown` closes the picker on Escape and on Enter the same way: by calling `saveAndClose()` directly, without first calling `updateValueFromInputs()` to parse the raw text typed in the input into the reactive `pickerProps.value`. This doesn't work when the calendar popover was never opened (i.e. the value was typed by hand instead of picked visually), `saveAndClose()` calls `apply()` directly, which only pushes `pickerProps.value` to `onApply`. Since that value was never refreshed from the input's text, `apply()` sees no change and silently returns without calling `onApply`, so the typed value is lost. Every other confirmation path (`onInputChange`, the popover's `onClose`, and `Ctrl+Enter`) already calls `updateValueFromInputs()` before proceeding, so plain Enter was the only path missing it. To fix this we call `updateValueFromInputs()` before `saveAndClose()` in the Enter/Escape case, like every other confirmation path already does. opw-6511435 Forward-Port-Of: odoo/odoo#286289 Forward-Port-Of: odoo/odoo#285963
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
Starting or joining a meeting now asks for microphone permission first when needed, so users can more easily join with audio only. This avoids confusion from camera-first prompts and makes the meeting entry flow better match common user behavior.
Original PR description
**Purpose of this PR:** Before this commit, starting or joining a meeting with both microphone and camera permissions pending opened the camera permission dialog, offering `"Use microphone and camera"` or `"Use Camera"`. This commit opens the microphone permission dialog in that case instead, offering `"Use microphone and camera"` or `"Use microphone"`, as joining with microphone only is more common than joining with camera only. Camera actions still keep the camera permission dialog. This commit also uses sentence case for permission dialog buttons. Related PR: odoo/enterprise#131553 task-6464811 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#282764
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
This fix restores the ability to group HR Gantt views by fields other than employees. Business users can again organize planning and time-off schedules in the way that best matches their workflow, improving visibility and reducing manual workarounds.
Original PR description
This PR brings back the "group by" functionality to all the HR gantt views. Making them go back to their default behavior when grouping by something else then just employees. task-6587751
When an event-related sales order is paid through Point of Sale, Odoo now asks for attendee details and records the attendance automatically. This removes the extra step of returning to the Sales app to confirm event registration, making POS settlement consistent with direct event ticket sales.
Original PR description
When we sell an event ticket on the POS, we directly ask for the registration details and automatically create the registration when the payment is complete. But if we create a SO for an event, and then try to settle it on the POS, the pos would carry out the payment without creating the attendance. So then we would need to go back to the SO on the Sale app and confirm attendance from there. Now settling a SO in the POS will have the same flow as selling an event ticket directly in the POS. So we'll ask for the registration data and confirm the attendance when the ticket is sold --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
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
Factur-X invoice exports now use the parent company or commercial partner name when an invoice address has no name of its own. This prevents required buyer name information from being omitted, reducing compliance failures when exchanging electronic invoices.
Original PR description
Description of the issue/feature this PR addresses: The Factur-X Refactoring (https://github.com/odoo/odoo/pull/284123) introduced an error that can result in the generated XMLs not being compliant…
Description of the issue/feature this PR addresses: The Factur-X Refactoring (https://github.com/odoo/odoo/pull/284123) introduced an error that can result in the generated XMLs not being compliant due to the partner name being missing (BT-44) Current behavior before PR: When a contact has an invoicing address without a name set, then the new Factur-X generation does not fall back to the parent name, leaving the corresponding XML entry empty, which is therefore pruned, leaving the Factur-X without a BT-44 and thus failing BR-07 Desired behavior after PR is merged: The new generation method uses the same data source and fallback method as the old Factur-X generator, pulling the `display_name` of the `commercial_partner_id` if the address doesn't have a `name`. This greatly reduces the chance of a generated Factur-X failing BR-07. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#289661 Forward-Port-Of: odoo/odoo#289498
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
This fixes Spanish TicketBAI/Batuz submissions for credit notes that include an equivalence surcharge. The surcharge percentage is now sent as a positive value, preventing tax agency rejection and allowing affected refunds to be reported correctly.
Original PR description
In credit notes, `TipoRecargoEquivalencia` was multiplied by the reversal sign, producing negative values (e.g. -1.40) that violate the Batuz `Tipo3.2Type` pattern and get rejected by the tax agency (`B4_2000001: cvc-pattern-valid`). Unlike `BaseImponible`/`CuotaImpuesto` (amounts that must be negative), `TipoRecargoEquivalencia` is a percentage and must stay positive, as `TipoImpositivo` does. Steps to reproduce: 1. Configure a Spanish company with TicketBAI (Bizkaia). 2. Create a credit note (out_refund) with an equivalence surcharge tax. 3. Send it to TicketBAI; the send fails with a schema validation error. Task: MT-15939 OPW: https://www.odoo.com/es_ES/my/tasks/6573801 @jco-odoo could you review? It's essential to be able to send to Tbai/Batuz with equivalence surcharge tax. Forward-Port-Of: odoo/odoo#289618
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
Fixes an issue where accordion sections added to default terms and conditions could break after saving. Businesses can now use richer page content in invoice terms without editor errors or damaged layout.
Original PR description
# How to reproduce - Go to Settings > Default Terms & Conditions > Preview - Open the editor - Add a Content Block - Add an Accordion in that Block - Save # The issue The accordion gets messed up and…
# How to reproduce - Go to Settings > Default Terms & Conditions > Preview - Open the editor - Add a Content Block - Add an Accordion in that Block - Save # The issue The accordion gets messed up and trying to add a new item to that accordion raises a traceback # Cause `invoice_terms_html` is an html field with some sanitization enabled : https://github.com/odoo/odoo/blob/c11ca6d10cac99b367078823dafef46808346267/addons/account/models/company.py#L172 This sanitization will remove the accordion snippet's buttons that controls the functionality of the snippet : https://github.com/odoo/odoo/blob/c11ca6d10cac99b367078823dafef46808346267/addons/website/views/snippets/s_accordion.xml#L9 This issue was already addressed by : https://github.com/odoo/odoo/commit/b6b4db5fb5690436a4284f6a22abf9f3b346a324 But it is not enough in the case of the accordion. The buttons will be removed by the lxml clean.Cleaner : https://github.com/odoo/odoo/blob/c11ca6d10cac99b367078823dafef46808346267/odoo/tools/mail.py#L364 # Proposed Solution Disable sanitization entirely, like for blog's content, which can also be edited in the website editor : https://github.com/odoo/odoo/blob/c11ca6d10cac99b367078823dafef46808346267/addons/website_blog/models/website_blog.py#L29 opw-6500378 Forward-Port-Of: odoo/odoo#285255
Backend Point of Sale refunds now apply the same quantity limits as the frontend, preventing users from refunding more items than were originally sold. This helps avoid incorrect refund amounts, inventory discrepancies, and accounting errors.
Original PR description
Currently, if you refund an order fro the backend it is possible to modify the qty as if to refund more than the original order qty. Steps to reproduce: ------------------- * Make an order from the…
Currently, if you refund an order fro the backend it is possible to modify the qty as if to refund more than the original order qty. Steps to reproduce: ------------------- * Make an order from the shop (1 product, qty 1) * Validate the order * Go backend * Find the order and select the refund button * Change qty from -1 to -3 * Save and continue the refund process > No problem refunding more than the original quantity Why the fix: ------------ In the frontend we cannot refund more than the original quantity, we assume the same should be in the backend process. The most simple way to do this is by doing a difference between the quantity from the original order and all the refund lines linked. From `self.refunded_orderline_id.refund_orderline_ids` we need to exclude the line that represents self as it holds the quantity before the onchange and we care about the quantity we're trying to write not the previous (allegedly correct). opw-6328635 Forward-Port-Of: odoo/odoo#287209 Forward-Port-Of: odoo/odoo#281405
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
Fixes Malaysian payroll calculations so SOCSO and Employment Insurance deductions are applied correctly and not counted twice. This helps payslips show the expected net salary and employer contribution amounts in line with official contribution rules.
Original PR description
There was a difference between the actual and expected NET. **Causes** - rules existed for both SOCSO Act 800 and EIS, but Act 800 seems to be the official name of the Employment Insurance System…
There was a difference between the actual and expected NET. **Causes** - rules existed for both SOCSO Act 800 and EIS, but Act 800 seems to be the official name of the Employment Insurance System (source: https://www.perkeso.gov.my/images/dokumen/Rate_of_Contribution_ACT_800.pdf). Keep the ACT 800 one as its matches the expected amount. - there was a double counting of the SOCSO employee contributions (4 and 800) , as `l10n_my_rule_socso_employee` (the sum of both) was added to the total deductions. **Change** Before: 3500/month wage results in a 3108 NET. <img width="1181" height="533" alt="before" src="https://github.com/user-attachments/assets/cdf4420f-e2cf-4dc7-9488-6bde3f1f9961" /> After: 3500/month wage results in a 3090.85 NET: - 6.90 SOCSO Act 800 Employee - 6.90 SOCSO Act 800 Employer - 17.25 SOCSO Act 4 Employee - 60.35 SOCSO Act 4 Employer Which seems consistent with online sources (https://payroll.my/) <img width="1181" height="425" alt="after" src="https://github.com/user-attachments/assets/7fb41186-dbb4-4d7a-ac9a-14fb56efc4bc" /> Other fix: while not affecting the calculation, 'SOCSO Employer Share' appeared as incorrect, the two rules SOCSO_800_EMPLR and SOCSO_4_EMPLR should have the same sign. opw-5976362 Forward-Port-Of: odoo/enterprise#131153 Forward-Port-Of: odoo/enterprise#118138
Reloading an Italian POS session now correctly restores the fiscal printer selection before checkout. This prevents the payment screen from failing after a browser refresh, helping store staff continue sales without interruption.
Original PR description
Steps to reproduce: - Set up an Italian fiscal printer; - Open a POS session; - Reload the browser page; - Create an order and proceed to the payment screen. **Issue**: The page fails to load, triggering an error in the console (`Cannot read properties of undefined (reading 'displayText')`), because the fiscal printer is not registered as the default printer following the page reload. **Solution**: Relocate the printer selection so it triggers on every POS reload rather than only during initial session creation. [opw-6499079](https://www.odoo.com/odoo/project/49/tasks/6499079) Forward-Port-Of: odoo/enterprise#129759
Employees without HR access can now see one-time work location updates in the calendar when those locations are shared through the sidebar. This makes calendar planning more accurate by showing exceptional work-from-home or office locations consistently with recurring locations.
Original PR description
**Steps to reproduce** - With a user having HR rights, create an exceptional work location for a user (click on the top bar of one of the days in the calendar, where work locations are displayed, and do not check "repeat every". - Open the calendar app with a user having no HR rights, in the sidebar, add the user with a non-recurrent work location. Notice that the work location is not visible, unlike recurring ones. **Cause** Recurring work locations are defined on the public employee (`*_location_id` type fields) and are readable by all users. Non-recurring work locations are `hr.employee.location` records and the `homeworking_own_rule` rule restricts read operations for non-HR users. opw-6190464 Forward-Port-Of: odoo/odoo#288438 Forward-Port-Of: odoo/odoo#266380
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
This fixes an issue in the HTML editor where Safari users could lose selected text without the replacement character being inserted. Editing notes and other rich text content in Safari is now more reliable and prevents confusing data entry behavior.
Original PR description
When using Safari, if the first character of the editable is selected and a character is pressed, the selection content is removed, but the character is not inserted. It seems that Safari does not trigger the actual `input` event, nor its native behavior, if the initial anchor node is detached from the DOM after `beforeinput`. This commit avoids this issue by preventing Safari from proceeding with the insertion right after the deletion by instead re-triggering the `insertText` command. Steps to reproduce: - Use Safari - Go to a To do note - Select the first word - Press a letter => The first word was deleted but the letter was not inserted. task-6445669 Forward-Port-Of: odoo/odoo#289225 Forward-Port-Of: odoo/odoo#281223
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
Users can now move a manufacturing order into progress even when the product quantity at its storage location is zero or negative. This removes an unnecessary blocker so production workflows can continue when stock levels are not yet available or recorded.
Original PR description
This PR removes the error that was raised when the user tries to set MO to progress while the available qty of the product at its store location is 0 or less. We allow the user now to do the set to progress without any blocking. Forward-Port-Of: odoo/odoo#289516
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#126620Irish balance sheet reports now place current-year profit or loss in the correct section only. This prevents the same invoice amount from being counted both as brought-forward profit and current-year profit, improving report accuracy for Irish accounting.
Original PR description
Scenario: - install l10n_ie and switch to a company with irish accounting - create and validate a 2025 customer invoice with one line and value 50 - go to the balance sheet report and check values of year 2025 Result: the 50 amount is present in both "H.V. Profit or loss brought forward" and "H.VI. Profit or loss for the financial year" while it should only be present in "H.VI." Cause: Start of december 2025 e699a14a1922d6b8a5bc6b88ad9c02a411e4b073 was merged that requires adding force_date_scope in some case. End of december 2025 597f25a4faff914504d1dfa021e9839e39ece937 was merged that added a new balance sheet report but didn't take into account the recent change for the force_date_scope parameter. Fix: add the missing force_date_scope parameters. opw-6425317 Forward-Port-Of: odoo/enterprise#129500
Guatemala 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
This fixes an error that could block users from confirming renewal or upsell quotations when the original subscription was cancelled and no longer had a recurring plan. The change adds a safety check so the process can continue without comparing against a missing invoice date.
Original PR description
## Steps to Reproduce: - Install the Subscriptions module with demo data. - Create a quotation containing a subscription product. - Set a recurring plan and confirm the quotation. - Create an upsell…
## Steps to Reproduce: - Install the Subscriptions module with demo data. - Create a quotation containing a subscription product. - Set a recurring plan and confirm the quotation. - Create an upsell quotation or a renewal quotation. - Cancel the original subscription. - Remove the recurring plan from the cancelled subscription. - Open either the upsell or renewal quotation and confirm it. ## Error: `TypeError - '>=' not supported between instances of 'datetime.date' and 'bool'` ## Cause: Since Commit https://github.com/odoo/enterprise/commit/315be581a4212b46191e0c4f82b02a2c3fde51dc#diff-07cf1dda5423f99452a763a54fb6e7fdbb861e19b1a9dca00cab093a832490a9, `plan_id` is no longer required when a subscription is in the cancelled state. During the confirmation of an upsell or renewal quotation, the parent subscription's next invoice date is used for several date validations. However, if the parent subscription is cancelled and its plan is removed, the `next_invoice_date` is computed as False. Comparing a date object with a boolean value leads to an error. ## Fix: This commit adds an extra check before using the next invoice date. sentry-7661150764 Forward-Port-Of: odoo/enterprise#132329 Forward-Port-Of: odoo/enterprise#128093
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
Belgian payroll now correctly applies the Scale 2 withholding tax calculation when an employee has a disabled spouse, regardless of the spouse's income status. This helps ensure affected employees have the proper tax withholding applied on their payslips.
Original PR description
Changed the qualifying conditions for Scale 1 and Scale 2 (Bareme I and II) to check the spouse disability status, so the employee with a disabled spouse qualifies for Scale 2 withholding tax computations regardless of income status of the spouse. task-6542651 Forward-Port-Of: odoo/enterprise#132115
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
Users can now click amounts in the aged receivable or payable reports when an "Open On" date is selected without seeing an error. This keeps report audit workflows working smoothly by opening the related journal items as expected.
Original PR description
Currently, an error occurs when a user clicks on a cell in the aged partner balance report. **Steps to Reproduce:** - Install the `account_reports` module. - Go to `Invoicing` > `Reporting` >…
Currently, an error occurs when a user clicks on a cell in the aged partner balance report. **Steps to Reproduce:** - Install the `account_reports` module. - Go to `Invoicing` > `Reporting` > `Partner Reports` > `Aged Receivable`. - Click on the `date filter`, select `Open On`, and set `any date`. - Click on any `amount` in the `Total Aged Receivable line`. `TypeError: the JSON object must be str, bytes or bytearray, not dict` After the [recent commit] that adds the context to the action, when preparing the action to open the journal items corresponding to the selected cell in the aged partner balance report, the context is added to the action [1]. When an "Open On" date is set, the code attempts to convert the context using json.loads() before adding the search_default_open_on key to it [2]. but, the context is already a dictionary, which raises the error [3]. This commit ensures that, since the action context is already a dictionary, the search_default_open_on key and its value are added directly to the context. [recent commit]: https://github.com/odoo/enterprise/commit/9678a1b987a5aa87922b72d972dd7f73a689afee [1]- https://github.com/odoo/enterprise/blob/8fceecea541564a9877babfc31b7e0bf896573a6/account_reports/models/account_aged_partner_balance.py#L357-L359 [2]- https://github.com/odoo/enterprise/blob/8fceecea541564a9877babfc31b7e0bf896573a6/account_reports/models/account_aged_partner_balance.py#L362 [3]- https://github.com/odoo/enterprise/blob/8fceecea541564a9877babfc31b7e0bf896573a6/account_reports/models/account_aged_partner_balance.py#L361 sentry-7685491449 Forward-Port-Of: odoo/enterprise#129142
The Timesheet Grid now only marks public holidays for the company currently being viewed. This prevents holidays from other companies from incorrectly greying out work days, helping teams enter timesheets against the right working calendar.
Original PR description
Issue: - Public holidays from other companies were incorrectly included in the Timesheet Grid view of the current company. As a result, days corresponding to those holidays appeared greyed out.…
Issue: - Public holidays from other companies were incorrectly included in the Timesheet Grid view of the current company. As a result, days corresponding to those holidays appeared greyed out. Cause: - The `grid_unavailability` method relies on the `_get_valid_work_intervals` function to fetch all unavailability data at once. When fetching data for multiple employees, this function also retrieves public holidays from all companies. Fix: - The method no longer uses the data returned by `_get_valid_work_intervals` for company unavailable days. Instead, it now always makes a separate, direct call via the `get_company_unavailable_dates()` function. This ensures that only holidays relevant to the current company are considered in the grid view. The company is also passed in the domain of `_work_intervals_batch`, which otherwise returns the leaves of every company when no resource is given. Steps to reproduce: - 1. Create Company A and Company B. 2. In Company B, create a public holiday on Tuesday. 3. Switch back to Company A. 4. Open the All Timesheets Grid view from Company A. Expected behavior: - - The grid column for Tuesday should not be grey for Company A users. Current behavior: - - The grid column for Tuesday is grey, incorrectly showing it as a time-off day. task:4492966 Forward-Port-Of: odoo/enterprise#132332 Forward-Port-Of: odoo/enterprise#88495
Fixed an issue where the Master Production Schedule could show actual indirect demand for lower-level manufactured components one period too early. This helps planners see component needs in the correct month, improving replenishment accuracy for multi-level bills of materials.
Original PR description
On a multi-level BOM where an intermediate component has a 0-day produce delay, the actual indirect demand shown on its own components in the Master Production Schedule could land one full period…
On a multi-level BOM where an intermediate component has a 0-day produce delay, the actual indirect demand shown on its own components in the Master Production Schedule could land one full period (e.g. month) too early, even though the indirect demand *forecast* for the same component was already correct. Steps to reproduce: ------------------- * Build a 3+ level manufactured BOM, - Finished (produce_delay 1 day) - Semi-Finished 1 (produce_delay 0) - Semi-Finished 2 (produce_delay 0) * Add all three products to the MPS (activate indirect demand and actual indirect demand). * Forecast 1 demand for Finished in month T. * Replenish Finished for month T - Semi-Finished 1 indirect demand correctly lands in T-1 (the 1-day produce delay move it to the next month) * Replenish Semi-Finished 1 for T-1 --> Semi-Finished 2's actual indirect demand lands in T-2 instead of T-1. Observation: ------------- When running action_replenish it will create a procurement, this procurement date will be calculated in MrpProductionSchedule._get_procurement_extra_values, this function always use the period's date_start as the procurement's date_planned: https://github.com/odoo/enterprise/blob/e2aa3073dafa9377654c761e371a660415db1e88/mrp_mps/models/mrp_mps.py#L773 This combined with a 1 hour delta when creating a mo, moved the newly created MO to the month prior (_run_manufacture->_prepare_mo_vals->get_date_planned): https://github.com/odoo/odoo/blob/1a8c6053709cb254f6a5297d72f43dd48aad1b96/addons/mrp/models/stock_rule.py#L172 https://github.com/odoo/odoo/blob/c1ec73be8e16b57c8cf7e4d0c3a915dd9fd6c78b/addons/mrp/models/stock_rule.py#L204 When retrieving the information for the mps calculation, it will be the date_range of the previous month: https://github.com/odoo/enterprise/blob/d3b7c312390d2c0026cc150055f08938c33f4d6f/mrp_mps/models/mrp_mps.py#L473 In that date range is added to indirect_outgoing_qty since it location_dest is a 'production': https://github.com/odoo/enterprise/blob/d3b7c312390d2c0026cc150055f08938c33f4d6f/mrp_mps/models/mrp_mps.py#L1164 https://github.com/odoo/enterprise/blob/d3b7c312390d2c0026cc150055f08938c33f4d6f/mrp_mps/models/mrp_mps.py#L1171-L1172 With the key still in the previous month opw-6519076 Forward-Port-Of: odoo/enterprise#130525
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
Creating a new product from the purchase catalog now correctly carries over the selected vendor without causing an error. This prevents interruptions when buyers add missing products while working on purchase orders or requests for quotation.
Original PR description
Opening a product creation form from the purchase catalog raises a traceback. ### Steps to Reproduce 1. Go to Purchase > Orders (or Requests for Quotation). 2. Open any order with a Vendor selected.…
Opening a product creation form from the purchase catalog
raises a traceback.
### Steps to Reproduce
1. Go to Purchase > Orders (or Requests for Quotation).
2. Open any order with a Vendor selected.
3. Click 'Catalog' on the order lines table.
4. Search for any non-existent product to trigger the empty state.
5. Click 'Create a product' from the no content helper.
### Traceback
```pytb
Traceback (most recent call last):
File "odoo/addons/web/models/models.py", line 2232, in onchange
defaults = self.default_get(missing_names)
File "odoo/orm/models.py", line 1401, in default_get
defaults[fname] = field.convert_to_write(value, self)
File "odoo/orm/fields_relational.py", line 759, in convert_to_write
if record != origin:
File "odoo/orm/models.py", line 6117, in __eq__
return self._name == other._name and set(self._ids) == set(other._ids)
TypeError: cannot use 'dict' as a set element (unhashable type: 'dict')
```
### Issue
The purchase catalog action helper (PR odoo/odoo#164131) sets the current
vendor as default on the new product using a bare dictionary:
```python
context = {'default_seller_ids': [{'partner_id': vendor_id}]}
```
Following commit 188c81575130 (PR odoo/odoo#272499), a check was added to
`convert_to_cache()` to optimize lists of record ids (`[1, 2, 3]`):
```python
elif isinstance(value, list) and value and not isinstance(value[0], (tuple, list)):
```
The `convert_to_cache` expects x2many default values to be passed as
formal commands or ids.Because the caller passed a bare dictionary instead
of a command, the dictionary was mistakenly placed into `record._ids`, causing a
TypeError when comparing records (`set(self._ids)`).
### Fix
Use `x2ManyCommands.create` from `@web/core/orm_plugin` to properly format
`default_seller_ids` as an x2many create command.
Related: odoo/odoo#272499
Related: odoo/odoo#164131
Forward-Port-Of: odoo/odoo#288282This 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
This fixes an issue where changing or discarding a section quantity in sales orders could update related line quantities more than once. The change keeps section and child line quantities aligned in one coordinated update, reducing the risk of inconsistent order lines.
Original PR description
We introduced the ability to adjust child line quantities from the parent section's quantity fields in 34c47e5493bc36af338efbb54050e060b04f8ea3. However, this caused an issue when discarding a change…
We introduced the ability to adjust child line quantities from the parent section's quantity fields in 34c47e5493bc36af338efbb54050e060b04f8ea3. However, this caused an issue when discarding a change made to a section's quantity. Previously, the child line quantity adjustment was triggered from the field's `useEffect`. Since `useEffect` runs on every re-render, discarding a section quantity change could trigger the adjustment again. This could result in two nchanges for a single line operation and potentially leave child line quantities in an inconsistent state. We already have `batch_onchange_sol` to handle onchange operations involving both virtual and saved records. It can handle the section quantity change and the corresponding child line quantity adjustments in a single ORM call. To achieve this, the quantity adjustment logic is moved from the field component to the `Record` class, specifically into `_getOnchangeValues`. The flow is now: 1. `record.update()` receives the section quantity change. 2. `_getOnchangeValues()` detects that the updated field is the section quantity. 3. It adjusts the quantities of the corresponding child lines as part of the same onchange values. 4. `batch_onchange_sol` sends the complete set of changes to the ORM in a single onchange call. 5. The resulting values are applied without relying on field re-renders. This ensures that the section quantity and its child line quantities are always updated together, while avoiding duplicate onchanges and side effects caused by `useEffect` re-renders. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#287843
Automatic point of sale session closing now safely rolls back accounting entries if validation fails partway through. This prevents incomplete accounting data from blocking session closure with balance errors, improving reliability for POS operations.
Original PR description
When automatically closing entries, an error during the accounting validation of a POS session can occur after some move lines have already been created. This was causing unbalanced accounts, preventing the POS session from being closed. An "The entry is not balanced" error was then raised. To handle this, use a savepoint so that if `_validate_session_accounting` raises an exception, the move lines created during the validation are rolled back. --- Task: https://www.odoo.com/odoo/project/1737/tasks/6581447 Forward-Port-Of: odoo/odoo#288958
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
Moved documents now correctly inherit group access permissions from their destination folder, even when that folder has no owner. This prevents group members from unexpectedly losing access after files are moved by drag and drop.
Original PR description
When moving a document into a folder (e.g., via drag and drop), the document fails to inherit the group access rights defined on the destination folder if that folder does not have an owner. While…
When moving a document into a folder (e.g., via drag and drop), the document fails to inherit the group access rights defined on the destination folder if that folder does not have an owner. While direct uploads correctly apply the groups, moved documents only inherit partner access rights in this scenario, potentially leaving group members without the expected access. This occurs because group access rules were inadvertently filtered out during the rights sync when the system evaluated the missing folder owner. This commit ensures that group-based access rules are correctly retained and applied to the document when it is moved into a folder, regardless of whether the destination folder has an owner. Steps to reproduce: - Create a new folder and ensure the "Owner" field is empty. - Add a group to the folder's access rights. - Drag and drop a file from elsewhere into that folder. - Notice the document doesn't inherit the group from the parent folder. Task-6585315 Forward-Port-Of: odoo/enterprise#132235
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