Wednesday, September 16, 2026
159 changes · master
Security fixes and vulnerability patches
Access to certain project forecasting templates and database-related project controls is now limited to System Administrators rather than Project Managers. This reduces exposure of sensitive administrative settings and helps ensure only the right users can manage them.
Original PR description
This commit scopes the planning slot template admin rule in project_forecast and the databases manager rule on projects to System Administrators instead of Project Managers. task-5039102
Access to secret project information is now limited to System Administrators instead of Project Managers. This better protects sensitive project details, tasks, milestones, reports, and timesheets from broader visibility.
Original PR description
This commit scopes visibility rules on projects, tasks, milestones, updates, the burndown report, the task analysis report and timesheets to System Administrators instead of Project Managers. task-5039102
New functionality added to Odoo
Website editors can now add animated numbers that count up or down between chosen values. This helps highlight statistics, achievements, or changes more visually, with timing settings shared with appearance animations for easier setup.
Original PR description
This commit introduce a new snippet to allow users to add animated numbers (numbers that dynamically increase/decrease) on their website. By changing the start and end values, the user can have an number that increase in an animation, to emphasize an improvement or a statistic. The snippet also enable a decreasing number. Timing values (animation delay or duration) will be shared with onAppearance animations to avoid duplicating options, since in most cases the user will put the same value for both in they want to add an onAppearance animation. task-5358340
Enhancements to existing features
Spanish electronic invoicing now recognizes additional identity document types such as passports, residence certificates, and other official documents. This helps businesses report customer identities more accurately across Spanish EDI systems, with automatic selection of the most reliable available ID type.
Original PR description
Following the task that introduced configurable ID types, this commit adds the missing document types required for Spain: - 03 PASAPORTE - 04 DOCUMENTO OFICIAL DE IDENTIFICACIÓN EXPEDIDO POR EL PAIS O TERRITORIO DE RESIDENCIA - 05 CERTIFICADO DE RESIDENCIA - 06 OTRO DOCUMENTO PROBATORIO Validators are intentionally omitted for now. Documentation and a warning text tooltip have been prepared to guide users. For Spanish EDI systems the 'IDType' field will now compute based on a priority hierarchy. When multiple document types are available, the system will fallback and choose the most reliable option closest to zero (higher up in the priority mapping table). task-6171794 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
Resolved issues and error corrections
Users can now open the Attachments menu even when an expense attachment belongs to a company that is not currently active. The fix prevents inaccessible expense records from being read, avoiding an access error in multi-company setups.
Original PR description
**Problem:** When any expense belonging to a given company has an attachment on it, an Access Error will occur when attempting to enter the Attachments Menu when that company is not active. **Cause:** In the `hr_expense` override of `_inaccessible_comodel_records`, all `hr.expense` records are browsed, then have their values read, even if they are not currently accessible. https://github.com/odoo/odoo/blob/f28aa8e7aa0e2c6fb97c841711800410a1da3b72/addons/hr_expense/models/ir_attachment.py#L22-L23 **Purpose:** Use `_filtered_access` to ensure that only currently accessible records are read. **Steps to Reproduce in Runbot:** 1. Add an attachment to an `hr.expense` record in the My Company (San Francisco) Company. 2. Activate a different company and disable My Company (San Francisco), then attempt to open the Attachments menu in the Settings App. opw-6517249 Forward-Port-Of: odoo/odoo#286845
Features or functions removed from Odoo
An obsolete Belgian point-of-sale module was removed because it only contained empty placeholder files. This cleanup reduces maintenance overhead without changing business functionality for users.
Original PR description
This module only contained static empty files
Code cleanup and technical improvements
Subscription confirmations can now automatically create and manage planning shifts using the subscription dates, allocated hours, and recurring plan. When a subscription changes or ends, future shifts and recurrence settings are updated so planning stays aligned with active customer commitments.
Original PR description
- Configure shifts generated on subscription confirmation with the subscription's dates, allocated hours, and recurring plan. - Update shifts when a subscription is closed, ended, or cancelled by removing future shifts and disabling recurrence accordingly. - Update the recurrence of the shifts when the recurring plan of the subscription is updated. - Tasks are no longer recurring tasks by default when they are created from a subscription, as this behavior is now implemented to shifts instead. task-5265646
Helpdesk can now identify tickets that are similar to the one being handled, using AI-powered comparison of ticket content. This helps agents find related past issues faster, reduce duplicate work, and provide more consistent responses.
Original PR description
This commit introduce a new ticket similarity search feature which make use of embedding vectors to find similar `helpdesk.ticket` records. To do so, a new `ai.embedding.mixin` abstract class was introduced. This model contains a set of methods/fields that would be needed by any model needing the embedding capabilities. Implementation details: - Addition of a new `ai.embedding.mixin` model which contains the following method definitions: a cron job to periodically compute the embeddings of the implementing record, a method which retrieves a list of similar record ids, and some utility functions (i.e. for custom filtering when retrieving similar records). - The `_get_similar_embeddings` method of `ai.embedding` now exposes a new param `min_similarity`. If set, the param allows to filter out records below a certain threshold. task-5170315 Upgrade PR: https://github.com/odoo/upgrade/pull/11324
Website editors can now open a preview dialog that shows how selected theme colors affect common page elements. This makes it easier to judge visual impact while editing and reduces guesswork when adjusting a site's branding.
Original PR description
Steps to reproduce: - Open the website builder. - Go to Theme > Colors. - Change theme colors. - Try to evaluate the impact on UI elements. Before this commit, it was hard to understand how theme colors affected typical components while editing. After this commit, users can open a dedicated colors preview dialog (see image), and theme CSS updates are reloaded in both the page iframe and the preview iframe. task-5960098 <img width="1550" height="925" alt="image" src="https://github.com/user-attachments/assets/f80dca4f-5223-4f9f-acaf-cb9e03541cae" />
Field service shift updates now use clearer notification categories for assignments, reassignment, unassignment, rescheduling, and status changes. This helps employees receive notifications only when they are relevant to the shift status and company settings, reducing unnecessary alerts.
Original PR description
Improve shift notification tracking by using dedicated subtypes for status changes, assignment, re-assignment, unassignment, and rescheduling. Ensure notifications are only sent when relevant based on the shift state and company configuration. task-6377602
Turkish localization now lets users apply VAT withholding more easily by choosing a fiscal position for the relevant withholding ratio. This reduces manual tax changes on invoices and supports accurate withholding calculations for related e-invoicing flows.
Original PR description
Turkish VAT withholding (tevkifat) is applied at seven ratios, from 2/10 to 10/10. Before, the seven withholding taxes were not linked to the normal 20% VAT, so there was no simple way to switch an invoice to withholding. After, seven fiscal positions are added, one per ratio, plus a Domestic one. Each links the 20% VAT to its withholding group, so choosing a position and running "Update Taxes and Accounts" swaps the tax on the invoice lines. `account.tax` also gains a helper that returns the fraction a tax withholds (9/10 gives 0.9), used by the Nilvera modules. task-6368193 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Odoo now removes reliance on an outdated spreadsheet-writing library and uses the maintained reader for older Excel imports. This reduces maintenance risk while preserving the ability to import existing .xls files and newer .xlsx files through the appropriate tools.
Original PR description
(see commit message) task-2480034 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
A small internal flag was added to the base module setup to prepare for possible future support for loading test data. This does not change day-to-day user workflows now, but it makes a later backport or rollout easier and safer.
Original PR description
Part of https://github.com/odoo/odoo/pull/284989 for 20.0 Introduce the new test data flag on ir.module.module in case we want to backport the feature in 20.0 later.
Project billing reports now use clearer, more specific categories for revenue and costs. This helps project managers distinguish services, subscriptions, materials, expenses, and purchase-order-related vendor bills more accurately when reviewing profitability.
Original PR description
The billing types of an analytic line name every revenue stream in the plural, although revenue is uncountable in English, and they lump together flows a project manager reads separately: expenses only ever appear as a cost, goods and subscriptions are both reported as "Other Revenues", and a vendor bill is reported the same way whether or not it comes from a purchase order. With this PR, the revenue types are renamed to the singular and the service ones are grouped under "Service Revenue (...)", expenses are split into a cost and a revenue type, "Other Revenues" is split into "Subscriptions", "Materials" and "Other Revenue", and vendor bills billed from a purchase order get a "Purchase Orders" type. The keys are renumbered so that grouping by billing type still lists the revenue types before the cost ones, the "Other" ones last. Task-6545004
Settings pages now include clearer spacing between the top control area and the settings form. This small visual adjustment improves readability and keeps the layout consistent across Odoo editions.
Original PR description
ENT: https://github.com/odoo/enterprise/pull/131451 task-6570898 | Before | After | |--------|--------| | <img width="1704" height="567" alt="Screenshot 2026-09-14 at 17 06 55" src="https://github.com/user-attachments/assets/8adfb0f8-97e3-4405-975f-2b3a198e35e5" /> | <img width="1706" height="547" alt="Screenshot 2026-09-15 at 15 51 45" src="https://github.com/user-attachments/assets/311569f0-d0f7-4e7b-ac21-754f4e3e9fff" /> |
Partner ledger reports now store opening balances at accounting lock dates instead of recalculating all historical entries each time. This should make partner ledger and related customer follow-up reports faster while still reflecting later reconciliation corrections accurately.
Original PR description
Snapshot the partner ledger's initial balance at lock dates to avoid recomputing historical move lines on every report rendering. The balance is split into an init_balance and a period_balance aggregated with a groupby, the summable part of the init_balance goes through a snapshotable subengine Reconciling a partner-less line with a line having a partner moves the amount onto it, even in a locked period, so that correction stays out of the snapshots and is recomputed live on top of them. task-6235268
Spreadsheet imports now rely on the maintained Excel handling already required by the system, instead of an older library that is no longer used for XLSX files. This keeps accounting import tests aligned with the current dependency setup and reduces outdated technical baggage without changing day-to-day user workflows.
Original PR description
xlrd is not used anymore for xlsx files. https://github.com/odoo/odoo/pull/286896
Turkish e-invoices now select one withholding reason at invoice level instead of requiring many tax-specific choices on each line. This reduces long tax dropdowns, prevents invalid mixed withholding ratios from being sent, and exports the reason in the correct Nilvera category.
Original PR description
A Turkish withholding invoice must carry a GİB reason code (601-627) that says why the tax is withheld. Before, this code was stored on the tax itself. The module therefore shipped one tax for every…
A Turkish withholding invoice must carry a GİB reason code (601-627) that says why the tax is withheld. Before, this code was stored on the tax itself. The module therefore shipped one tax for every (ratio, reason) pair: 138 withholding taxes in each line's dropdown. The code was also asked per line and read from the fiscal position, which only reaches the lines after "Update Taxes and Accounts", so the form asked for a reason before the matching tax was on the invoice. After, the invoice type and the list of reasons are taken from the taxes on the lines. The reason is a single field on the invoice, limited to the codes for the ratio the lines withhold, kept while it fits and cleared when the ratio changes. A missing code can be created from the field, and an invoice mixing ratios cannot be sent. On export the reason is written under the 9015 withholding category, not the 0015 exemption one. `l10n_tr_nilvera_edispatch` changes only because its tests reuse the invoice fixture from `l10n_tr_nilvera_einvoice`, which built a wrong tax; the two reference files are regenerated. task-6368193
The contact smart button for Signature Requests now opens a complete list of all related requests, including those still awaiting signature. This removes confusion where the displayed count did not match the documents shown and makes requests easier to review.
Original PR description
The Signature Requests smart button on a contact opened a kanban view filtered to signed documents, while the number displayed on the button also included requests awaiting a signature. Users could therefore see fewer documents than the number displayed on the button, with no indication that a filter was applied. Open the requests in a list view without any filter, so that all requests counted by the smart button are displayed and easier to scan. task-6575586
Users can now download a version of an in-progress signing request that includes signatures and entered information already completed by other signers. The original document remains available, while the signing page continues to show only the original, making it easier to track progress without disrupting the signing flow.
Original PR description
Downloading from a sign request in progress always returned the original template document, even when some signers had already signed it. The request now serves its working copies, which already carry the values of the completed signers as incremental updates, under a "Partially signed" section of the download menu. The original documents stay available next to it, and the signing view still offers the original only. task-6469337
Changing a worksheet on a field service shift now automatically saves the shift first. This prevents users from entering information into outdated worksheet fields and helps avoid accidental overwrites or incorrect configurations.
Original PR description
Previously, when we changed the worksheet, the worksheet fields were not being changed because it required a save to update. So there were times when a user entered some data, and it updated the previous one and completely ruined their configuration. Now, when the user changes the worksheet field, the shift is automatically saved, so the user will always get only the updated fields. Task-6559528
Planning now better supports cases where an employee asks to be replaced by allowing the replacement flow to switch to that user. Button text, confirmation messages, access rules, reporting, and tests were updated to make shift switching clearer and more reliable for staff and managers.
Original PR description
Allow the adapter to switch to the user who only wants to be replaced. Change the button wording and popups of the switching scenarios --- task-5979777
Project managers can now see revenue from subscription orders under a dedicated "Subscriptions" billing type instead of mixed into "Other Revenues". This makes recurring revenue clearer in project analytic lines and improves reporting visibility.
Original PR description
Revenue invoiced on a subscription is reported as "Other Revenues", together with every other revenue that has no type of its own, so a project manager cannot tell recurring revenue apart in the analytic lines of a project. With this PR, an analytic line invoiced on a subscription order gets its own "Subscriptions" billing type. Task-6545004
The activity view now has softer cell gradients and slightly more padding after the web client redesign. This makes activity information easier to scan and gives the interface a cleaner, more polished appearance.
Original PR description
| Header | Header | |--------|--------| | <img width="264" height="77" alt="image" src="https://github.com/user-attachments/assets/95dd9535-c66a-420e-8e34-cd2a3a44c195" /> | <img width="262" height="80" alt="image" src="https://github.com/user-attachments/assets/2e62ad1a-afc1-4999-b4b1-f2b534597504" /> | This PR finetunes the cells of the activity view after the webclient redesign. It slightly reduces the strength of the gradient applied on the cells and adds a bit of padding. task-6577089 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The Point of Sale snooze choices now use larger rectangular buttons instead of small radio buttons. This makes the options faster to scan and easier to tap or click, improving the day-to-day user experience for staff.
Original PR description
Replacing standard radio buttons with rectangular buttons. This makes the options quicker to scan and easier to click, enhancing the overall user experience. task-6564075
This update removes an obsolete internal option from expense receipt extraction and Stripe expense processing. It helps keep the expense workflow code simpler and easier to maintain without changing how users handle expenses.
Original PR description
Remove the check parameter as it is not used anywwhere anymore Related: https://github.com/odoo/odoo/pull/288256
The website shop carousel filter has been renamed from “Newest Products” to “Newest Arrivals” and now uses the same sorting logic as the shop page. This makes product presentation more consistent for website editors and shoppers, reducing confusion around which items are shown as new.
Original PR description
Currently, the `Newest Products` dynamic filter shows products that were recently created and published. This is inconsistent with the `Newest Arrivals` filter already used on the /shop page, which…
Currently, the `Newest Products` dynamic filter shows products that were recently created and published. This is inconsistent with the `Newest Arrivals` filter already used on the /shop page, which sorts products according to publish date. Steps to produce: --- - Install the website_sale module with demo data. - Navigate to Website and open the homepage in edit mode. - Add a Dynamic Snippet Carousel to the homepage. - Click on the newly added carousel. - In the right-side Edit panel, select the Dynamic Carousel settings. - Observe that the Current Filter is set to Newest Products by default. This PR aligns the dynamic filter with the /shop page behavior by: - Renaming the filter from `Newest Products` to `Newest Arrivals` (including its XML ID) for consistency. - Updating the underlying sort logic to match the /shop page's `Newest Arrivals` filter. - Updating the related tests accordingly. upgrade PR: https://github.com/odoo/upgrade/pull/10668 opw-6331212 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Odoo now routes Gevent worker web requests through the same internal HTTP server used elsewhere, while still relying on Gevent for connection handling. This reduces duplicate server logic and should make future maintenance more consistent without changing business workflows.
Original PR description
The Gevent worker (started in a subprocess by the PreforkServer) was still using the WSGI server of gevent, although we have our own server since [h11]. We think it is a good idea to consolidate the codebase around a single server, then to use multiple different ones. The Threaded and Prefork servers are calling `socket.accept()` themselves, doing the same for geven is proving more difficult, so we decided to still rely on Gevent and its StreamServer class for the socket management, but leave the HTTP part to our h11-based WSGI server. Co-authored-by: Chong Wang <cwg@odoo.com>
Companies can now view and manage grouped tax identifier information directly on the company record, reducing the need to track many separate fields. The setup flow is also improved for country-specific identifiers, with related localization screens updated to match the new layout.
Original PR description
*:fr,ar,au,br,ca,cl,es_edi_verifactu,in,nz,ph,sa_edi,tr_nilvera_einvoice
[IMP] account,base,l10n_fr: add the identifier list on the company
A new feature to group all TIN identifiers was added on the partner, to
avoid having a huge load of fields that are hard to track.
We now display it also on the company. This PR also adds the possibility
to force the display of some additional identifiers, for an easier setup
process. (Used here to display specific French identifiers for French
companies).
[IMP] l10n_{*}: update views after base template update
*ar,au,br,ca,cl,es_edi_verifactu,in,nz,ph,sa_edi,tr_nilvera_einvoice
The vat field in the base template has changed a bit for a
new feature, this updates the view that were xpathing to it.
task-6285604Several localization modules were updated so their company settings continue to align with a recent change to the VAT field in the base system. This helps keep country-specific reporting, payroll, payments, and e-invoicing settings working consistently after the underlying template change.
Original PR description
*au_hr_payroll_api,be_reports,bg_reports,ca_payment_cpa005,cl_edi, de_intrastat,eu_oss_reports,ke_edi_oscu,lu_reports,nl_reports, ph_reports,uy_edi In the associated community PR, the vat field has changed a bit for a new feature, this updates the view that were xpathing to it. task-6285604
Invoice emails now include the relevant timesheet report by default while avoiding unnecessary or empty timesheet PDFs. This gives customers clearer supporting details for service invoices and prevents irrelevant attachments on invoices without timesheet-based work.
Original PR description
Before this PR --- - Invoice email templates did not attach the Timesheets report by default. - The invoice email templates contained a hardcoded portal link to view timesheets. - The Timesheets report was generated from the Send & Print wizard even for invoices without timesheet-based service lines. - The Timesheets print action generated an empty PDF when no timesheet entries were available. After this PR --- - The Timesheets report is attached by default to the standard and self-billing invoice email templates. - The hardcoded portal link is removed from the invoice email templates. - The Timesheets report is generated from the Send & Print wizard only when the invoice contains timesheet-based service lines. - The Timesheets print action displays a notification instead of generating an empty PDF when there are no timesheet entries. task - 5361456
The RPC key generation dialog is clearer and now shows a ready-to-use Python example, making it easier for users to connect external tools correctly. Users can also copy the generated key more conveniently, while the clipboard button component gains more flexible icon support across the interface.
Original PR description
This commit improves the RPC key generation dialog by refining the form layout and displaying a ready-to-use Python code snippet. The key can also be copied directly using the provided copy button. Additionally, it modifies the CopyClipboardButton widget to support custom button icons while keeping `fa-clipboard` as the default. task-6375961
The purchase dashboard KPI cards have been visually updated so the Days to Order card matches the other dashboard cards. This improves readability and consistency by using clearer backgrounds and rounded styling.
Original PR description
Before this PR, the not all the KPI's backgrounds were updated to be visible with the new background. Now they are raised to bg-200 and border-radius was added. | Before | After | |--------|--------| | <img width="1681" height="193" alt="Screenshot 2026-09-14 at 15 16 27" src="https://github.com/user-attachments/assets/7cb39825-cf19-4872-97a1-5203fe79b8ff" /> | <img width="1681" height="193" alt="Screenshot 2026-09-14 at 15 16 05" src="https://github.com/user-attachments/assets/19f5f8cc-6eab-47b3-9604-ea1500d3d653" /> | task-6570029 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Dropdown menus across several Odoo areas have been standardized and visually refined to better match the new Frost design. This gives users a more consistent and polished experience when navigating options in web, email, project, and website tools.
Original PR description
*: html_builder, mail, project, website This commit standardizes dropdowns into a consistent layout and fine-tunes them to better align with the new Frost design. task-6542810 Requires: - https://github.com/odoo/enterprise/pull/130999 | Community | Enterprise | |--------|--------| | <img width="230" height="285" alt="Screenshot 2026-09-15 at 10 56 08" src="https://github.com/user-attachments/assets/b0aa7b5f-4706-4ee9-898d-0a6fc8c70dae" /> | <img width="231" height="271" alt="Screenshot 2026-09-15 at 10 54 05" src="https://github.com/user-attachments/assets/e86deed6-1552-4b19-9531-b8684d3a9b4c" /> | --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The invite people experience in Discuss has been visually refined to match the rest of the interface. Search fields, selected person chips, invitation links, result rows, and dialog spacing now feel more consistent and easier to scan.
Original PR description
The invite people panel did not match the rest of Discuss. Its search field was square, while every other search input in Discuss is pill-shaped, and its result rows were stacked flush against each other without any padding. Give the search field the same pill shape and height as the one of `mail.SearchInput`, used by the member list and the sidebar. Add padding and a gap between result rows, and let the selected person chips and the invitation link field follow the same pill language. The dialog wrapping these panels, opened by "+ Chat" and by the "Invite people" entries, had almost no padding of its own, letting its content touch the modal border. Use the standard modal body padding instead. <img width="1716" height="686" alt="invite-popover-comparison-zoom" src="https://github.com/user-attachments/assets/d6338e61-3c72-49cc-a0b6-f5bfb73eaed0" />
This update brings the embedded spreadsheet tool up to its latest version, improving dashboards, chart behavior, pivot table accuracy, and data analysis suggestions. Business users should see more reliable spreadsheet reporting and a more consistent dashboard appearance.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/4784627a29 [REL] 19.5.0-alpha.20 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/4784627a29 [REL] 19.5.0-alpha.20 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/e7d6e6e095 [IMP] spreadsheet: Allow integrator to set the spreadsheet dashboard [Task: 6542221](https://www.odoo.com/odoo/2328/tasks/6542221) https://github.com/odoo/o-spreadsheet/commit/14f6529b65 [IMP] colors: update dark background color [](https://www.odoo.com/odoo/2328/tasks/) https://github.com/odoo/o-spreadsheet/commit/c0f451af1e [IMP] demo: debounce xml template build [Task: 6574005](https://www.odoo.com/odoo/2328/tasks/6574005) https://github.com/odoo/o-spreadsheet/commit/aa96e07891 [FIX] demo: fix scorecard demo definition [Task: 6573109](https://www.odoo.com/odoo/2328/tasks/6573109) https://github.com/odoo/o-spreadsheet/commit/11eac2b445 [FIX] model: evaluation plugin dispatch should trigger update [Task: 6574488](https://www.odoo.com/odoo/2328/tasks/6574488) https://github.com/odoo/o-spreadsheet/commit/dc06c6a41f [FIX] chart annotation: text input style [Task: 6533642](https://www.odoo.com/odoo/2328/tasks/6533642) https://github.com/odoo/o-spreadsheet/commit/f8d1faf29b [FIX] Charts: Bubble chart background depends on color scheme [Task: 6448882](https://www.odoo.com/odoo/2328/tasks/6448882) https://github.com/odoo/o-spreadsheet/commit/8f8951738b [FIX] Charts: fix rounded borders in full-screen [Task: 6569794](https://www.odoo.com/odoo/2328/tasks/6569794) https://github.com/odoo/o-spreadsheet/commit/1efdd6cc50 [FIX] pivot: wrong running total with collapsed/hidden dimensions [Task: 6569607](https://www.odoo.com/odoo/2328/tasks/6569607) https://github.com/odoo/o-spreadsheet/commit/a709278102 [IMP] data_analysis: detection of headers [Task: 6516198](https://www.odoo.com/odoo/2328/tasks/6516198) https://github.com/odoo/o-spreadsheet/commit/736ce42775 [FIX] gaugeCharts: fix GaugeChartBuilder typing [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/845acc4dd7 [REF] chart_suggestion_engine_test : small rewrite [Task: 6537589](https://www.odoo.com/odoo/2328/tasks/6537589) https://github.com/odoo/o-spreadsheet/commit/5d7b912754 [IMP] chart_suggestion_engine: date column [Task: 6537589](https://www.odoo.com/odoo/2328/tasks/6537589) https://github.com/odoo/o-spreadsheet/commit/84cfa4ba58 [IMP] chart_suggestion_engine: boolean column [Task: 6537589](https://www.odoo.com/odoo/2328/tasks/6537589) https://github.com/odoo/o-spreadsheet/commit/5b7222b702 [FIX] pivot: fix scope of `pivot_html_renderer` css [Task: 6523521](https://www.odoo.com/odoo/2328/tasks/6523521) https://github.com/odoo/o-spreadsheet/commit/c411984235 [FIX] standalone viewport: use correct devicePixelRatio [Task: 6445656](https://www.odoo.com/odoo/2328/tasks/6445656) https://github.com/odoo/o-spreadsheet/commit/487d50683b [IMP] model: remove notifyUser from the model [Task: 6517821](https://www.odoo.com/odoo/2328/tasks/6517821) https://github.com/odoo/o-spreadsheet/commit/681c280799 [IMP] model: remove raiseBlockingErrorUI from model [Task: 6517821](https://www.odoo.com/odoo/2328/tasks/6517821) 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>
The ellipsis menu buttons in Odoo Discuss now use a consistent size and hover style across related screens. This creates a more polished and predictable experience for users interacting with chat, channels, and messaging menus.
Original PR description
Before this commit, ellipsis buttons in Discuss had an inconsistent style (different size, different hover effect). This commit harmonizes the style with a shared classname `.o-discuss-ellipsisButton`. <img width="1188" height="1130" alt="ellipsis-button-before-after" src="https://github.com/user-attachments/assets/54e7f6f8-1308-4075-adaf-7b95230e2a70" />
Stock screens now use clearer wording and visually de-emphasize empty values, making key information easier to scan. Manufacturing bill of materials printouts are cleaner, with unnecessary items removed and breadcrumbs fully shown for better context when printing.
Original PR description
stock ----- The name of the `Detailed Stock`-menu needed to change and the null fields were too prominent in the line so they are now muted for clarity. mrp --- The default browser print button option showed some unnecessary objects. These have been removed to improve clarity. Also the breadcrumb is now fully expanded when using the browser print option. Task-id: 6201687
Completed activity meeting links now keep users connected to the record they came from, making it easier to return after viewing a meeting. The change also improves these links in email notifications so navigation remains reliable outside the app.
Original PR description
If you clicked on the activity meeting link of a done activity, you'd have no robust way of going back to the record you were on. Using this instead of _get_html_link and adding base_url in order to work on email notifications too. Task-6577150
Payroll line updates are now grouped together instead of handled one by one, reducing processing overhead during large payroll runs. This can make payroll generation noticeably faster, with the reported benchmark improving a 300-payslip Belgian run from about 12 seconds to about 7 seconds.
Original PR description
This commit batches the assignment in `hr.payslip.line. _inverse_name` to reduce the frequency to `write` on the field and it's calling `modified`, which is quite expensive to call. On a Belgian CP200 payrun with 300 payslips and 199 salary rules, which generates roughly 12k `hr.payslip.line`, it shaves off 4.75s of the whole creation process (from ~12s -> ~7s). Before: <img width="1917" height="296" alt="image" src="https://github.com/user-attachments/assets/45640465-09ee-43c2-861d-bf01eac35505" /> After: <img width="1917" height="346" alt="image" src="https://github.com/user-attachments/assets/30412ed4-ca68-4214-9e37-7ddeaf62427a" />
The appointment module interface has been updated to better align with the newer Frost design style. This should make scheduling pages feel more polished and consistent, improving the experience for users booking or managing appointments.
Original PR description
This PR adds some improvements to the appointment module UI Task-6533622
The AI assistant connection setup now includes clearer hints about the information users need to provide. This makes it easier for users to configure the connection correctly and reduces confusion during setup.
Original PR description
This commit adds hint to the MCP configuration dialog describing the parameters required to connect an AI assistant, making the setup process clearer for users. task-6375961
VoIP users can now access the queues menu while they are already on a call. This lets them join or leave call queues before their current call ends, helping control whether they receive another queued call immediately afterward.
Original PR description
Follow-up of [1], we now show the queues menu while in a call (softphone top-left dropdown menu). This allows to join/leave a queue during a call allowing/preventing a queue call to be made as soon as you hang up your current call. In any case, while in a call, you are marked as being busy from the queue point of view of course. [1]: https://github.com/odoo/enterprise/commit/7250e8dda350019f739b91fa6cc7533395ec45da task-6575682
Helpdesk users will no longer receive an empty PDF when trying to print timesheets for a ticket with no logged time. Instead, the system shows a notification, keeping the action available while avoiding confusing blank reports.
Original PR description
Before this PR --- - The "Timesheets" print action was available from helpdesk tickets even when no timesheet entries were logged on the ticket - Clicking the action generated an empty timesheet PDF After this PR --- - The "Timesheets" print action remains available on helpdesk tickets - When no timesheet entries are available to print, a toast notification is displayed instead of generating an empty PDF task-5361456
Dropdown menus have been visually adjusted to better match Odoo's new Frost design direction. This improves interface consistency and polish for users across enterprise web screens without changing business workflows.
Original PR description
This commit adapts the dropdown layout to better align with the new Frost design. task-6542810 Requires: - https://github.com/odoo/odoo/pull/287459
Users can now archive, unarchive, or delete AI agents directly from agent menus. When an agent is deleted, empty chats are removed while chats with prior messages remain available as read-only history, preserving important context without allowing unavailable agent actions.
Original PR description
Adds 'Archive', 'Unarchive', and 'Delete' actions to the AI agent kanban card menu and panel menu. On agent deletion, its empty chats are deleted. Chats with existing messages are kept but become read-only where the composer and any agent-dependent actions are hidden. task-id-6570223
The spreadsheet dashboard grid now better matches the surrounding action interface color. This creates a more consistent visual experience for users working with spreadsheet dashboards.
Original PR description
Task-6542221
Payroll run lists now show the most recent entries first. This makes it easier for payroll teams to find and review current pay runs without scrolling through older records.
Original PR description
-Order of payruns has been adjusted to show the newest firstly.
Belgian payroll tax reports now use configurable mappings instead of fixed salary rule codes, making it easier to adapt report boxes without developer changes. The update also separates sickness and work accident replacement revenue reporting and corrects withholding tax calculation for hourly-paid employees.
Original PR description
The reports listed salary rule codes in the code, so no rule could be added to a box without a developer. - each box now has its own category - the reports add up the payslip lines of the rules in those categories - reported amounts unchanged Task 6413398
Odoo settings can now store text-based options directly through configuration parameters. This makes it easier for businesses and implementers to manage longer or multi-line setting values consistently without extra custom work.
Peppol-related errors are now shown as separate, easier-to-read items with plain-language explanations where possible. This helps users understand what went wrong with electronic invoicing and what action may be needed, instead of seeing one long technical message.
Original PR description
Before this commit, Peppol error messages (e.g. Schematron errors) were logged in the chatter as a single unformatted line and without any humanization. The errors were too technical and the user could not easily know what action to take. This PR splits the raw error payload into individual entries, maps known error codes to human-readable explanations, and renders them as an HTML list in the chatter. task-6144909 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#283311 Forward-Port-Of: odoo/odoo#265253
The point of sale now remembers whether the cashier last used a percentage or fixed global discount and uses that choice as the default on the next order. This reduces repeated setup for businesses that commonly use fixed discounts, and the related label is clearer by referring to a discount value instead of only a percentage.
Original PR description
The default global discount type was always `percent`, ignoring the type the cashier last picked. Some clients prefer `fixed` and had to reselect it on every order. Save the last global discount type used in local storage and use it as the default type for the next global discount. Since the discount value is no longer necessarily a percentage, rename the "Discount Percentage" field and its label to "Discount Value". --- Task: https://www.odoo.com/odoo/project/1737/tasks/6507075 Forward-Port-Of: odoo/odoo#285353
ESG metric and action lists now open records more clearly, reducing accidental inline edits and making navigation easier. The metric form and ESG report templates were reorganized so users can find assessment details, company information, and action summaries more quickly.
Original PR description
Lists now only let you edit a record's fields once it's selected, otherwise clicking opens the form view directly. Reorganized the metric form (moved tags, grouped type/status under a new "Impact, Risk, Opportunity Assessment" section, moved company under a new "Other Info" tab). Moved the Actions appendix article to the top of the CSRD report and added a short note about what it shows, plus a few wording tweaks in the VSME report template. no-task
The Knowledge app interface has been refreshed to align with Odoo's new Frost design language. This improves visual consistency across comments, side panels, navigation, permissions, and article views, giving users a more modern and coherent experience.
Original PR description
This commit adapts Knowledge to match the new Frost design. task-6512406
AI-powered searches now return references to files instead of loading every file's content automatically. This keeps the AI context focused and allows file contents to be read only when needed, improving efficiency for searches involving attachments or binary fields.
Original PR description
Searching records sent the content of every binary field returned, filling the context with files rarely needed. The search tool now returns a reference for each of them, and a new tool reads the content of an attachment or a binary field for the records that need it. task-id-6562658
Accounting dashboards can now fully hide KPI indicators using a central system setting, extending the existing option to disable dashboard graphs per journal. For very large databases, this setting will be enabled by default to help reduce dashboard load and improve usability.
Original PR description
Currently, we give the option to disable dashboard graphs per journal via `disable_dashboard_graph`. This commit enhances this even more by adding a system parameter to hide the KPIs completely. An upgrade script will set it to True by default for any DB with over a 100k `account.move` records. task-6518856
Spreadsheet dashboards now use a background color aligned with the surrounding action view, creating a more consistent visual experience. The update also brings spreadsheet component refreshes and several quality fixes that improve printing, charts, exports, and interface behavior.
Original PR description
Task-6542221 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Spreadsheet dashboards now use a grid color that matches the surrounding action interface. This creates a more consistent visual experience for users working with dashboards and spreadsheets.
Original PR description
Task-6542221
Self-order and kiosk orders now show a clearer reference using the customer or partner name together with the selected preset name. Each self-order configuration also gets its own unique tracking number, making it easier for staff and customers to identify and follow the right order.
Original PR description
After this commit: = - The floating order name for Self Order/Kiosk will be formatted as: `partner_name - preset_name` - Each self-order config have a unique tracking number. task-5470833 related pr: https://github.com/odoo/enterprise/pull/104163
The order status display now shows the floating order name instead of the tracking number when that name is available. Long order names are shortened on screen, making orders easier for customers and staff to recognize without disrupting the display layout.
Original PR description
After this commit: == - Floating order name will be displayed on the order status display instead of order tracking number if available - If floating order name is longer it will be truncated. task-5470833 related pr: https://github.com/odoo/odoo/pull/250288
The mail system now skips empty alias names when checking email routing. This avoids unnecessarily loading very large numbers of unnamed aliases, improving performance and reducing load for large databases.
Original PR description
`email_localparts_tocheck` might contains the empty string. It can end up fetching tons of aliases without name (2M+ in odooo.com) task-6570805 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#288230
The Guatemala and Peru localization settings have been moved higher in the Accounting settings page. This makes electronic invoicing configuration immediately visible when users arrive from dashboard links or warnings, reducing scrolling and setup friction.
Original PR description
Purpose: Moving the Guatemalan/Peruvian Localization section higher in the settings ensures that when a user is redirected from the Accounting Dashboard or from warnings, the relevant EDI configuration is immediately visible without scrolling. task-6572740
This update adds configurable rules that automatically classify extra or missing work time and can adjust compensatory leave balances. It also makes employee working schedules mandatory and improves how flexible schedules are interpreted, helping payroll, attendance, and leave records stay more accurate with less manual correction.
Original PR description
[IMP] hr_{work_entry,attendance,holidays,holidays_attendance}: sequential time rule pipeline engine Adds a configurable threshold-based engine that automatically reclassifies attendance and leave…
[IMP] hr_{work_entry,attendance,holidays,holidays_attendance}: sequential time rule pipeline engine
Adds a configurable threshold-based engine that automatically reclassifies
attendance and leave records when a worked-hours threshold is crossed, and
optionally creates or deducts compensatory-leave allocation credits.
MECHANISM
A rule (hr.time.rule) expresses a condition:
"When employee X works more (or less) than Y hours on day/week D,
reclassify the excess (or deficit) as work-entry type Z and grant
(or deduct) N% of those hours as compensatory-leave allocation."
Rules run sequentially in sequence order. Each rule sees the already-
reclassified output of all prior rules, so they compose cleanly:
Rule 1 - excess > 2 h -> Overtime
Rule 2 - excess > 4 h -> Double-time (evaluates the post-rule-1 pipeline)
KEY MODULES
hr_work_entry
hr.time.rule rule model, field definitions, pipeline entry point
_evaluate_rules builds initial intervals, runs rules in sequence,
extracts excess and deficit per (employee, source) pair
_evaluate_period period-level threshold: compares worked hours against
the employee's schedule or a fixed expected-hours value
_apply_output writes results: reclassifies sources in-place or creates
child output records; collects allocation credit tuples
HrTimeRuleSourceMixin abstract trigger layer inherited by hr.attendance and
hr.leave; fires the pipeline on validated create/write
and exposes daily/weekly cron entry points for undertime
hr_attendance
attendance_validation per-company policy: when an attendance counts as a
validated pipeline source (immediate, officer, tolerance)
_apply_attendance_output base implementation - no allocation tracking
hr_holidays
leave_compensation_rate / allocation_type_id output fields on the rule
_apply_leave_output excess -> hr.leave.allocation credit;
deficit -> allocation deduction
hr.time.rule.allocation.log per-source log of credits; allows precise reversal
when a source record is modified or deleted
hr_holidays_attendance
bridge module: attendance-based excess/deficit also creates/deducts
hr.leave.allocation records using the same log + reversal mechanism
TRIGGER TIMING:
On write/create (for daily excess rules)
Daily cron for yesterday's daily undertime
Weekly cron for weekly rules
Task-6158746Label printing is now more consistent across products, inventory, and manufacturing, with more format choices including QR labels and updated printer layouts. This helps businesses produce clearer labels with standardized product details, pricing, packaging, barcodes, and related information while reducing duplicated setup behind the scenes.
Original PR description
Label printing offered limited formats and inconsistent layouts across products, inventory, and manufacturing. Adding new label designs also required duplicating report classes, actions, and data…
Label printing offered limited formats and inconsistent layouts across products, inventory, and manufacturing. Adding new label designs also required duplicating report classes, actions, and data preparation. Add QR label variants for Dymo, 2x7, 4x7, and 4x12 PDF formats. Add redesigned normal, alternative, small, and jewelry ZPL formats with optional prices and packaging. This commit's changes: - Standardizes names, pricing, packaging, barcodes, and extra content. - Shares PDF, Dymo, and ZPL rendering and pagination infrastructure. - Moves model-specific data preparation into the corresponding wizards. - Applies the new formats to products, lots/SNs, locations, operation types, packages, and finished products. - Removes obsolete report classes, actions, and templates. task-6127471 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
Sales service products can now have a task template selected even when no project is assigned. This reduces setup friction while keeping choices relevant by limiting templates based on whether a project is selected.
Original PR description
The task template field on the product form was hidden if there were no project set on the service, forcing users to set a project before being able to pick a task template. With this commit, the task template can be selected even without project. Further, if no project is set, only task templates without project can be chosen. Finally, if a project is set then task templates either matching the project or without project can be selected. task-6514809
Project administrators can now open a project's settings directly from the task kanban or list view using a new cog menu action. This saves time by reducing navigation steps while keeping the option limited to users with project administration rights.
Original PR description
In this commit, we add a "Configure Project" action to the cog menu of the kanban and list views of tasks. This action redirects to the form view of the current project and is only visible for users with 'project > admin' access rights. task-6533807
Attendance and leave time rules now carry premium pay categories through to payroll, helping payslips reflect special working time more accurately. Employee attendance can also replace the planned schedule for that day, improving payroll calculations when actual hours differ from standard working hours.
Original PR description
WIP Task-6158746
Field Service auto-planning now factors in technician and customer locations, travel time, working hours, existing jobs, equipment conflicts, and required skills before assigning work. This helps create more realistic schedules, reduce unnecessary driving, and avoid assigning jobs when location data is missing.
Original PR description
Auto-plan used to assign open Field Service interventions to technicians purely based on their availability, with no notion of where the technician or the customer actually is. This could send a…
Auto-plan used to assign open Field Service interventions to technicians purely based on their availability, with no notion of where the technician or the customer actually is. This could send a technician to two customers an hour's drive apart back-to-back, or send them off without accounting for the trip back to their own home or office. This only affects interventions that have a customer set — shifts without one keep being planned exactly as before. And if a customer's or a technician's location can't be determined, the intervention is left unplanned rather than scheduled without regard for travel. Auto-plan now takes travel time into account when assigning interventions to technicians. For each open intervention, it looks for the technician and time slot that fit best while respecting: - The technician's working schedule (only assigns within their actual working hours/days). - The technician's other confirmed interventions that day (no double-booking, and no cutting it too close before/after them). - Any material assigned to the technician already booked at that time, so sharing it with another intervention doesn't create a conflict. - The driving time between two consecutive interventions, or between an intervention and the technician's home/office when it's the first or last of the day. - The technician's required role/skill for the intervention, as before. - A technician's maximum workload for the day, for technicians without a fixed schedule. Among every technician and time slot that satisfies all of the above, the one requiring the least total driving time is chosen. The auto-plan works in any scale if MapBox is not enabled. If, however, MapBox is enabled, the auto-plan only works day-by-day to account for the runtime of estimating travel times (see below). Open shifts which are in 'draft' are considered as plannable anytime of the day, respecting the resources' work schedules. Interventions are planned in priority order: priority and long ones first, since they are the hardest to fit in, then shorter ones to fill the remaining gaps, and finally interventions with no requested date at all, if any availability remains. Travel times are first estimated using two different approaches, depending whether a MapBox token is set. In the negative case, a simple Haversine (straight-line distance) is used with a fixed average speed. In the positive case, we employ MapBox's isochrones API [1] and interpolate travel times between the different contours. At the end, and if MapBox is enabled, the true travel times are computed and the interventions just planned are rescheduled (iff they are in draft). See odoo/upgrade#11332 task-6200253 [1] https://docs.mapbox.com/api/navigation/isochrone/
Manufacturing and barcode users now have clearer label printing choices for product and lot/serial number labels. The update adds more label formats and keeps printing available from Shop Floor and Barcode workflows, making label handling more flexible and easier to understand.
Original PR description
Split label printing into explicit product and lot/SN quality-check types. Reuse the shared Community label wizards and reports while preserving Shop Floor and Barcode application printing. This commit's changes: - Add separate Print Product Label and Print Lot/SN Label check types. - Expose the manufacturing product-label formats on quality points. - Add 4x12 and ZPL lot/SN formats with per-lot and per-unit quantities. - Route quality-check printing through the product and lot label wizards. - Adapt Shop Floor buttons and commands to the new MRP label actions. - Render location and operation-type sheets through the shared PDF report while preserving server-side PDF merging. - Update quality domains, views, tests, and client behavior for both check types. - Rename the Barcode application action from Print Barcodes to Print Labels. task-6127471
This update aligns HR, payroll, planning, appointments, attendance, leave, and timesheet features with the new rule that every employee version must have a working schedule. It also changes how flexible employees are identified, using a flexible schedule type rather than the absence of a schedule, which improves consistency in payroll and workforce planning.
Original PR description
adapting after making hr.version.resource_calendar_id required and redefining a "flexible" employee as one assigned a flexible-type calendar instead of having no calendar at all. l10n_be_hr_payroll: move l10n_be_part_time_status from the employee/contract to the Working Schedule (resource.calendar), as part-time status is now a property of the schedule. Related: https://github.com/odoo/odoo/pull/275244 Task-6296065
Employees must now have a working schedule assigned, including flexible employees who will use a dedicated flexible schedule instead of leaving the field empty. This makes work time, leave, attendance, and planning calculations more consistent and easier to manage across HR processes.
Original PR description
[IMP] hr: make the Working Schedule required on employees Employees could previously be left without any resource_calendar_id, using standalone "Hours per Week"/"Hours per Day" fields on the…
[IMP] hr: make the Working Schedule required on employees Employees could previously be left without any resource_calendar_id, using standalone "Hours per Week"/"Hours per Day" fields on the employee/contract as an implicit "flexible schedule" signal instead. Since resource.calendar now supports a "variable" calendar_type that can hold zero predefined attendance slots:: a flexible employee can simply be assigned a variable-type calendar with no slots. This commit: - Makes hr.version.resource_calendar_id required, and removes the "Flexible" placeholder and standalone hours fields from the employee form. - Turns hours_per_week/hours_per_day into read-only fields related to the calendar instead of independently editable values. - Redefines is_flexible/is_fully_flexible: instead of keying off the calendar being absent, they now key off the calendar being a variable-type calendar with no predefined slots (fully flexible additionally requires no hours_per_week/hours_per_day target). Task-6296065
The VoIP project app now includes required access group information when the user session starts. This avoids an extra background request during startup, helping the web client load more efficiently.
Original PR description
The voip app needs this group at startup: https://github.com/odoo/enterprise/blob/c50de485ab5c0fa7927652d4129629b5b674ca37/voip_project/static/src/softphone/softphone_model_patch.js#L14 This commit adds the group inside the session info to avoid extra RPCs at webclient startup. The exact same thing is done for `voip_crm` task-6565730 Forward-Port-Of: odoo/enterprise#131207
The VoIP recruitment integration now includes a needed permission check during the initial session load. This reduces extra background requests when the web client starts, helping the app open more efficiently without changing user workflows.
Original PR description
The voip app needs this group at startup: https://github.com/odoo/enterprise/blob/203c85cade63a6564f5051d318916aaf0ea87df5/voip_hr_recruitment/static/src/softphone/softphone_model_patch.js#L14 This commit adds the group inside the session info to avoid extra RPCs at webclient startup. The exact same thing is done for other voip_* bridge modules task-6565730 Forward-Port-Of: odoo/enterprise#131210
The Point of Sale customer list now loads more smoothly when there are many customers. Menu controls for each customer are only prepared when needed, reducing freezes on slower devices without changing the user experience.
Original PR description
Opening the customer list with a few hundred partners freezes the UI for several seconds on a slow device (~300ms on a desktop, 5.6s with a 6x CPU throttle in the Chrome profiler). Each `PartnerLine`…
Opening the customer list with a few hundred partners freezes the UI for several seconds on a slow device (~300ms on a desktop, 5.6s with a 6x CPU throttle in the Chrome profiler). Each `PartnerLine` instantiates a full `Dropdown` for its "≡" menu. Setting up a `Dropdown` registers about ten lifecycle hooks (`useDropdownNesting`, `useNavigation`, `useDropdownGroup`, `usePopover`, `useEffect`, ...), and each hook registration eagerly allocates two `OwlError` objects to keep a stack trace. Multiplied by hundreds of rows, this dominates the render: ~60% of the click task is spent constructing errors for menus that will never be opened. Render a plain button per row instead and only mount the `Dropdown`, driven by a `useDropdownState`, once that button is clicked. The `Dropdown` opens its popover on mount when its state is already open and is unmounted again when it closes. The placeholder button keeps the classes the `Dropdown` would add to its toggler so the DOM, the styling and the tour selectors (`button.dropdown`) are unchanged. opw-6453848 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#287564 Forward-Port-Of: odoo/odoo#285974
The customer list in POS due settlement now avoids repeated due amount calculations for each row and uses the correct linked commercial partner to find balances. This makes opening large customer lists faster and reduces the risk of showing dues for the wrong customer with a similar name.
Original PR description
Opening the customer list with a few hundred partners is slow; part of the time is spent in `getPartnerCredit`. The `PartnerLine` template reads `this.partnerInfos` eight times per row, and each call runs `getPartnerCredit` again. For a contact, that method resolves the partner carrying the due by scanning every loaded partner for one named like `parent_name`, so the cost grows with the square of the number of partners. Cache the getter in a template variable so it is evaluated once per row, and resolve the due partner through the loaded `commercial_partner_id` instead of the name scan. This is also what the server sums the dues by, and it no longer picks a wrong homonym. `refreshTotalDueOfPartner` used the same lookup and now shares it. opw-6453848 Forward-Port-Of: odoo/enterprise#131079 Forward-Port-Of: odoo/enterprise#130015
Updated website builder test checks so they continue to pass with newer Chrome behavior. This helps keep quality checks stable without changing the website features users see.
Original PR description
In Chrome 152, single-value `background-size` properties may be serialized or expanded to include implicit dimensions (e.g., appending `auto` like `100px auto`), causing strict exact-string test assertions to fail. This commit updates `website` builder test expectations to use regex prefix matching or substring inclusion so tests remain reliable across different Chrome versions. Note: this is a followup of https://github.com/odoo/odoo/pull/285591 where I missed one occurence during forward-port. My bad. runbot-946570 Forward-Port-Of: odoo/odoo#288519
This fix restores the correct spacing around status bars when they appear inside dialog windows. It improves visual consistency and prevents cramped layouts in affected Odoo forms.
Original PR description
| Master | This PR | |--------|--------| | <img width="1016" height="393" alt="image" src="https://github.com/user-attachments/assets/5c60052d-c95b-4351-8ed5-ae122d4db5d6" /> | <img width="1006" height="312" alt="image" src="https://github.com/user-attachments/assets/6b88796f-5eb9-4fb8-b685-b59feed796e9" /> | This PR fixes an oversight from Commit[^1] which omitted the scenario of a statusbar rendered within a dialog. As we relied on the padding utility class for this scenario, we need to set the CSS variable in the dialog context as well. [^1]: https://github.com/odoo/odoo/commit/95e354c75386dc514e8fd0905ab8d348c7fb6ecd task-6578339 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix lets local electronic invoicing rules require a description field when needed. It helps prevent validation errors when generating or submitting electronic documents in countries or formats where that field is mandatory.
Original PR description
In a recent commit, odoo/odoo@c5037bb, we removed the product name from the description field, making the Description node optional for all localisations. This can lead to validation errors when generating or submitting electronic documents. Since individual localisations may enforce their own EDI requirements, this commit adds support for making the Description node mandatory in EDI overrides. See Also: - https://github.com/odoo/enterprise/pull/131081 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Message previews in Odoo Mail now prevent links and mentions from triggering their own actions when clicked. This helps users reliably open the intended conversation or related record from previews without accidental navigation or unwanted interactions.
Original PR description
Prior to this commit, clicking links or mentions in the message preview could trigger their actions instead of opening the related record. This could happen when clicking the preview from the messaging menu, while links and mentions in the chat bubble preview could also be clicked directly. This commit prevents clicking links and mentions from triggering their actions in message previews in both the messaging menu and chat bubbles. The links and mentions keep their visual appearance, but clicking the preview now only opens the related record in messaging menu and does nothing in bubble preview. Task-6569382 https://github.com/user-attachments/assets/8565bfa2-848f-424e-8378-bcacc43dfba8 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes an error that occurred when users opened sale or purchase receipts from Invoice Analysis. Businesses using receipts can now review related records from reports without interruption.
Original PR description
When enabling Sale/Purchase Receipts and trying to open the form view from Invoice Analysis, an error occurs. The issue is caused by the `move_type` used in `_where()`, which includes a type that is not defined in the `move_type` field selection. Steps to reproduce: - Enable Sale/Purchase Receipts. - Create a Sale/Purchase Receipt for partner A and confirm it - Go to Invoice Analysis and open the Pivot view - Click on a cell to open partner A's receipt, then try to open the form view - Error Ticket [link](https://www.odoo.com/odoo/project.task/6462153) opw-6462153 Forward-Port-Of: odoo/odoo#288425 Forward-Port-Of: odoo/odoo#282922
Fixed an issue that stopped the Timesheet Assistant from creating a summary when users grouped more than two AI suggestions. The assistant now uses the correct lookup method, so grouped suggestions can be summarized as expected.
Original PR description
Grouping more than two Timesheet Assistant suggestions called `/ai/get_direct_response` with agent_id. That route no longer accepts an agent id: it resolves a composer from interface_key and raises 404 when none is found, so the summary never ran. Register a timesheet_assistant_ai composer and pass that key from the client. task-6570754
This fixes electronic document generation for Colombian and Peruvian localizations by ensuring required description fields are included where local rules demand them. It helps prevent validation or submission errors after a recent change made descriptions optional more broadly.
Original PR description
In a recent commit, https://github.com/odoo/odoo/commit/c5037bb, we removed the product name from the description field, making the Description node optional for all localisations. This can lead to validation errors when generating or submitting electronic documents. Since individual localisations may enforce their own EDI requirements, this commit adds support for making the Description node mandatory in specific EDI overrides. See Also: - https://github.com/odoo/odoo/pull/287566
External attendees who cannot access an unpublished appointment type will now see a warning asking them to contact the organizer instead of hitting an error page when trying to reschedule. Cancellation remains available and now takes attendees to the cancelled event page, while backend-created appointments handle reschedule and cancel actions correctly.
Original PR description
**Purpose:** To reschedule, the attendee is sent to the appointment type page to pick a new slot. That page requires read access on the appointment type, which an external attendee does not have on an unpublished appointment and they get a 403, or a 404 with website_appointment installed. **Specifications:** - An attendee with no access to the appointment type should not be allowed to select slots, so the reschedule button now returns a warning message asking to contact the organizer. - Cancelling is still allowed as it does not need that page, and the cancel button now redirects to the cancelled event page instead. Task-6570481
The change prevents installation failures when using Dutch VAT reporting by making shared VAT payment warning settings available outside the Belgian localization. This helps affected companies install and use the reporting module without duplicate setup logic or broken views.
Original PR description
*: account_reports, l10n_be_reports --- Description of the issue this commit addresses: Since commit 8a2d22f9fdac, the Dutch VAT payment wizard view references a warning field and configuration action defined only by the Belgian localization. Installing l10n_nl_reports therefore fails during view validation. --- Desired behavior after this commit is merged: This commit moves the shared field and action to the generic QR payment wizard, making them available to both localizations without duplication --- task-6578161
The Point of Sale product configurator now only shows extra-price labels when those extras will actually be charged. This prevents cashiers and customers from seeing misleading price add-ons when a fixed pricelist keeps the final product price unchanged.
Original PR description
Steps to reproduce: - Create a pricelist "TAKEAWAY" with a fixed price of 10.00 on a product whose sales price is 20.00 - Create a preset "TAKEOUT" and set its pricelist to "TAKEAWAY" - Add to that…
Steps to reproduce: - Create a pricelist "TAKEAWAY" with a fixed price of 10.00 on a product whose sales price is 20.00 - Create a preset "TAKEOUT" and set its pricelist to "TAKEAWAY" - Add to that product an attribute with variant creation "Never", with a value carrying an extra price of 1.00 - In the POS, switch to the preset "TAKEOUT" and click the product Issue: The configurator advertises the attribute value with a "+ $ 1.00" badge, but that extra is charged nowhere: the title of the popup and the resulting order line both stay at the 10.00 of the pricelist. Cause: A fixed pricelist rule replaces the whole price of the product, the attribute extra prices included: _compute_price on product.pricelist.item returns fixed_price and never reaches _compute_base_price, the only place where _get_attributes_extra_price is taken into account. getPrice is a faithful port of that and overwrites `basePrice + price_extra` with rule.fixed_price. The configurator, however, rendered its badges out of value.price_extra alone, without ever asking what the pricelist of the order does with it. Fix: Only advertise an extra price when the price of the product actually reflects it, the way website_sale already does with the show_extra_price of _get_additionnal_combination_info. Asking getPrice covers more than a fixed rule: a rule based on another pricelist recurses with no extra either, and a full discount leaves nothing of it. Combo items keep their badges, since computeComboItems adds their extras on top of the combo price, like _get_combo_item_display_price does. opw-6528187 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#287740 Forward-Port-Of: odoo/odoo#286475
This fixes an unwanted gap between the control panel and the settings form in Odoo Enterprise. The change makes the settings page layout appear more consistent and polished for users.
Original PR description
In Enterprise, the spacing between the control panel and the settings form view is not wanted. COM: https://github.com/odoo/odoo/pull/288107 task-6570898
This update cleans up several manufacturing and inventory screens so key status information is clearer and visual icons are more consistent. It also fixes a display issue where draft manufacturing orders were missing their status indicator, helping users scan work orders and stock operations more reliably.
Original PR description
1) the state of an MO now stays on one line in the work order kanban view 2) the icon of package is changed to package_2 in the smart button and kanban view 3) remaining time and date is hidden on a work order card in the kanban view 4) fixed a bug where draft manufacturing orders didn't have a state bubble in the MO kanban view --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Manufacturing and work order cards now display key status information more consistently and with cleaner visuals. This makes it easier for users to scan production status, identify draft orders, and recognize package-related actions without visual clutter.
Original PR description
1) the state of an MO now stays on one line in the work order kanban view 2) the icon of package is changed to package_2 in the smart button and kanban view 3) remaining time and date is hidden on a work order card in the kanban view 4) fixed a bug where draft manufacturing orders didn't have a state bubble in the MO kanban view
This fixes an issue where portal users could not open chat conversations if they did not have access to the related contact record. The chat view now handles avatars in this case, restoring access to discussions from the portal.
Original PR description
Before this commit, a user was not able to access a chat if not having access to the partner. Steps to reproduce: Log in as 'Admin' and create a chat with a portal user Send a message in the same chat Log in as the portal user > My Account > Discuss go to the 'chat' tab To fix this issue, we follow a similar approach as livechat and generate the avatar in that specific case. task-6455893 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes an issue where translated labels for partner additional identifiers were not displayed correctly in views. The change ensures labels are translated before rendering, reducing test failures and preventing confusing untranslated text for users.
Original PR description
Problem: Failing tests revealed that the lazy translated labels of the additional identifiers from the multi id latam refactor were not finding translations in the t-out of the views. Markupsafe is resolving the lazy translation first without an env which resulted in the error of not finding a translation. Solution: Resolve the lazy translation of the labels with an established helper method in Python before it hits Markupsafe. Related PR: https://github.com/odoo/enterprise/pull/117163 runbot-build-error-947021 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The Planning and Sales Planning apps now correctly create a new planning entry from the Plan dialog when users click an empty schedule cell. This prevents an error message and lets teams continue scheduling work without interruption.
Original PR description
Before this commit, when clicking on an empty cell and when the "Plan" dialog was opened, the "Create New" button produced a traceback. This was because the "assign_slot" rpc was called in "props.onSelected" instead of "props.onCreateEdit". Because "onCreateEdit" not overriden in the planning module, it was defaulting to "onSelected". We fix this by overriding "onCreateEdit" in the planning module and calling the "create" method of the model. task-6574764 version: 20.0
Validated time off that is shortened, such as when an employee leaves mid-leave, now keeps the employee calendar in sync instead of removing the related absence entry. This prevents payroll from incorrectly counting those time off days as worked attendance, improving accuracy for final payslips.
Original PR description
Problem ------- Fixes bug caused by PR odoo#249527. When a validated time off's dates are shortened while it stays validated (e.g. when the employee's departure date falls int he middle of the…
Problem ------- Fixes bug caused by PR odoo#249527. When a validated time off's dates are shortened while it stays validated (e.g. when the employee's departure date falls int he middle of the leave), the linked resource.calendar.leaves record was unconditionally unlinked. To reproduce: 1. Create and validate a time off request covering a whole month. 2. Register the employee's departure with a departure date in the middle of that time off. 3. Generate the employee's last payslip. The leave is correctly cut at the departure date, but since it never leaves the `validate` state, it never goes through `_validate_leave_request()` again, so its resource.calendar.leaves record is never recreated. The days that were covered by the deleted entry are no longer blocked in the employee's resource calendar, so the payslip's worked day lines (computed from resource.calendar.leaves) count them as attendance instead of time off. Cause ----- `hr.leave.write()` removed the resource.calendar.leaves record any time either the state changed away from `validate` or the leave's dates changed, regardless of whether the leave remained validated. Date-only changes on an already-validated leave never re-trigger validation, so the entry was not recreated. Solution -------- Only remove the resource.calendar.leaves record when the leave actually loses its validated state. When a validated leave's dates change but it stays validated, amend the existing resource.calendar.leaves record in place instead, falling back to creating one if none exists. Related PR: odoo#249527 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#288070 Forward-Port-Of: odoo/odoo#286465
The Spanish VAT Books report was failing to open because it referenced an outdated page element. This update aligns the report with the current interface so users can view the VAT Books report normally again.
Original PR description
The chatter icon in account_reports's line_name.xml was changed from a <button t-if="line.chatter"> to an <i t-if="this.hasChatter()">. l10n_es_reports's VatBooksLineName template still targeted the old button element, so the inherited view could no longer find its xpath target and the VAT Books report failed to render. Update the xpath expression to match the current base template structure. task-6571232
The website sitemap generation now loads only the page data it needs instead of pulling large design history fields into memory. This helps sites with many pages generate sitemaps more reliably and reduces the risk of crashes during indexing-related tasks.
Original PR description
- Before this commit: All fields of ir.ui.view were prefetched, including arch_db and arch_prev. This caused an out-of-memory issue when dealing with many pages. - After this commit: Only required fields are fetched, avoiding unnecessary memory consumption from view architecture data. opw-6470593 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#284945
Website tabs using button or tab styles now correctly apply selected theme backgrounds and automatically adjust link colors for readability. This makes designed page sections more consistent with the chosen brand theme and avoids manual color fixes.
Original PR description
*: html_builder, html_editor Steps to reproduce: - Drop a tabs snippet on the website builder - Switch the style to "Buttons" or "Tabs" - Select a theme (color combination) background => It isn't applied. After this commit, the color combination is properly applied. In addition: - When a theme is selected, the links custom color is applied on inactive tabs (the active one takes the color of the theme). - When a solid or gradient background color is selected, the links custom color is applied on all links (including active), but the active button takes a default background with an opacity (white/black depending on the link's color luminance) - When selecting a background, the links color is adapted to constrast with the background. - After designing the "button" or "tabs" styles, if you go back to "underline" or "pills" styles, the colors are reset (because they cannot be adapted from those styles). task-5951656
Fixed an issue where adding a property in worksheet templates could open the setup popover in read-only mode with a broken layout. The system now checks editing permissions at the right time, so users can configure properties as expected without needing to reload the record.
Original PR description
1. Open Planning > Configuration > Worksheet Templates and open a template 2. Click "Add Property" -> the definition popover opens read-only and its layout is broken During the migration to owl3, the `useLayoutEffect` updating `canChangeDefinition` was changed to a `useEffect`. This makes it run during setup rather than after mounting, so it runs while the edit mode is still off, returns early, and never performs the check that would set `canChangeDefinition`. Due to the fact that the condition inside the `useEffect` is only present inside the `untrack`, the effect never subscribes to it, so it is only re-run when the record is reloaded and `canChangeDefinition` remains false in the meantime. With this commit, the `untrack` is dropped so that the effect subscribes to its own condition and the check runs as soon as the field becomes editable. Task-6469849
Company-paid expenses now open the related accounting move correctly even when no supplier bill exists or is expected. The update also removes an obsolete internal option in expense handling, reducing maintenance overhead without changing day-to-day workflows.
Original PR description
## [FIX] hr_expense: Fix existing bill view
Fix an issue where company paid expenses
would refuse to display the move if there was no linked bill, even for cases where there would be no existing bill ever
## [IMP] {hr,sale}_expense: Remove deprecated parameter
Remove the check parameter as it is not used anywwhere anymore
Related: https://github.com/odoo/enterprise/pull/131561The website cookie policy now lists the timezone cookie alongside the existing language preference cookie. This helps ensure visitors receive a more complete explanation of essential cookies used before consent is requested.
Original PR description
The cookie policy page must disclose every cookie stored on a visitor's device, including the essential ones set before any consent is given. Add tz to the existing "Preferences (essential)" row next to frontend_lang, and extend that row's purpose to mention the timezone. task-6470891
This fixes Belgian payroll leave handling so public holidays during long economic unemployment are only employer-paid within the legally allowed first 14 calendar days. It prevents incorrect payment for holidays from day 15 onward and preserves the correct final leave day in payroll calculations.
Original PR description
The employer pays a public holiday during economic unemployment only when it falls in the first 14 calendar days. The window ended one day too late, and any segment crossing it took over every remaining day. A holiday on day 15 was paid, together with the days after it, and the last day of the leave was lost. task-6566666
The chat input request button now uses the standard filled secondary button style instead of a custom border. This keeps the Discuss interface visually consistent with the product theme and improves polish for users.
Original PR description
Drops the inline `border-black` override in favour of proper theme btn styling. task-6528352 | Before | After | |--------|--------| | <img width="392" height="639" alt="image" src="https://github.com/user-attachments/assets/99990e51-b9d9-4b1d-b76a-6ad89422cc18" /> | <img width="390" height="648" alt="image" src="https://github.com/user-attachments/assets/06b64fed-82ca-44cf-b3d8-af7a5a0d6556" /> |
This fixes an internal accounting test so it only checks identifiers that belong to the accounting area. It helps keep automated validation accurate and reduces false failures in development, with no expected change for end users.
Original PR description
The xmlids are defined in `account_reports` runbot-946593
Expense policy limits for job positions are now displayed in the company currency, matching how those limits are configured. This helps avoid confusion when reviewing or applying employee expense rules, especially in multi-currency contexts.
Original PR description
Display job position expense limits using the company currency to match how the limit amount is configure. Also clean up the limit model by moving it to its own file. task-[6445873](https://www.odoo.com/odoo/project/967/tasks/6445873) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The meeting-ready banner is no longer shown in one-to-one direct messages, where inviting others is not applicable. This prevents users from seeing an empty invitation link and keeps the chat experience clearer.
Original PR description
The "Your Meeting is Ready" banner offers to add more people to the call and shows a permanent invitation link to share with them. It is meant for conversations that can grow. In a DM there is nobody else to add, and DMs have no invitation link, so the link input rendered empty. Hide the banner for chat conversations. <img width="2742" height="689" alt="meeting-banner-dm-before-after" src="https://github.com/user-attachments/assets/7eaa527d-8260-4c8c-9425-343cca974d9b" />
Sales users can once again drag and drop request for quotation files onto the Quotations list or kanban views. This fixes a failed upload message and restores the intended quick upload workflow.
Original PR description
Versions -------- - saas-19.4+ Steps ----- 1. Install Sales (with `sale_management`); 2. open Sales > Orders > Quotations; 3. drag a request for quotation file onto the list. Issue ----- The drop…
Versions -------- - saas-19.4+ Steps ----- 1. Install Sales (with `sale_management`); 2. open Sales > Orders > Quotations; 3. drag a request for quotation file onto the list. Issue ----- The drop zone appears, but dropping the file only raises a "Could not upload files" notification. Same in the kanban view. Cause ----- `UploadDropZone.onDrop` hands the dropped files to the closest input matching `.document_file_uploader.o_input_file`. Commit d1742c42 moved the RFQ upload into the cog menu with a template overriding `account.DocumentFileUploader`'s, but without forwarding `fileUploadClass` to the `FileUploader`, so that input never carried the class. This went unnoticed because `saleFileUploadListView` inherited `account.FileuploadListView.Buttons`, which renders `account.DocumentViewUploadButton` and therefore a matching (hidden) input the drop zone could fall back on. Commit 00545bdd patched `saleFileUploadListView` and `saleFileUploadKanbanView` to use the `sale_management` button templates, which inherit `web.ListView.Buttons` instead, removing that input and leaving the page with no drop target at all. Solution -------- Set `fileUploadClass` on the cog menu's `FileUploader`. The drop zone now targets the RFQ uploader itself rather than the account one, so dropped files go through `QuotationRequestUploader.getResModel` as intended. opw-testing-day-v20 Forward-Port-Of: odoo/odoo#288293
The quotation document kanban card layout now has better spacing, making it easier to scan and read. This small visual fix improves the sales quotation builder experience without changing any business workflow.
Original PR description
The kanban card lacks spacing. task-6566640 | Before | After | |--------|--------| | <img width="1307" height="254" alt="image" src="https://github.com/user-attachments/assets/aff159f8-cddc-4b44-b98a-5609c0bf5748" /> | <img width="1363" height="274" alt="image" src="https://github.com/user-attachments/assets/23d135ae-79b0-4287-9d5c-81e44716324c" /> | --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Automation rules that run when a field reaches a target value now avoid running twice during record creation. This prevents duplicate emails, activities, or other automated actions when Odoo computes a default value while creating a record.
Original PR description
An automation rule triggered when a field reaches a specific value can run its actions twice when a record is created without that field provided explicitly. For example, a rule that sends one email…
An automation rule triggered when a field reaches a specific value can run its actions twice when a record is created without that field provided explicitly. For example, a rule that sends one email and schedules two activities can send two emails and schedule four activities for one record. ### Reproduction Steps Create an automation on `crm.lead` that triggers when the stage is set to "New", with one email action and one activity action. Create an opportunity through the website contact form, which leaves the stage unset. The lead is assigned to the "New" stage, but both actions run twice. ### Cause The lead stage is computed and read during creation. That computation can trigger the automation before the creation hook processes the same record, causing both paths to run the actions. The processing code tracks records already handled during nested computations. The feedback flag used for this tracking is attached to the records, but the code checked the automation context instead. When the computation was triggered during creation, the flag was therefore missed. ### Fix Read the feedback flag from the records so nested computations update the shared tracking state. The creation hook then skips records already processed by the computation. opw-6331134 Forward-Port-Of: odoo/odoo#288222
Gantt views now correctly hide unavailable time columns even when bookings or records have no value in the grouped field. This prevents the "Undefined" row from making off-hours appear available, giving users a cleaner and more accurate schedule view.
Original PR description
Folding a column requires it to be unavailable on every row, which means ignoring the "Undefined X" one: no record stands behind it, so the server sends no unavailability for it, which reads as "available at all times" and prevents any folding. That row was spotted as the one without any record, but it gathers the records with no value on the grouped by field: a single booking with no resource in the appointment gantt was enough to bring folding back to nothing. Record-less rows are not placeholders either, as group_expand returns real ones (every resource, every employee) whose unavailabilities do count. It is now spotted through the resId its unavailabilities are read from, which is false for it whether it holds records or not.
This fixes an unwanted extra line that could appear in list views when no footer totals were shown, especially with sample data or empty results. The change makes the interface look cleaner and avoids visual confusion for users reviewing lists such as Contacts.
Original PR description
Since 50b1ceabf1b2, the list view redesign gives the footer cells a top border, and at the same time drops their padding when they are empty, so that a footer without any aggregate takes no space. Both rules contradict each other: the row is squashed to a zero height, but its border keeps being painted. And since the table borders are collapsed, that border is painted by the table itself, so it also ignores the opacity the sample mode applies to the footer. Hence the line, especially visible with sample data where everything else is faded out. Only draw the separator when the footer actually holds something, the way the x2many list footers already do in form views. Steps to reproduce: - go to Contacts - add a favorite filter matching no record - go back to the list view: the sample data is displayed, and a stray line is drawn right under the last row
Instagram posts now allow more time to complete when images are involved. This reduces failed posts caused by timeouts because Instagram needs to download the image from Odoo before publishing.
Original PR description
Bug === On some database on the saas, timeout issue happen for Instagram. Because Instagram downloads the image on our server, it needs more timeout than other social media. Task-6547753 Forward-Port-Of: odoo/enterprise#131632 Forward-Port-Of: odoo/enterprise#131069
Leads created from WhatsApp conversations in Discuss now automatically include the related customer contact. This prevents sales teams from receiving incomplete leads and reduces manual correction after creating CRM opportunities from WhatsApp chats.
Original PR description
### Steps to reproduce: - Install 'whatsapp', and 'crm_livechat' - Configure a WhatsApp channel and receive a message to create a conversation in Discuss - Open the WhatsApp conversation in Discuss -…
### Steps to reproduce: - Install 'whatsapp', and 'crm_livechat' - Configure a WhatsApp channel and receive a message to create a conversation in Discuss - Open the WhatsApp conversation in Discuss - Click on the 'Create Lead' smart button - Check the created lead > The Customer/Contact field is empty ### Cause of Issue: When a lead is created from a Discuss conversation, `_convert_visitor_to_lead` in `crm_livechat` attempts to set the lead's customer. It does this by checking if the channel has `livechat_customer_partner_ids`. However, in whatsapp discuss conversations, the client is saved in `whatsapp_partner_id` and `livechat_customer_partner_ids` is empty. https://github.com/odoo/odoo/blob/b8f3a5c1d2a673fd896d3b8c2968d68e9fcefe19/addons/crm_livechat/models/discuss_channel.py#L56-L58 ### Fix: Kept the fix local to `crm_livechat` and checked whether `whatsapp` is installed before reading `whatsapp_partner_id`, which would otherwise raise an `AttributeError` since `crm_livechat` does not depend on `whatsapp` and vice versa. opw-6371274 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#283008
This fixes a Point of Sale issue where removing a coupon reward could prevent the customer list from opening. Staff can continue managing customers and coupon-related loyalty cards without the checkout screen crashing.
Original PR description
Steps to reproduce: - A coupon program with a coupon assigned to a customer - In the PoS, set that customer on the order - Enter the coupon code, its reward line is added - Remove the reward line -…
Steps to reproduce: - A coupon program with a coupon assigned to a customer - In the PoS, set that customer on the order - Enter the coupon code, its reward line is added - Remove the reward line - Click the customer button Issue: The customer list does not open. The PoS crashes with "TypeError: Cannot read properties of undefined (reading 'id')" raised while rendering PartnerLine. Cause: `partnerId2CouponIds` maps a partner to the ids of its `loyalty.card` records. It is filled at boot and on every `loyalty.card` create, but nothing ever removes an id from it: the models only trigger a create event. Removing the reward line of a code activated coupon deletes that card from the local models (`_setValue` in the order summary), so its id stays in the map while the record is gone. `getLoyaltyCards` pushed `models["loyalty.card"].get(id)` unconditionally, hence an `undefined` entry in the list the PartnerLine template iterates over with `t-key="_loyaltyCard.id"`. Fix: Skip the ids whose record no longer exists. The partner keeps its remaining cards, and the path where no card was deleted is unchanged. The stale id is not pruned from the map: it is reached through the reactive store proxy, and mutating it there would notify subscribers in the middle of a render. opw-6517564 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#287503 Forward-Port-Of: odoo/odoo#286971
This fix ensures that when a Point of Sale session cannot be closed cleanly because its accounting entry is unbalanced, the user is shown the proper force-close wizard instead of seeing a misleading successful close. This helps prevent missing accounting entries and unposted cash differences.
Original PR description
When the closing journal entry of a session is unbalanced, `_process_session_validation` in point_of_sale rolls back the transaction and returns the "Force Close Session" wizard action, which…
When the closing journal entry of a session is unbalanced, `_process_session_validation` in point_of_sale rolls back the transaction and returns the "Force Close Session" wizard action, which `_validate_session` returns to the user so the difference can be posted on a chosen account. The pos_stock override of `_process_session_validation` calls `super()` without returning its result. The action is dropped, `_validate_session` carries on, and the session is written as `closed` while the rolled-back entry no longer exists: `move_id` is empty, the orders stay in `paid`, `cash_real_transaction` stays at 0 and the cash difference is never posted. The user sees a successful close and nothing in accounting. Steps to reproduce: - Use a stock configuration whose costs yield a rounding difference on the closing entry (e.g. AVCO products with a sale and a return whose unrounded costs round differently when split between the expense and valuation lines). - Close the session from the PoS. - The session is closed, no journal entry exists, and no wizard was shown. Return the result of `super()` so the wizard is shown as in 19.0. opw-6543863 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#287618
Point of Sale cash register closing messages now correctly include cash in/out entries made by POS administrators who do not have accounting permissions. This prevents false closing differences from appearing after a register is closed, improving trust in cash control reports.
Original PR description
Steps to reproduce: - Give a user PoS Administrator rights and no Accounting rights. - As that user, open a session with cash control, sell something paid in cash and do a Cash Out. - Close the…
Steps to reproduce: - Give a user PoS Administrator rights and no Accounting rights. - As that user, open a session with cash control, sell something paid in cash and do a Cash Out. - Close the register. The closing popup shows the expected cash (opening + cash payments - cash out); enter exactly that amount, the popup shows no difference. - Open the closed session: its chatter says "Closing difference: -X", X being the cash out amount, and "Closing expected" is the amount before the cash out. Issue: The closing control data agrees with the user, but the closing message records a cash difference equal to the cash out. Cause: `_compute_cash_balance` sums `statement_line_ids` with the rights of the current user. Cash moves are `account.bank.statement.line` records, which `_inherits` `account.move`, so the account.move record rules apply to them too. For a PoS user the only such rule is `rule_invoice_pos_user` (`pos_order_ids != False`), and a cash move has no PoS order: unless the user is in `account.group_account_invoice`, their own cash moves are filtered out and `cash_register_balance_end` ignores them, while `get_closing_control_data` sums the lines in sudo. Since da8be203ec32 PoS managers can create cash moves without any accounting group, which made this visible: in 18.0 cash in/out required `account.group_account_invoice`, whose `account_move_see_all` rule makes every move readable. The values stored at closing are right by accident: `_validate_session` reads the lines in sudo just before, and the one2many cache is shared between the sudo and non-sudo environments of the same transaction. The message posted by `update_closing_control_state_session` runs in its own transaction and gets the filtered sum. Fix: Read the cash lines in sudo in `_compute_cash_balance`, as `get_closing_control_data`, `get_cash_in_out_list` and `_validate_session` already do. Users with accounting rights see all lines already, so nothing changes for them. opw-6521591 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#287741 Forward-Port-Of: odoo/odoo#286308
This fixes a Point of Sale issue where selling multiple physical gift cards with the same value could combine them into one order line, preventing staff from entering a unique code for each card. Orders with multiple gift cards should now validate and sync correctly, reducing checkout failures and duplicate-code problems.
Original PR description
Steps to reproduce: - Create a gift card program (several programs sharing the same gift card product show the same issue) - In the PoS, sell a physical gift card: click the gift card product and set…
Steps to reproduce:
- Create a gift card program (several programs sharing the same gift card product show the same issue)
- In the PoS, sell a physical gift card: click the gift card product and set a code through "Sell physical gift card?"
- Click the gift card product again to sell a second physical card of the same value
- Validate the order
Issue:
The second unit is merged into the already coded orderline (one line, qty 2, one code), so the "Sell physical gift card?" link is no longer displayed and the second code cannot be entered. Validating the order then fails with "The operation cannot be completed: A coupon/loyalty card must have a unique code." and the order stays unsynced: the qty 2 line is split into two point entries both carrying the same gift_code, so two loyalty.card records are created with the same code.
Cause:
_setupGiftCardOptions() (and setupEWalletOptions()) pass merge=false so that a gift card line is never merged, and until 17.0 add_product() honored it ("options.merge !== false"). The 18.0 store refactoring dropped it: addLineToOrder() decides merging from a local variable that is only set to false when a price_unit is given in vals, and never reads opts.merge. The option became dead code, in point_of_sale's addLineToOrder as well as for the pos_discount caller.
Fix:
Honor opts.merge === false in addLineToOrder(). Callers that do not pass the option are unaffected, so the default merging behaviour is byte-for-byte the same; only the callers explicitly forbidding a merge (gift card, ewallet and discount lines) get their pre-18.0 behaviour back.
opw-6466324
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#287486
Forward-Port-Of: odoo/odoo#286237Preparation tickets from self-order flows are now sent through the Odoo Box point-of-sale printing setup. This helps kitchen or preparation staff receive the right tickets when customers place orders themselves, reducing missed or delayed order preparation.
Original PR description
Following this commit : ==== - Preparation ticket will be printed through obox in self order task-6255005 Related PR : https://github.com/odoo/odoo/pull/269216
This fix ensures Odoo resets an internal performance counter for the registry itself, not just individual models. It matters for large combined test runs because it prevents Python from disabling a cache that can slow or destabilize extended testing.
Original PR description
reset_classes_tp_versions_used() was only ever fed model classes (registry.values() / self.values()), never the Registry class itself. Since Registry._lock (among others) gets patched on every HttpCase setUpClass/tearDownClass, the shared Registry class silently exhausts CPython 3.13's per-type version-tag budget (1000) over a long test run, permanently disabling its attribute cache, while the periodic reset kept "succeeding" on every other class. This causes issues particularly when testing all the modules in Odoo Community + Enterprise in a single go (not like in runbot)
This update reduces excess spacing around the form view control area and status bar for a cleaner, more balanced layout. It also adjusts the chatter area spacing so the page background and content alignment look more consistent across Odoo editions.
Original PR description
There is too much spacing under the control panel when we are in a form view and the community spacing doesn't work with the background. This commit reviews the spacing of the o_form_statusbar and control_panel, adapted in community and enterprise to a better visual balance. This change requires us to adapt the chatter spacing, removing the margins on the inner element to rely on a padding on the .o-mail-Chatter-topbar instead. task-6531145 Enterprise PR: https://github.com/odoo/enterprise/pull/130825 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The spreadsheet command palette now hides actions that users cannot access from the regular spreadsheet menu. This prevents users from seeing unavailable options and keeps the experience consistent across the interface.
Original PR description
Some items are displayed in the command palette while being hidden in the spreadsheet interface. With this revision, we synchronize the availability of a menu item between the topbar menu and the command palette. Task-6352180 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#273294
The help text for leave type pay rates now explicitly explains that unpaid leave should be configured at 0%. This reduces confusion for HR users when setting up leave policies and helps avoid incorrect payroll-related configuration.
Original PR description
- Update the help tooltip of the pay_rate field on leave types to explicitly mention the 0% configuration for unpaid leaves, preventing user confusion. task-6574198
This update fixes the setup for Latin American check tests so they no longer depend on unnecessary country-specific data. It makes the test suite simpler and more reliable, reducing the risk of false failures during development and quality checks.
Original PR description
Some tests were relying on latam documents or AR master data for no good reason. It only make sense to tests the third party checks with an Argentinean company. Most of the tests should run on a company of any localization. We create two separate setup to reflect that fact, and remove some useless complexity where we can. runbot-947000
This fix ensures Odoo correctly recognizes when a field has no real unsaved change after a user retypes the same value in a different format. It prevents the Save and Discard buttons from remaining stuck on screen when there is nothing left to save, reducing user confusion in forms.
Original PR description
**Description of the issue/feature this PR addresses:** Fixes #287978 In `useInputField` (`input_field_hook.js`), `onChange` and `commitChanges` only trigger the `FIELD_IS_DIRTY` bus event with…
**Description of the issue/feature this PR addresses:** Fixes #287978 In `useInputField` (`input_field_hook.js`), `onChange` and `commitChanges` only trigger the `FIELD_IS_DIRTY` bus event with `false` when the newly typed value actually differs from the value already stored on the record. When the typed text parses to the *same* value as what is already on the record (e.g. retyping `6,250` after the field already holds `6,25`), the code takes the `else` branch, which only resets the displayed text and never notifies the bus that the field is no longer dirty. `form_status_indicator.js` keeps whatever `fieldIsDirty` state it last received from that bus event, and shows the Save/Discard buttons whenever `root.dirty || fieldIsDirty`. Since nothing ever fires `FIELD_IS_DIRTY(false)` in that `else` branch, `fieldIsDirty` stays stuck at `true`. `Discard` correctly resets `root.dirty`, but has no way to reset `fieldIsDirty`, so the Save/Discard buttons keep showing even though the record is clean. **Current behavior before PR:** 1. Edit a field to a new value, click away (value committed, indicator shows Save/Discard as expected). 2. Edit the same field again, this time typing different text that parses to the *same* value (e.g. `1.20` when the field already holds `1.2`), click away. 3. Click **Discard**. The record is reverted, but the Save/Discard buttons remain visible. They stay stuck until the page is reloaded. **Desired behavior after PR is merged:** Retyping different text that parses to the same value clears the field's dirty state like any other case where the field ends up unchanged, so Discard (or any other action) correctly hides the Save/Discard buttons once there is nothing left to save. Forward-Port-Of: odoo/odoo#288030
Customers switching from store pickup to a country-specific delivery option now see the correct delivery charge instead of it remaining free. This prevents misleading checkout totals and ensures eligible delivery methods are priced using the customer's address.
Original PR description
Steps to reproduce: - Install eCommerce and Click & Collect. - Publish Pick up in store with a warehouse whose address is in country A (e.g. United States). - Publish a country-specific delivery…
Steps to reproduce: - Install eCommerce and Click & Collect. - Publish Pick up in store with a warehouse whose address is in country A (e.g. United States). - Publish a country-specific delivery method (Fixed Price, non-zero) limited to country B (e.g. Spain). - On the shop, checkout with a delivery address in country B. - Select Pick up in store, then select the country-specific method. Issue: Selecting the country-specific method keeps Delivery at 0 (Free). The same happens with country-restricted connectors: `/shop/set_delivery_method` never applies the method, so no rate is requested for that switch. Cause: Since saas-19.3, a pickup location replaces `partner_shipping_id` with a generated pickup address. `/shop/set_delivery_method` only calls `_set_delivery_method` if the method is in `_get_delivery_methods()`, which matches on the shipping address. The pickup country makes the country-specific method look unavailable, so it is never applied. The order still has the pickup method (0 delivery), and the summary reports the selected method as Free. Match availability on the customer when shipping is a pickup address, and restore that address before rating the method that is being set. Keep the Based on Rules check so a method with no applicable price rule is not listed after pickup. opw-6493956 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#285068
This fix removes leftover component records that could be created when users manually adjust subcontracted production components. It helps prevent later inventory reservation and transfer validation errors caused by incomplete background records.
Original PR description
#### Issue When manually adding component lines in the subcontracting Record Production flow, extra stock move lines can remain in the database without a linked stock move. Those lines have no…
#### Issue When manually adding component lines in the subcontracting Record Production flow, extra stock move lines can remain in the database without a linked stock move. Those lines have no move_id, so their related state is empty. They can later be selected by stock reservation code and cause validation errors when processing the transfer. #### Steps to reproduce 1. Create a subcontracted product. 2. Confirm a subcontracting receipt/purchase flow for that product. 3. Open the subcontracting Record Production popup. 4. Remove an existing component line. 5. Add a new component line for another storable product available at the subcontractor location. 6. Save/record the production. 7. Check stock.move.line records , Inventory > History > Group By Status. An extra stock move line is left with no move_id. #### Root cause The inverse of `mrp.production.move_line_raw_ids` already collects and deletes move lines detached from existing raw moves. However, when the user adds a new component product, the inverse creates a new additional raw move. Creating that raw move can also create reserved move lines. The inverse then replaces `move.move_line_ids` with the user-entered lines, but it did not collect the newly created reserved lines before replacing them. Those reserved lines were detached from the move and left in the database as orphan stock move lines. #### Fix Apply the same cleanup logic to newly created additional raw moves: collect their auto-created move lines before replacing `move_line_ids`, then unlink those detached lines at the end of the inverse. opw-6304649 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#281864 Forward-Port-Of: odoo/odoo#276235
Voice transcription requests are now sent in a format compatible with the updated service connection. The client also reads the new response format correctly, helping prevent transcription failures for call recordings and VoIP-related workflows.
Original PR description
Ok got it. 3 separate issues. 1st When we send audio for the transcription we used to send that over http, where we could have raw bytes, now we use json rpc, so we should base64 encode it first, addressed here 2nd When iap, requests the transcription request, and pipes it to the AI provider, it tries to unpack usage from the request. Which in the case of the VTT raw response is not there. Fixed here 3rd is that when odoo-client receives the transcription it tries to unpack the results. It looks for `result` key which got updated to `text` Thought about updating it on the iap side, but I see that realtime already uses it, so maybe let's keep it similar, so just updated it here This pr fixes 1s and 3rd, 2nd fixed on the iap side here https://github.com/odoo/iap-apps/pull/1909
Adjusted spacing around the form view control panel and chatter area to create a cleaner, more balanced layout. This fixes excessive empty space and keeps the interface visually consistent across Enterprise messaging and WhatsApp-related views.
Original PR description
*: mail_enterprise, whatsapp There is too much spacing under the control panel when we are in a form view and the community spacing doesn't work with the background. This commit reviews the spacing of the o_form_statusbar and control_panel, adapted in community and enterprise to a better visual balance. This change requires us to adapt the chatter spacing, removing the margins on the inner element to rely on a padding on the .o-mail-Chatter-topbar instead. task-6531145 Community PR: https://github.com/odoo/odoo/pull/287003
Corrects how fixed-rate taxes are calculated on Mexican electronic payment complements when an invoice is partially paid. This helps prevent payment CFDIs from being rejected by Mexican tax authorities or certification providers due to small tax amount mismatches.
Original PR description
When generating a payment complement, tax base and importe coming from the related invoice are prorated by the percentage actually paid, each rounded independently to the currency precision. The…
When generating a payment complement, tax base and importe coming from the related invoice are prorated by the percentage actually paid, each rounded independently to the currency precision. The post-fix step that restores the SAT invariant uses a Tasa-only formula (`base = total / (1 + rate)`), so Cuota (fixed amount per unit) taxes keep mismatched values, ending up with `ImporteDR != round(BaseDR * TasaOCuotaDR)`. This leads to CFDIs rejected by the PAC/SAT. Steps to reproduce: - Create a customer invoice with a Cuota IEPS tax (e.g. 26.2569). - Register a partial payment whose amount is not an exact divisor of the invoice total (e.g. one third). - Send the payment CFDI: the resulting Cuota TrasladoDR has an ImporteDR that does not match BaseDR * TasaOCuotaDR, leading to a rejected CFDI. This commit recomputes `importe` from the prorated `base` for Cuota taxes (bypassing the Tasa post-fix) opw-6087564 Forward-Port-Of: odoo/enterprise#131436 Forward-Port-Of: odoo/enterprise#113395
Australian payroll users can now register super payments successfully even when they open a super contribution from the Pay Runs kanban view. This prevents an incorrect pay run status from being applied to the payment process, avoiding an error and making the workflow consistent across entry points.
Original PR description
Current behavior: -- Registering a super payment from a pay run opened out of the Pay Runs kanban fails with "Wrong value for account.payment.state. The same super contribution registers without…
Current behavior: -- Registering a super payment from a pay run opened out of the Pay Runs kanban fails with "Wrong value for account.payment.state. The same super contribution registers without error when opened from Payroll > Reporting > Australia > Super Contributions. Expected behavior: -- Register Super Payment should work regardless of how the super contribution record was reached. Steps to reproduce: -- - Take an Australian pay run through to Paid - Open Payroll > Payslips > Pay Runs, kanban grouped by Status (default) - Open the pay run from the Paid column, then Super Submissions - Lock the super contribution and click Register Super Payment Cause of the issue: -- The Pay Runs kanban is grouped by state, so the web client adds default_state to the context of records opened from a column. That context follows the smart button into action_register_super_payment, where account.payment is created without an explicit state. The ORM applies default_state from the context which is a hr.payslip.run value that account.payment.state does not accept. The same leak reaches account.move through action_post, which creates the payment journal entry. Fix: -- apply with_context(clean_context(self.env.context)) to the recordset to remove the default_state key opw-6478084 Forward-Port-Of: odoo/enterprise#128724
The spreadsheet command palette is now consistently available from the top bar across all spreadsheet-related actions, not just document views. This fixes an access gap and makes spreadsheet tools easier to reach in different workflows.
Original PR description
The command palette was made available as a topbar menu item but it was only exposed in the document action. Task-6352180 Forward-Port-Of: odoo/enterprise#122423
Subscription invoices now use the earliest deferred start date across all invoice lines when setting subscription or upsell log effective dates. This prevents later invoice lines from overriding the correct start date, improving accuracy for subscription tracking and reporting.
Original PR description
When posting a subscription invoice, each invoice line overwrites the effective date of the subscription or upsell logs. The last line therefore determines the date, even when another line has an earlier deferred start. Use the earliest deferred start date on the invoice, falling back to the invoice date when no deferred start date is set. Forward-Port-Of: odoo/enterprise#131512
Portal users can now submit product reviews with attached files without hitting a misleading “Not Found” error. The fix ensures the website’s review settings are checked correctly during attachment uploads, so enabled review features work consistently.
Original PR description
A portal user cannot add an attachment when posting a review on a product page: submitting the review with a file attached fails with a generic "Not Found" error, while posting the exact same review…
A portal user cannot add an attachment when posting a review on a product page: submitting the review with a file attached fails with a generic "Not Found" error, while posting the exact same review without an attachment works fine.
Steps to reproduce:
-------------------
* Enable "Discussion and Rating" on a product page (Website > Customize)
* Log in as a portal user and open that product page
* Write a review, attach a file, then submit
> Observation:
"Not Found
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again."
Why the fix:
------------
`product.template._get_mail_message_access()` demotes a portal user's create access to 'write' whenever
`env['website'].is_view_active('website_sale.product_comment')` is False, since 'write' access is a deliberate way to block posting when the feature is toggled off for the website. `is_view_active` only picks the correct, website-specific view when `website_id` is present in `self.env.context`; that key is injected by the website frontend only for routes declared `website=True`.
`/mail/attachment/upload` is not `website=True` (attachments used to go through the dedicated, `website=True` `/portal/attachment/add` route, removed when portal's attachment uploader was unified with mail's), so `website_id` is missing from context on that route, `is_view_active` falls back to the generic, shipped-`active="False"` view, and always reports the feature as disabled - even when it is actually enabled for the current website. Create access is then wrongly demoted to 'write', which a portal user never has on `product.template`, so the thread lookup fails and the controller raises `NotFound()`.
Resolve the current website from the request itself (`env['website'].get_current_website()`) and inject its id into context before checking `is_view_active`, instead of relying on `website_id` already being in context. This makes the check accurate regardless of which route triggered it.
opw-6539184
Forward-Port-Of: odoo/odoo#288116
Forward-Port-Of: odoo/odoo#287345Product carousels in single-scroll mode now slide correctly on right-to-left language websites such as Arabic. This prevents empty spaces and image distortion, giving visitors a smoother browsing experience.
Original PR description
**Description of the issue/feature this PR addresses:** When a dynamic product carousel is set to single-image scrolling mode in an RTL language (e.g., Arabic), sliding between items behaves…
**Description of the issue/feature this PR addresses:**
When a dynamic product carousel is set to single-image scrolling mode in an RTL language (e.g., Arabic), sliding between items behaves inconsistently, resulting in empty spots or temporarily distorted images.
This occurs because the DOM manipulation creating the infinite scroll was coded for LTR physical movements. In LTR, the first DOM element is visually on the left. In RTL, the visual layout is mirrored, with the first DOM element visually on the right. When we then trigger a "left" slide in RTL, the LTR-based JavaScript doesn't appropriately move the last element to the first index prior to the animation, resulting in an empty gap, among other issues.
This commit resolves the issue by checking the document's text direction. By swapping the target direction ("left" or "right") in onSlideSingleScroll and onSlidSingleScroll when RTL is active, the underlying array operations now correctly align with the animation.
**Steps to reproduce:**
- Website > Edit > add Product Carousel > Customize > change Scrolling Mode to Single
- Website > Edit > Theme > Website > Language > change to Arabic
- Click the arrows in the product carousel > observe inconsistent scrolling with visual glitches
**Current behavior before PR:**
- Visual glitches when sliding carousels in single-image scrolling mode for RTL languages
**Desired behavior after PR is merged:**
- No visual glitches when sliding carousels in single-image scrolling mode for RTL languages
opw-6490277
Forward-Port-Of: odoo/odoo#286042This fix keeps existing guided tours from breaking when they contain an older extra field. It helps ensure previously exported custom and industry tours continue loading normally without requiring manual updates.
Original PR description
Tours exported between 37b35f18 and d2ee747d carry a stray `url` key. `validate()` throws on any unknown key at `registry.addValidation()` time, which aborts asset loading for those pre-existing custom tours. Add a `"*"` wildcard to the schema: unknown keys are ignored, `steps` is still validated. 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#287807 Forward-Port-Of: odoo/odoo#287617
The Peruvian POS electronic invoicing tests now use the correct sales journal when checking receipts. This keeps automated validation aligned with recent accounting changes and helps prevent false test failures.
Original PR description
Since the POS accounting refactor in odoo/odoo#256889 pos.config.journal_id is the journal used to create invoices, so it has to be a sale journal. Before that it was the journal for session entries and invoice payments, which allowed general journals, and invoices went to invoice_journal_id. runbot-error-947223
This fix prevents an error when a check template filters accounts and the filter returns no results. Businesses can now use such templates without unexpected interruptions or tracebacks during accounting report processing.
Original PR description
When a check template has a domain on account.account that would give no result, it would throw a traceback because min cannot operate on an empty result. Forward-Port-Of: odoo/enterprise#131540
Customer invoice numbering now ignores vendor bill numbers, preventing the two document flows from accidentally sharing the same sequence. This helps businesses keep official Dominican electronic invoice numbers accurate and avoids confusion or compliance issues caused by skipped or incorrect numbering.
Original PR description
### Issue before this commit: When users enabled the "Use Documents" option on a Purchase journal and created a vendor bill with a specific document type (e.g., type 31) and number (e.g., E3100056),…
### Issue before this commit: When users enabled the "Use Documents" option on a Purchase journal and created a vendor bill with a specific document type (e.g., type 31) and number (e.g., E3100056), creating a new customer invoice with the same document type would incorrectly continue the sequence from the vendor bill's number (e.g., E3100057). ### Steps to reproduce the issue: 1. Download Accounting and l10n_do_edi 2. Go to invoices and vendor bills and delete all of them 3. Go to Journals and tick Use Documents options for Sales and Purchases journals 4. Create a vendor bill setting the document type as for example (31) Electronic Tax Credit Invoice and the document number as for example E3100056 5. Create an invoice and set the same document type 6. See that the sequence will increase by 1 but starting from the last number setted (so it will be E3100057) when you create a new invoice ### Cause of the issue: https://github.com/odoo/enterprise/blob/d4da04a036486818c12712a200a3482a66921abf/l10n_do_edi/models/account_move.py#L346-L354 The _get_last_sequence_domain override is fetching the last sequence across the company based on the document type, but it did not filter by move_type. Consequently, it was catching vendor bill numbers (in_invoice) to compute the next sequence for customer invoices (out_invoice). ### Reason to introduce the fix: Restrict the sequence lookup to sales documents will ensures that vendor bill references do not interfere with the official sequential numbering of customer invoices. opw-6430906 Forward-Port-Of: odoo/enterprise#128178
The appraisal process no longer requires a final assessment to be completed. This reduces unnecessary blockers for HR teams and managers when an appraisal can be closed or managed without that final text.
Original PR description
Forward-Port-Of: odoo/enterprise#131393
When the website generator cannot find an attachment, the error log now includes the missing file name. This makes troubleshooting faster because support teams no longer have to rely on an attachment ID that may be empty or unhelpful.
Original PR description
When an attachment is not found, we should log the filename as well as often the attachment id is None and tells us nothing. Forward-Port-Of: odoo/enterprise#131370
Large blog imports now process link updates in smaller controlled batches, preventing timeouts during website content generation. This helps ensure imports complete reliably instead of stopping partway through.
Original PR description
This commit fixes an issue where huge blog requests were timing out due to large replacements for links that weren't controlled with our batch creation wrapper. This resulted in incomplete imports. The fix is to put the text replacements in the batch create wrapper which will avoid timeouts and let it continue reliably. Forward-Port-Of: odoo/enterprise#131368
Salespeople now receive the expected upsell warning when multiple timesheet entries together exceed the prepaid service threshold. This helps teams catch upsell opportunities even when customer work is logged incrementally rather than all at once.
Original PR description
Steps to reproduce: -------------------------------------------- 1. Install `sale_timesheet` module 2. Create a product with: * Type: Service * Invoicing Policy: Prepaid/Fixed Price * Create on…
Steps to reproduce:
--------------------------------------------
1. Install `sale_timesheet` module
2. Create a product with:
* Type: Service
* Invoicing Policy: Prepaid/Fixed Price
* Create on Order: Project & Task
* Upsell Threshold: Set some value (e,g. 600%)
3. Create and confirm the sale order with that product
4. Create and confirm an invoice for the sale order
5. From Recorder Hours Smart button:
* Add two timesheets for hours 3 & 4 (Combined h > Threshold Percentage/100)
Observation:
--------------------------------------------
* When adding a single 7h timesheet, an upsell warning activity is correctly created for the salesperson in the chatter.
* When adding multiple incremental timesheets whose combined duration exceeds the threshold, no upsell warning activity is created.
Issue:
--------------------------------------------
* The `_compute_field_value` method filters on `invoice_status != 'upselling'` before recomputing the new invoice status.
* After the first incremental timesheet is added, the sales order already has the upselling status from the previous computation.
* As a result, subsequent computations skip the upsell activity logic, even though `has_displayed_warning_upsell` is still `False` and no warning activity has yet been created.
Solution:
--------------------------------------------
* Removes the `so.invoice_status != 'upselling'` condition from the filter.
* The order-level `invoice_status` was never the right place to control upsell activity creation. An order can have `invoice_status == 'upselling'` for various reasons (delivered > invoiced), but that doesn't mean all lines have already triggered their upsell warnings.
opw-6117754
Forward-Port-Of: odoo/odoo#287642
Forward-Port-Of: odoo/odoo#266275The spreadsheet insertion dialog no longer shows an unwanted horizontal scrollbar or duplicate scrolling on small screens. This makes the insert flow cleaner and easier to use, while keeping spreadsheet template styling separate from selector dialogs.
Original PR description
Opening "Insert in Spreadsheet" displayed an unwanted horizontal scrollbar in the spreadsheet selector. On small viewports, it could also produce a second scrollbar alongside the scrollable modal. The selector reused the `o-spreadsheet-templates-dialog` class, whose styles belong to `documents_spreadsheet`. This applied template-only max-height and overflow rules to the selector and made `spreadsheet_edition` rely on styles from a dependent module. Give selector dialogs their own class and keep the template-specific styles on the template dialog. Move the shared pager layout to `spreadsheet_edition` under a dedicated class, and update both pager consumers and the dashboard document selector. Task: 6526781 Forward-Port-Of: odoo/enterprise#131450 Forward-Port-Of: odoo/enterprise#130114
This update makes marketing campaign webhooks more reliable by better validating incoming data, avoiding unintended record creation, and improving error logging. It also restores and cleans up marketing automation views, helping teams diagnose campaign activity issues more easily after recent refactoring.
Original PR description
Provide various fixes after recent marketing automation refactoring. Notably * improve defensive webhook behavior, sanitize input, improve logging; * various views fixup, notably introducing back a generic activity view for debugging; * fix various small code issues; See commits for more details. Task-6559148 Followup of Task-3866422 (PR odoo/enterprise#113376)
Direct debit mandates now receive a sensible default type when the system cannot find an exact match. This prevents missing selections in cases where only one mandate option exists and the field may be hidden from users.
Original PR description
When no good match is found for the mandate_type, we still want to default on something. In particular when only one concrete implementation of the mandate exists, the field will be hidden since there is only one possible value. task-none
A website test was adjusted so it consistently uses a mock service instead of accidentally calling the real external image API. This reduces false test failures and helps keep the release process stable without changing customer-facing functionality.
Original PR description
The `test_media_dialog_undraw` test monkeypatches `HTML_Editor.media_library_search` to avoid calling the real undraw API during the tour. However, the "routing" ormcache may already hold the controller endpoint built with the original (unpatched) method, if it was resolved by an earlier request served by the same worker. Invalidate the "routing" ormcache after patching so the requests are routed to the patched methods. Same change as done in #271536. https://runbot.odoo.com/odoo/error/939933 Forward-Port-Of: odoo/odoo#288246
This change removes an obsolete calendar connection setup screen and related assets that are no longer used. Calendar syncing is now handled directly by the Google and Microsoft calendar integrations when credentials are configured, reducing maintenance overhead without changing the current user workflow.
Original PR description
Purpose ======= Removing the 'calendar.provider.config' wizard, its associated widget and images as they're not used anywhere. Specification ============= Following…
Purpose ======= Removing the 'calendar.provider.config' wizard, its associated widget and images as they're not used anywhere. Specification ============= Following odoo/odoo@eccb937393ff3fb22e3d341137325782d1faf9cd , the calendar onboarding has been removed which consequently removed the onboarding banner with the "Connect your calendar" button opening the provider wizard. Following odoo/odoo@f78a82df0e712caa82608f35a393e6d522179483 , the "Connect your calendar" xml action opening the wizard has been removed as part of a sync flow reorganization. Following odoo/odoo@d87d5fe51fa945cac014033032f33333168ed579 , the "configureCalendarProviderSync" js method opening the wizard has also been removed. Now, each provider (google_calendar, microsoft_calendar) adds their own sync button in the attendee controller depending on their credentials and sync status. No "Sync" or "Connect" button will be suggested if no google or microsoft credentials are set. Credential settings are only accessible via the Settings. The 'calendar.provider.config' wizard is thus unused, as well as its related widget and the google / microsoft images which was used in its form view. => Removing the dead code Task-6297321 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update modernizes how Odoo handles internal business actions across Studio and many enterprise apps. It should not change day-to-day workflows, but helps keep the platform easier to maintain and aligned with the latest web architecture.
Original PR description
web_studio: replace makeActionManager with StudioActionManagerPlugin (subclass of ActionManagerPlugin), and move its doAction override onto the plugin class instead of monkey-patching it in the service, matching how the dialog service was already handled. Second commit updates every import for odoo/odoo's action_service.js → action_plugin.js rename.
This update restructures how Odoo's web client manages navigation actions and internal messaging, without changing expected user workflows. It helps make the platform easier to maintain and prepares the interface architecture for future improvements while keeping compatibility for existing features.
Original PR description
Extracts env.bus into its own GlobalBusPlugin (temporary EnvBusBridgePlugin keeps env.bus working for legacy callers), then converts the action service into ActionManagerPlugin, keeping a backward-compatible action service shim for existing useService() callers. File renamed to action_plugin.js to match every other migrated service.
Several country-specific payroll, reporting, and localization screens were updated to use the current component validation approach. This is an internal modernization that helps keep these features maintainable and aligned with the platform, with no expected change to day-to-day user workflows.
Original PR description
Replaced deprecated uses of `static props` with calls to `useProps()`, providing actual props validation for Owl components.
Whenever possible, also removed "empty" props definition, being either:
- `static props = ["*"]` with no use of `this.props`;
- `static props = {}`.The AI app module and its related Documents and Knowledge connectors have been renamed to better reflect the agent-based AI direction. References, assets, and translations were updated so the renamed modules continue to work consistently, with a dependency simplified behind the scenes.
Original PR description
- Rename `ai_app` to `ai_agentic`. Rename the Documents and Knowledge bridge modules accordingly. - Update all references and asset paths to use the new module names. - Replace the `web_studio` dependency with `base_automation`. task-id-6497307
The AI question tool can now display markdown-style formatting when asking users questions. This makes prompts clearer and easier to read, improving the user experience with AI-assisted workflows.
Original PR description
This commit introduce markdown formatting for the `_ai_tool_ask_user_question` tool.
The barcode scanning system was reorganized to support Odoo's upcoming interface technology migration. This is mainly an internal change that helps keep barcode-related features reliable across areas like events, attendance, point of sale, and self-ordering, without introducing major visible changes for users.
Original PR description
Services need to be converted to Plugin as part of the Owl3 migration. This commit converts the barcodeService into a new BarcodePlugin.
This update modernizes how several Odoo Enterprise apps validate information passed between interface components. It reduces reliance on deprecated code patterns, helping keep manufacturing, planning, projects, rooms, sales, and related tools easier to maintain without changing day-to-day user workflows.
Original PR description
* mrp_mps,mrp_workorder,project_enterprise,obox*,planning*,room,sale_*
Replaced deprecated uses of `static props` with calls to `useProps()`,
providing actual props validation for Owl components.
Whenever possible, also removed "empty" props definition, being either:
- `static props = ["*"]` with no use of `this.props`;
- `static props = {}`.The point-of-sale enterprise barcode handling has been reorganized to support Odoo's upcoming platform technology migration. This is an internal change that should help keep barcode features compatible and maintainable without changing day-to-day business workflows.
Original PR description
Services need to be converted to Plugin as part of the Owl3 migration. This commit converts the barcodeService into a new BarcodePlugin.
This update modernizes internal component setup in the Sign and Social apps by replacing an older validation pattern with the current one. It helps keep these apps maintainable and aligned with the platform’s latest standards, with no expected change to day-to-day user workflows.
Original PR description
Replaced deprecated uses of `static props` with calls to `useProps()`,
providing actual props validation for Owl components.
Whenever possible, also removed "empty" props definition, being either:
- `static props = ["*"]` with no use of `this.props`;
- `static props = {}`.Egyptian electronic invoicing is now handled directly through the invoice sending flow, with separate demo, test, and production modes. Businesses can also retrieve official ETA invoice PDFs, request cancellations from invoices, and track submissions more clearly, reducing reliance on older infrastructure and improving operational visibility.
Original PR description
This PR does following changes: - removes the dependency of `account_edi` module. - moves the e-invoice send logic to Send wizard. - Introduces following modes for sending invoices: - Demo: invoice not sent to ETA, only internal validations - Pre-production: Invoices sent to ETA pre-prod/test server - Production: Invoices sent to ETA production server - Adds support to fetch invoice PDF from ETA once invoice is sent to ETA. - Adds support to Cancel Invoice on ETA via the new cancel wizard accessible through Request Cancel button on invoice. - Minor UI improvements in invoice list view. - Introduces new model to log the submissions to ETA. task-5190493 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This pull request appears to be a test related to the Singapore localization area rather than a functional business change. It should have little to no direct impact on users or day-to-day operations.
Original PR description
Ignore. Testing with VIN if the codeowner is properly set. task-because-why-not
This update modernizes internal component definitions across time tracking, timesheet grid, and barcode workflows. It helps keep these areas maintainable and aligned with the current framework, with no expected change to day-to-day user behavior.
Original PR description
Replaced deprecated uses of `static props` with calls to `useProps()`,
providing actual props validation for Owl components.
Whenever possible, also removed "empty" props definition, being either:
- `static props = ["*"]` with no use of `this.props`;
- `static props = {}`.This change reorganizes how Odoo handles internal page actions and shared event messaging across many apps. It should preserve existing user workflows while making the platform easier to maintain and extend in future releases.
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
This update modernizes the way Odoo opens and manages actions across several business apps, without changing the intended user workflows. It helps keep the platform easier to maintain and prepares these areas for more consistent behavior in future updates.
This update simplifies how inter-company sales, purchases, and stock transfers match related stock movements. It is an internal cleanup that should make the process easier to maintain without changing day-to-day user behavior.
Original PR description
Clean up context key in _find_corresponding_move. The 2 context keys assigned_move_ids and skip_price_check are only used in this specific method. This commit updates to use method parameters instead.