Tuesday, September 15, 2026
184 changes · master
Security fixes and vulnerability patches
The Nilvera-based Turkish e-invoicing and e-dispatch integrations are now part of Odoo Enterprise as the officially supported solution. The move preserves existing module names and data, updates the license, and includes a security tightening to protect API keys from broader journal access.
Original PR description
Moves l10n_tr_nilvera{,_einvoice,_edispatch} from Community to Enterprise. - [MOV] adds the three modules byte-identical to their Community source, and registers their translations in .weblate.json.…
Moves l10n_tr_nilvera{,_einvoice,_edispatch} from Community to Enterprise.
- [MOV] adds the three modules byte-identical to their Community source, and registers their translations in .weblate.json.
- [IMP] switches their licence to OEEL-1.
- [REF] moves the ubl_tr EDI overrides (_get_edi_builder and _get_ubl_cii_formats_info) from l10n_tr_nilvera into l10n_tr_nilvera_einvoice, which owns the builder model and depends on account_edi_ubl_cii. l10n_tr_nilvera overrode both but did not depend on the module defining them; it worked only because l10n_tr_nilvera_einvoice auto-installs on it. The format selection, partner config, and _get_suggested_invoice_edi_format stay in l10n_tr_nilvera, since its views render the format and that method extends account, which is in its dependencies. Also drops an extra blank line (E303).
- [FIX] restricts l10n_tr_nilvera_api_key on account.journal with groups='base.group_system', matching the company field it is related to, so the key is not exposed to anyone able to read the journal (PY039); and uses urlsplit instead of urlparse to take a Nilvera endpoint path, avoiding urlparse's outdated RFC 1808 params behaviour.
Community pr: odoo/odoo#281446
Upgrade pr: odoo/upgrade#10977
task-6424221New functionality added to Odoo
Users can now organize events across multiple calendars, share calendars with others, and better manage calendars synchronized from Google. This makes scheduling more flexible and improves handling of shared or read-only calendars such as public holidays.
Original PR description
Enhancements to existing features
The online store price selector is now presented as a simple site-wide customer choice in the header or footer, rather than as a technical “pricelist” control on individual shopping pages. Businesses can also show tax-included or tax-excluded prices by customer segment, with defaults better aligned to local market expectations.
Resolved issues and error corrections
The accounting review status badge now follows read-only rules set on the field. This prevents users from editing statuses in places where the business process expects the information to remain locked.
Original PR description
enable readonly attribute on the field to be taken into consideration when using the widget account_review_state_selection_badge. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Features or functions removed from Odoo
The Turkish Nilvera e-invoicing and e-dispatch integrations are being removed from the Community repository and moved unchanged to Odoo Enterprise under the official Odoo-Nilvera partnership. Existing Enterprise customers should keep their data and references because the module names remain the same, while translation tracking also moves to the Enterprise repository.
Original PR description
Under the Memorandum of Understanding between Odoo and Nilvera, the Turkish e-invoicing integration becomes the officially supported Enterprise solution. This commit removes the three modules, which move to odoo/enterprise unchanged. The module names do not change, and Odoo identifies a module by name alone, so a database resolving them from the enterprise repository keeps its data and its xmlids across the move. Every database reaching a migration script has the enterprise addons available, so this is the expected path; odoo/upgrade#10977 covers the case where they are not. No module in this repository depends on them. Enterprise pr: odoo/enterprise#127381 Upgrade pr: odoo/upgrade#10977 task-6424221 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Code cleanup and technical improvements
Work entry and time-off type names and codes were renamed to match Partena formats, making it easier for organizations moving from Partena to Odoo. Duplicate work entry types were cleaned up and some entries were simplified into categories for clearer payroll and absence reporting.
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
Documentation and clarification updates
Mina Adel has signed the Individual Contributor License Agreement, allowing their contributions to be accepted under Odoo's legal requirements. This administrative update supports related contribution work and has no direct effect on product features or users.
Original PR description
Individual Contributor License Agreement signature for Mina Adel (minallegend@gmail.com, https://github.com/minaonlyone). Needed for odoo/enterprise#131352 (19.0). Replaces #287992, whose branch name made runbot diff it against master. Forward-Port-Of: odoo/odoo#288010
## New `calendar.calendar` and 'calendar.calendar.user' models Before this commit, the user model had a direct One2Many relation with events. To organize the events into different calendars, new…
## New `calendar.calendar` and 'calendar.calendar.user' models
Before this commit, the user model had a direct One2Many relation with events.
To organize the events into different calendars, new models were introduced,
resulting in the following structure:
- user --o2m--> calendar.user --m2o--> calendar --o2m--> event
Because Google and Outlook support sharing calendars between users, we
introduced a calendar.calendar.user 'membership' model to allow more users
to share one calendar. The model holds the user's access role to a calendar
along with any relevant metadata for each calendar/user pair, such as saved
filters and if it is the user's primary calendar
The calendar_default_privacy field was moved from user_settings to the
individual calendars.
Each user should have exactly one primary calendar, which cannot be deleted.
This is enforced by a migration script and a post_init hook which creates this
calendar for each existing user. For new users, this is handled in a 'Create'
override. A db constraint was added to ensure each user has no more than one
primary calendar.
The is_readonly flag cannot currently be set anywhere within the calendar
module. It is there because some calendars synchronized from Google/Outlook are
readonly (such as public holidays) - Should it stay in the calendar module?
## calendar view
The filter section can be used to edit/create new calendars via buttons
shown on hover. Alternatively, a simple form/list view was added to the
configuration menu.
The colors of the events are based on:
1. Calendars if they belong to the user's calendar
2. partner_id otherwise (just like before)
# Sync
The calendar.model is extended with sync logic, sharing the base sync class with
events. Each calendar also holds its individual sync token so that we only
update when there is new data from google.
Unlike for events, the calendar endpoints do not return an 'updated' timestamp,
meaning we can't rely on last write date to determine which update wins in case
of a conflict - we have to decide which side is authoritative.
In this case -> Odoo
## Sync Flow
1. Synchronize all calendars
Before starting the usual sync flow in 'res.users', we first make a call to
`/calendarList` to fetch all the users calendars. A sync token for this call is
stored in the user settings, similar to the 'global' sync token before. All
calendars which do not have a google_sync_id set, are then posted to Google.
After this part of the request is done, we manually commit the changes. This is
because the google api methods are decorated with @after_commit so that we
don't send data if the sync process fails for some reason. We need all the
calendars to be synchronized when we sync events, thet's why we call
`env.cr.commit()`
Small technical limitation:
Besides the events themselves, we currently only sync the name (summary) field
with google. When this is changed on google however, it does not invalidate the
sync token, meaning we are not notified of this change (changing some other
field on google, such as calendar color, correctly invalidates the sync token)
2. Synchronize the events
Google handles moving events between two calendars -> It returns a canceled
record for the original calendar, and a new one for the moved one. This means we
have to split the process into several parts instead of running the current
flow for each calendar:
2.1: Get events for all calendars from Google
Paths always used to be `.../primary/...` -> now `.../{calendar_id}/...`.
Otherwise the same as before.
2.2 Google -> Odoo
First, determine which should be active after the sync is done.
This is done to prevent canceling events which were moved in Google - E.g.:
- event1 was moved from cal1 to cal2
- when we iterate over the calendars, cal1 tells us the event was canceled
- if the event with the same id is still active somewhere, it means it was moved
and not canceled, se we leave it be
- cal2 then tells us the new calendar so we can update the event
2.3 Odoo -> Google
This part is mostly unchanged from the previous flow, with calendar ids added to
the api route paths just like before
Task-5485938Adds support for Greek electronic Dispatch/Delivery Notes for reporting goods movements to the AADE platform. Businesses can now capture required delivery details, validate them before sending, and link dispatch notes to related invoices for compliance.
Original PR description
To comply with Greek tax regulations on the mandatory electronic reporting of physical goods movement, this commit introduces the possibility to send Dispatch/Delivery Note (Document Type 9.3). Under Greek tax legislation, entities delivering goods to customers or transferring stock between internal locations must report these physical movements electronically to the AADE platform. - Implemented support for Dispatch Notes adding required fields on the stock picking view - Added the linking of those delivery notes to the invoice when those are created with the same sale order - Added prior sending to AADE validation to ensure that evrythin required is filled in task-5485365
The AI Website Builder can now create new website pages, use existing pages as inspiration, and add the new pages to the site menu when requested. This helps users build out richer websites faster, including creating multiple related pages in one interaction, while confirming before moving away from unsaved changes.
Original PR description
Allows the AI agent to create a new page and add it to the menu. task-6143451
Adds support for Argentina's WSMTXCA electronic invoicing service in Odoo, helping businesses in securities and currency exchange markets submit fiscal documents directly to AFIP. This reduces manual work, improves compliance, and stores electronic authorization details within the normal invoicing workflow.
Original PR description
Overview This module integrates the WSMTXCA (Web Service de Autorización de Comprobantes Electrónicos para Mercado de Títulos Valores y Cambios de Argentina) with Odoo's existing Argentinean…
Overview This module integrates the WSMTXCA (Web Service de Autorización de Comprobantes Electrónicos para Mercado de Títulos Valores y Cambios de Argentina) with Odoo's existing Argentinean Electronic Invoicing capabilities. It enables businesses operating in specific markets (like securities and currency exchange, which typically use this webservice) to seamlessly send electronic invoices and other fiscal documents to AFIP (Administración Federal de Ingresos Públicos) using the WSMTXCA web service. This ensures compliance with Argentine tax regulations for transactions falling under this specific regime. Goal of this Module The primary goal of this module is to automate and streamline the electronic invoicing process for entities required to use AFIP's WSMTXCA web service. It extends Odoo's standard localization to support this specific AFIP endpoint, allowing businesses to manage their sales and invoicing workflows within Odoo while fulfilling their fiscal obligations accurately and efficiently. This module aims to reduce manual intervention, minimize errors, and ensure that all electronic documents are correctly authorized by AFIP. Key Features ✅ AFIP WSMTXCA Integration – Connect directly to AFIP’s WSMTXCA web service for electronic invoicing and other fiscal documents relevant to this service. ✅ Automated Document Submission – Send electronic invoices (Facturas Electrónicas) and other supported document types to AFIP in real time. ✅ Compliance with Argentine Regulations – Ensures documents meet all legal requirements for electronic billing under the WSMTXCA scope. ✅ Error Handling & Validation – Validates documents before submission and provides clear error messages from AFIP for quick resolution. ✅ Seamless Odoo Integration – Works natively with Odoo’s accounting and invoicing modules, extending the capabilities of the standard Argentinean localization. ✅ CAE (Código de Autorización Electrónica) Management – Automatically retrieves and stores CAE codes and expiration dates for approved documents. Functional Flow The module integrates into the standard Odoo invoicing workflow with specific considerations for WSMTXCA: Invoice Creation: The user creates a customer invoice in Odoo as usual, selecting a journal specifically configured to use the WSMTXCA AFIP web service. Data Preparation: Before validation, the module gathers all necessary information required by WSMTXCA, including transaction details, currency, tax information, and specific codes relevant to the market (e.g., securities, exchange operations). Validation and Submission: Upon validating the invoice in Odoo, the module: Performs initial data validation. Constructs the XML request according to AFIP's WSMTXCA specifications. Establishes a secure connection with the WSMTXCA web service using the configured credentials (Certificate and Private Key for WSAA). Sends the electronic document data to AFIP for authorization. AFIP Response Processing: Approval: If AFIP approves the document, the WSMTXCA service returns a CAE (Código de Autorización Electrónica) and its expiration date. The module automatically records this CAE and related information on the Odoo invoice. The invoice is then considered fiscally valid. Rejection/Observations: If AFIP rejects the document or returns observations, the web service provides error codes and messages. The module displays these messages to the user within Odoo, allowing them to correct the invoice and resubmit it. PDF Report: The authorized invoice, including the CAE number and barcode, can then be printed or sent to the customer. Consultation: The module also allows for querying the status of previously submitted documents or fetching the last authorized document number for a given Point of Sale (POS) and document type via WSMTXCA. Configuration To use this module, the following configuration steps are generally required: AFIP Credentials: Obtain a Digital Certificate (Certificado Digital) and Private Key (Clave Privada) from AFIP for the WSMTXCA web service. This involves creating a Certificate Signing Request (CSR), authorizing it in the AFIP portal, and downloading the definitive certificate. Ensure the CUIT associated with the certificate is authorized to operate with the WSMTXCA service via the "Administrador de Relaciones de Clave Fiscal" on the AFIP website. Odoo Company Configuration: In Odoo, navigate to Accounting > Configuration > Settings (or general company settings). Upload the AFIP Digital Certificate and Private Key. Set the environment (Testing/Homologación or Production). Journal Configuration: Navigate to Accounting > Configuration > Journals. For each journal that will issue electronic documents via WSMTXCA: Set the "AFIP POS System" (or equivalent field) to "MTXCA" (or the specific identifier used by the module). Configure the AFIP Point of Sale (POS) number. Associate the correct AFIP document types (e.g., specific invoice types for securities markets) allowed for this journal and POS. Testing: It is crucial to perform thorough testing in AFIP's "Homologación" (testing) environment before moving to "Producción" (production). This involves sending test invoices and verifying their authorization. The module should provide a mechanism to switch between AFIP's testing and production web service URLs. Legal Support & AFIP Documentation The WSMTXCA web service is regulated by AFIP. For detailed legal information, technical specifications, and official manuals, refer to the AFIP website. Key documents typically include: Manuales de Usuario y Especificaciones Técnicas de WSMTXCA: AFIP usually provides detailed PDF documents outlining the functionality, data structures, error codes, and communication protocols for each web service. These can typically be found in the "Webservices" section of the AFIP site ([www.afip.gob.ar](http://www.afip.gob.ar/)). Search specifically for "WSMTXCA Manual para el Desarrollador" or similar titles on the AFIP portal. Resoluciones Generales (RG) de AFIP: Specific resolutions establish the obligation, scope, and conditions for using electronic invoicing and particular web services like WSMTXCA for certain taxpayer categories or activities. For example, RG AFIP N° 2557/09 and RG AFIP Nº 2758/10 laid groundwork for electronic invoicing in securities markets, though newer RGs might supersede or complement these. WSAA (Web Service de Autenticación y Autorización): WSMTXCA, like other AFIP web services, requires authentication through WSAA. Documentation for WSAA is also essential. Disclaimer: AFIP regulations and documentation are subject to change. Always refer to the official AFIP website for the latest and most accurate information. Why Use This Module? This module simplifies the process of electronic invoicing in Argentina for businesses under the WSMTXCA scope, reducing manual work and ensuring compliance with AFIP’s latest standards. By leveraging the WSMTXCA web service, businesses can: ✔ Avoid penalties by submitting documents correctly. ✔ Speed up billing processes with automated submissions. ✔ Improve accuracy with built-in validation checks and direct AFIP feedback. ✔ Maintain a centralized record of all fiscal documents within Odoo. Compatibility Odoo v16 Requires the base Argentinean Electronic Invoicing module (or relevant Odoo's core localization features for Argentina). --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update makes employee leave records available directly from employee information in the Time Off module. It supports related business processes, such as payroll integrations, by making leave data easier to read where needed.
Original PR description
Allows to read it (without payroll). See enterprise PR. Task-6344800
Planning administrators can now choose WhatsApp as the communication channel for shift-related notifications instead of relying only on email. This helps businesses reach employees through a more immediate channel for assignments, reassignments, open shifts, and published schedules.
Original PR description
Adds a new module, whatsapp_planning, that allows planning shifts to be sent via WhatsApp. Before this commit, planning-related notifications were only sent by email, with no option to use another communication channel. After this commit, an administrator can configure the Planning app to send WhatsApp messages instead of emails. When in debug mode, the administrator can also edit the templates used to generate these WhatsApp messages.Notifications are supported for direct shift assignment, shift reassignment, open shifts, and planning publication. task-[5138715](https://www.odoo.com/odoo/project/4105/tasks/5138715)
A new report helps businesses compare intercompany transactions across related companies and quickly see whether each operation has a matching counterpart. This makes reconciliation easier and helps teams identify unmatched balances that need investigation.
Original PR description
This new report is use to make sure every interco operation is properly matched with a counterpart in the corresponding company. Users can ensure that by making sure every line of the report balances to 0. task-6515399
Original PR description
The eCommerce currently exposes its selectable pricelists through a dropdown labelled "Pricelist:". A pricelist is a backend configuration concept that means nothing to a customer, and the label also…
The eCommerce currently exposes its selectable pricelists through a dropdown labelled "Pricelist:". A pricelist is a backend configuration concept that means nothing to a customer, and the label also takes the naming decision away from the user, who may well want to present that choice as a currency, a country or a market. This PR removes the label, leaving a plain dropdown listing the pricelists by name. It is then up to the user to name them however fits their audience. The selector also moves out of the shop, product and event pages, and is rendered next to the language selector in the website header and footer: both are site-wide preferences, so customers look for them in the same place. Each of the two can be toggled from the website builder. A few notable points on the implementation: - The current pricelist is exposed as a `website.pricelist_id` field, computed from the session and writable through its inverse, so templates and controllers no longer reach into the session cache keys themselves. `website.currency_id` now derives from it. - The price filter bounds are converted only when the currency actually changed, instead of whenever the pricelist changed, since several pricelists can share a currency. - A keyboard typeahead was added to the dropdown, as these lists get long once pricelists are named after countries or currencies. On a related topic, the tax display (tax-included vs. tax-excluded pricing) can now be overridden per pricelist. It is currently decided once for the whole website, which forces users selling to both consumers and businesses to pick one audience: either their B2C visitors see prices without their taxes, or their business customers see prices they have to compute back. They can now keep their website tax included by default and show prices tax excluded for the pricelist assigned to their business partners. Finally, the default tax display is inverted to tax included, except for Canada and the United States which keep tax excluded through two new bridge modules, l10n_ca_website_sale and l10n_us_website_sale. eCommerce shows prices tax included in most countries, so the previous default had most users starting from the wrong display, and the Argentinian and Brazilian localizations each had to opt back into it. Only the default changes: the field is stored, so websites with an explicit value keep theirs. task-4826932 See also: - https://github.com/odoo/enterprise/pull/128613 - https://github.com/odoo/upgrade/pull/10715
The accounting dashboard now highlights the most useful KPIs for freelancers, replacing broader company metrics with clearer invoice, cash, receivable, and payable views. Dashboard cards now link to more relevant reports, and the visual design is simplified to reduce clutter and make key financial information easier to act on.
Original PR description
the dashboard is mainly useful for freelancers and not large companies so changing it to align more with what a freelancer might need - replace Revenue with Invoices and redirect it to Invoice Analysis, this is much cleared and straight to the point - replace Cash In/Out with a single net Cash value card to match the pattern of the other cards and also now it's more clear - redirect Receivable and Payable to their respective aged reports - remove Gross Margin and obsolete multi-value card handling as it's not that important and we wanna keep only the most important kpis and to not get the user overwhelmed - lighten sale/purchase graph bars to be like the color of the Bank journal, to have a better look for the dashboard overall task-[6571051](https://www.odoo.com/odoo/project/967/tasks/6571051) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update prepares Appointment scheduling for multi-calendar use and aligns related enterprise tests with recent calendar changes. It also includes small fixes to keep appointment forms, Google Calendar synchronization tests, and AI mail-related tests working reliably after the refactoring.
Original PR description
Enterprise part of the multicalendar feature. Includes adjustments to existing enterprise tests and edits based on refactoring from community Community PR: https://github.com/odoo/odoo/pull/261571
When a subscription is duplicated, it no longer keeps the dates from the original contract. The new subscription receives its start date when confirmed and its end date is based on the quotation template, making dates easier to review before activation.
Original PR description
Duplicating a subscription carried the original start date over to the new record, which then began on a date belonging to the previous contract. The field sat in the Other Info tab, so the mistake was easy to miss. The dates are no longer carried over. A duplicate gets its start date when it is confirmed, and its end date follows from the duration of the quotation template. The start date now sits next to the recurring plan and the end date, where it can be reviewed and adjusted before confirming. task-6515131
Subscription payment reminder timing can now be adjusted in settings instead of being fixed in the system. This helps businesses tailor failed-payment and missing-payment-method reminders to their own customer follow-up policies, with clearer day numbering to reduce configuration mistakes.
Original PR description
Before: - Payment-failure and no-token reminder days were hardcoded ([2, 7, 14] and [0, 1, 2, 7, 14, -2, -7, -14]), and user was not able to configure it. - In the no-token reminder path, a positive day number meant "days before the payment is due" and a negative number meant "days after it's overdue" which reads backwards and is easy to get wrong when configuring or extending it. After: - Two system parameters (payment_failed_reminder_days, no_token_reminder_days), added in Settings, to allow user to configure the reminder days. - The no-token reminder path's day numbers now read the natural way: positive means days late, negative means days early including its catch-up logic for missed cron runs, which does the same date math and needed the same fix. task-6421393
Pricelist setup is now cleaner and avoids creating unnecessary duplicates when configuring platform order providers. Demo pricing data for online rentals is also improved, making test and demonstration environments more consistent.
Original PR description
Improves the pricelist setup, with and without demo data. task-4826932 See also: - https://github.com/odoo/odoo/pull/265605 - https://github.com/odoo/upgrade/pull/10715
This update refreshes internal query counter expectations used to monitor Odoo performance. It helps keep automated checks aligned with current system behavior, reducing false alarms without changing day-to-day user workflows.
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
The Manufacturing Order overview now shows one clear MO Cost instead of multiple competing cost figures, helping users quickly understand expected or actual production cost. It also flags overconsumed materials and operations that take longer than planned, making production variances easier to spot and act on.
Original PR description
The MO overview currently displays three different cost values: MO Cost, BoM Cost, and Real Cost. This makes common manufacturing use cases harder to read, as users have to compare multiple values to identify the relevant MO cost. With this commit: - Keep a single MO Cost that represents the planned cost before the MO is completed and the actual cost once it is completed. - Highlight the component quantity and consumed quantity when they exceed what was planned, making overconsumption easier to identify. - Highlight the operation duration when it exceeds the expected duration, making extra operation time easier to identify. Enterprise PR: odoo/enterprise#127411 TaskID-6432201
This update makes payroll-related screens easier to use by improving how employee leave and work entry types are displayed and managed. It helps HR and payroll teams review time off and payroll inputs more clearly, reducing friction in day-to-day payroll preparation.
Original PR description
UX Improvement for payroll Task:6456624 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
The Sri Lankan localization now includes tax invoice compliance directly in the main module, so businesses no longer need a separate add-on for these requirements. Withholding tax setup and VAT registration detection were also improved to reduce manual corrections and better support contacts missing country details.
Original PR description
This PR consolidates and improves the Sri Lankan localization (l10n_lk) module by merging tax invoice features, updating withholding tax definitions, and refining VAT detection rules. **Commit 1:** Merged Invoice Module Integrated l10n_lk_invoice into l10n_lk so all Sri Lankan tax invoice compliance requirements are available out-of-the-box in the main module. **Commit 2:** Withholding Tax Updates Set the is_withholding_tax flag on AIT taxes to match updated withholding handling rules. **Commit 3:** Improved VAT Detection Removed the country_id dependency for l10n_lk_vat_registered so partners without a set country are still properly flagged based on their VAT number. task-6373062 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
POS payment methods can now be updated and new payment methods can be added without closing an active session, making setup changes such as payment terminal configuration less disruptive. Accounting-critical settings and removal of linked payment methods remain restricted during open sessions to protect session closing and financial reporting.
Original PR description
..., l10n_us_hr_payroll_account --- Before this, almost any change to a payment method, or to the set of payment methods linked to a POS, was blocked while a session using it was open. In practice this forced closing a client's ongoing session just to, for example, configure a payment terminal. Payment methods can now be edited, and new ones can be linked to a POS, while a session is open. Only the fields that determine where money gets booked (type, journal, outstanding account, intermediary account) stay locked, since changing them mid-session could corrupt the session's accounting. Removing a payment method from a POS is still forbidden while a session is open, for the same reason: the session's accounting and closing report rely on that link staying intact until the session is closed. --- Task: https://www.odoo.com/odoo/project/1737/tasks/6471242
The fields list view no longer shows the Index column, reducing visual clutter for users reviewing field definitions. The index setting remains available in the detailed field form, so functionality is preserved while the overview is easier to scan.
Original PR description
The Index column is unnecessary in the fields list view and adds visual clutter. Remove it while keeping the property available in the field form. Follow up on: task-6507120 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Payroll and time-off planning screens have been refined to make routine payroll work clearer and easier to complete. The update improves Gantt-based holiday visibility, payslip batch workflows, and guidance around payroll warnings so HR teams can act with more confidence.
Original PR description
UX Improvement for payroll Task:6456624
Production Analysis reports now separate work center costs from total operation costs, making manufacturing cost measures easier to understand. Per-unit cost calculations and labels were also cleaned up so business users can compare expected and actual costs more reliably.
Original PR description
The Production Analysis measures did not clearly distinguish work center costs from combined operation costs. Some per-unit measures also used unnecessary "Average" prefixes, making the measure list harder to understand. Separate work center and operation costs, align their expected measures, and simplify the labels displayed in the report. This commit's changes: - Rename work center-only fields and SQL helpers to `workcenter_cost`, `unit_workcenter_cost`, and `_get_workcenter_cost`. - Add `operation_cost` and `unit_operation_cost` as the sum of work center and employee costs. - Rename the expected work center measure to `expected_workcenter_cost_unit` and use `expected_operation_cost_unit` for the combined expected cost. - Apply quantity-weighted aggregation to employee and operation costs per unit. - Remove unnecessary "Average" and redundant view strings. - Update the HR and subcontracting report views and report tests. task-6425682
Manufacturing order overview costs now present a single cost total that reflects the order status. Once production is completed, employee time from work orders is included in that total, giving business users a more consistent and complete cost view.
Original PR description
The MO overview costing is simplified in mrp to use a single MO Cost based on the production state. Since mrp_workorder contributes employee time costs to the MO overview, this commit updates the workorder report so employee time costs are included in MO Cost once the manufacturing order is completed, keeping the enterprise overview consistent with the simplified costing behavior from mrp. Community PR: odoo/odoo#281486 TaskID-6432201
Businesses can now adjust payment methods and add new ones to a Point of Sale while a sales session is still open, avoiding unnecessary session closures for setup changes such as payment terminals. Accounting-critical fields and removal of payment methods remain restricted during open sessions to protect financial reporting accuracy.
Original PR description
..., l10n_us_hr_payroll_account --- Before this, almost any change to a payment method, or to the set of payment methods linked to a POS, was blocked while a session using it was open. In practice this forced closing a client's ongoing session just to, for example, configure a payment terminal. Payment methods can now be edited, and new ones can be linked to a POS, while a session is open. Only the fields that determine where money gets booked (type, journal, outstanding account, intermediary account) stay locked, since changing them mid-session could corrupt the session's accounting. Removing a payment method from a POS is still forbidden while a session is open, for the same reason: the session's accounting and closing report rely on that link staying intact until the session is closed. --- Task: https://www.odoo.com/odoo/project/1737/tasks/6471242
The separate Open Items menu has been removed to simplify the reporting menu. Users can now access the same open item functionality directly from the Aged Receivable and Aged Payable reports, reducing clutter while keeping the workflow available.
Original PR description
In order to reduce some clutter in the reporting menu we removed the Open Items menu from the reporting tab and added its functionality to the Aged receivable/payable reports instead of the `Statement` button. task-4603708
US Balance Sheet and Profit and Loss reports were updated to better match business reporting needs. The changes add optional cash-basis reporting, improve default hierarchy and total alignment, rename Income to Revenue, and add a cumulative translation adjustment section.
Original PR description
- Make cash basis available (but not checked/enabled) by default on US BS & PL. - Enable Account/Parent hierarchy by default on BS. - Rename "Income" to "Revenue" in the PL report. - Add a Cumulative Translation Adjusments section to the BS, similar to the one that exists in the generic report. - Rearrangement of the Revenue section in the PL. task-6468767
Some restaurant appointment demo bookings now include notes, making sample data more realistic and easier to understand during demonstrations. This helps users and evaluators see how booking notes can appear in typical restaurant appointment scenarios.
Original PR description
Add notes to some demo bookings. --- Task: https://www.odoo.com/odoo/project/1737/tasks/6569809
The point of sale system now separates the logic that turns receipt images into printer-ready output. This makes the same printing preparation reusable for both order changes and receipts, helping keep receipt-related features consistent and easier to maintain.
Original PR description
We extract image to epos raster xml generation to allow reusing for both order change and order receipts. see odoo/enterprise#130184
Subcontracting receipts created without a purchase order now use the supplier price to assign the extra cost. This helps keep manufacturing and inventory valuation more accurate when teams receive subcontracted products through manual or non-standard flows.
Original PR description
When a subcontracting product is received from a subcontractor without a purchase order, the extra_cost is assigned based on the product's supplierinfo price_unit. Task 6527490
When a customer's address is changed, Odoo now refreshes their saved geographic coordinates if they already had location data. This helps keep travel fee calculations and Field Service planning accurate without slowing down bulk address updates.
Original PR description
Currently, updating the address of a res.partner does not refresh its coordinates. The old (stale) coordinates are silently kept, which is especially problematic in Field Service flows where travel fees invoiced to customers rely on those coordinates. This commit ensures that partners are re-geolocalized whenever their address change *if and only if* they already were geolocalized. This avoids forcing the geolocalization on every write, if it is not required. The re-geolocalization is deferred to an asynchronous cron so that mass edits do not block the users. task-6563828
Product tracking options are now presented more clearly so users can distinguish between storable products tracked by quantity and products that are not storable. This reduces confusion when configuring inventory and manufacturing products, while keeping the underlying behavior consistent across forms, lists, and filters.
Original PR description
In order to be set as unstorable, a product's tracking field must be unset (False under the hood; distinct from 'none', which corresponds to tracking by quantity for storables). This is unclear for some users who might not realise that they need to clear the value of the field to unset it, as opposed to picking an option from the dropdown menu. Changing it on the view by modifying the selection widget doesn't cover how it's grouped in list views or the way it's handled in custom filters. Thus, here we add a new unstored computed field to be used in form views and searches to set the `tracking` and `is_storable` fields, for visual clarity. Task ID: [6106458](https://www.odoo.com/odoo/my-tasks/6106458)
Product names now appear centered on POS product cards when no product image is available. This creates a cleaner, more balanced product grid while still allowing longer names to wrap properly without overflowing.
Original PR description
Products without an image currently display their name aligned to the top-left, which leaves awkward empty space and unbalanced product cards in the POS. Centering the text improves the visual layout, while the safe alignment ensures that longer names still wrap and display correctly without overflowing.
This update simplifies how product tracking settings are handled by removing a confusing internal option while keeping the same workflow for users on product forms. It helps make inventory, manufacturing, sales, and service-related processes more consistent without changing the expected business behavior.
Original PR description
The 'none' option for the `tracking` selection representing the 'tracking by quantity' setting is replaced with the state of `tracking = False` and `is_storable = True`. The product form view workflow is preserved in an unstored and computed field that sets `tracking` and `is_storable` under the hood. `tracking` (but not `is_storable`) is now an internal technical field. Task ID: [6106458](https://www.odoo.com/odoo/my-tasks/6106458)
Mobile self-ordering can now automatically print customer receipts when auto-printing is enabled. This helps restaurants and stores keep receipt handling consistent by using the connected proxy printing device.
Original PR description
We now allow printing order receipts in mobile self ordering if auto print is enabled, using the proxy device. see odoo/odoo#286255
Documents linked to attachments are now preserved by being archived when those attachments are deleted from chatter or when related records are removed. Users also get clearer audit messages directly on affected documents, making it easier to understand why a document was archived.
Original PR description
…re deleted Previously, documents.unlink.mixin was used to protect documents from cascade deletion when their shared attachments were removed. To extend this protection to all business models (and…
…re deleted
Previously, documents.unlink.mixin was used to protect documents from cascade deletion when their shared attachments were removed. To extend this protection to all business models (and not just those inheriting from the mixin), we have moved this logic to mail.thread.
We also prevent the deletion of documents when their associated attachments are deleted via the chatter (through the _delete_and_notify method).
Co-authored-by: Florian Charlier <flch@odoo.com>
Instead of moving the unlink.mixin in mail.thread, we apply the logic to all models (archiving document when the document attachment is deleted because of the deletion of a record associated with the attachment).
Co-authored-by: Debauche Stéphane <std@odoo.com>
[IMP] {test_}documents{_full}: improve traceability of indirect archiving
Currently, when a document is archived indirectly, logs are only available in the parent folder. This commit adds direct traceability within the document's own chatter.
A message is now logged on the document to specify the cause of archiving:
- Attachment removal from a record's chatter.
- Deletion of the attachment associated record (orphan attachment).
This provides users with a clear audit trail directly on the affected document.
Task-5155496Turkish invoice withholding setup is simplified by separating the official withholding reason from individual tax options. This reduces confusing tax choices on invoice lines and helps electronic invoices report withholding reasons more accurately.
Original PR description
The GİB reason a withholding is levied under, a code between 601 and 627, was stored on the tax, so the localization shipped one tax per (ratio, reason) pair: 138 withholding taxes in the dropdown of…
The GİB reason a withholding is levied under, a code between 601 and 627, was stored on the tax, so the localization shipped one tax per (ratio, reason) pair: 138 withholding taxes in the dropdown of every invoice line. It also asked at the wrong level, since an invoice carries one reason for all of its lines. The seven ratios now ship as fiscal positions, `Withholding 2/10` through `Withholding 10/10`, mapping the domestic 20% VAT to the matching withholding group through the `fiscal_position_ids` and `original_tax_ids` columns the tax template already had. A `Domestic` position ships at the lowest sequence, otherwise a withholding one wins `_compute_domestic_fiscal_position_id` and flips `is_domestic` across the chart. The invoice type and the available reasons read the taxes on the lines, not the position. A position only reaches the lines on `Update Taxes and Accounts`, so reading it made the reasons move to the newly picked ratio while the lines still withheld at the previous one, and required a reason before the tax it describes existed. `default='SATIS'` also pre-empted its own compute at create, so the invoice type never derived anything. The reason reuses `account.move.l10n_tr_exemption_code_id`, limited to the codes describing the ratio the lines withhold, kept while it fits and dropped once the ratio changes. Only imported codes are listed, so a missing one is created from the field itself, and an invoice withholding at several ratios cannot be sent. The export attaches the reason to the `9015` category, the only marker of the withheld portion, and keeps it out of `0015`, where the same field means an exemption. `l10n_tr_nilvera_edispatch` is touched because its tests build their invoice through the shared fixture in `l10n_tr_nilvera_einvoice`, which used a 2/10 withholding tax as its plain 20% one: their reference files declared `SATIS` while carrying a `9015` withheld subtotal. The fixture now uses the domestic tax and both files are regenerated. task-6368193 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Documents placed in an employee's folder or its subfolders are now automatically connected to the right employee record. This makes document handling more consistent whether users upload files from the Documents app or from the employee profile, while preserving existing links when files move to regular folders.
Original PR description
Previously, documents uploaded directly in the Documents app within an employee's folder were not automatically linked to the employee record. The link was only established when accessing the Documents app via the employee's smart button. This commit implements an automatic linking mechanism based on the folder hierarchy: - When a document is created or moved into an employee's directory (or its sub-folders), the system automatically associates it with the corresponding 'hr.employee' record. - If a document is moved to a standard folder (non-employee), any existing `res_model`/`res_id` link (including link to 'hr.employee') is kept untouched to preserve existing document associations. This provides a consistent user experience regardless of the entry point. Task-6310302
Manufacturing teams can now include draft manufacturing orders in planning workflows and confirm selected draft orders directly from the list view. This makes production planning smoother by removing extra manual steps and ensuring unplanned orders are easier to find and schedule.
Original PR description
The To Plan filter excluded draft manufacturing orders, while selected draft orders could not be confirmed in bulk from the list view. The Plan MO popup also enforced a fixed state domain. This commit's changes: - add a Confirm action that only confirms selected draft MOs - make the To Plan filter depend only on `is_planned` - replace the Plan MO popup's fixed state domain with the default Confirmed and To Plan filters task-6446072 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
The web interface now uses the existing phone icon instead of keeping a duplicate call icon that looked the same. This reduces unnecessary icon assets and helps keep the interface resources cleaner without changing the user experience.
Original PR description
odoo/odoo@36bf562 added the `call` icon to the subset. However the `phone` icon was already in it and is exactly the same. + Enterprise PR: odoo/enterprise#131224
The gift card email and website presentation has been adjusted so the card image fits correctly again. This restores a previous visual asset state and prevents broken or awkward gift card layouts for customers.
Original PR description
This PR adjusts the gift card template layout to better fit the gift card image. The image had been replaced in a previous commit (f37504d5142ff8459a9620a7a80d5393569d82cb) to remove unnecessary whitespace, but this broke the layout on the website; it has therefore been restored to its original state. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The HR time off screens now use the label "Company Holidays" instead of "Closure Days". This makes the wording clearer because these dates may be official company holidays without necessarily meaning the business is closed.
Original PR description
A previous task renamed 'Public Holidays' display name into 'Closure Days' but that label can be misleading since these days are not necessarily days when the company is closed. So, to make terminology clearer, 'Closure Days' label is being changed into 'Company Holidays' to better represent its purpose. task-6524048 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Accounting reports can now use a consolidation availability setting so they appear only when multiple companies are selected and affected. This helps users see the most relevant report variant for multi-company consolidation scenarios while keeping other contexts uncluttered.
Original PR description
With the related enterpise pr, add a new variant availability "consolidation" which makes the report visible only if it is impacted by several companies (company selector has at least 2 companies selected and options['companies'] is more than 1. This new type of variant should prioritize the other types in the selection. task-6398453 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Belgian payroll now assigns remunerations to the fiscal period in which they must be declared, rather than relying on case-by-case rules tied to the pay period. This improves accuracy for tax declarations such as 274.XX, 273S and 281.XX, and adds a safer modification flow when already filed periods need corrections.
Original PR description
In Belgian fiscality the period a remuneration is declared in is not always the period it is paid for. That difference was hardcoded case by case, through the arrears flag and a deferral of the…
In Belgian fiscality the period a remuneration is declared in is not always the period it is paid for. That difference was hardcoded case by case, through the arrears flag and a deferral of the intellectual property of a correction. Two fields carry it instead. The fiscal date of a payslip says which period its remuneration is declared in: the pay period, deferred to the confirmation date once the pay period has been declared. The follow pay period policy of a salary rule says how its own amounts behave, resolved per payslip line against the delta they bring and overridable by hand, so a benefit in kind stays in the pay period whichever period its payslip lands in. The 274.XX, 273S and 281.XX declarations select payslips and add up amounts through that attribution. They rebuild their base from the lines and worked days it is made of instead of reading the aggregate line, so an amount is declared in the period it is attached to rather than the one its aggregate landed in. The 274.XX also gains a modification flow: a declaration is filed against a Belcotax reference, a modification declares only what its predecessors left out of the period, and confirming a payslip of an already filed period flags it.
Employee documents are now organized consistently for all employees, whether or not they have system access. Payroll documents are placed in a dedicated Payroll subfolder, making sensitive HR records easier for authorized teams to find and manage.
Original PR description
This PR unifies the documents centralization for employees, regardless of their user status. * All employees get a dedicated folder for their documents. * Payroll documents are posted inside a new Payroll subfolder. Some fixes, cleanups, tests along the way. Details in individual commits. Task-6344800
Manufacturing users can now confirm draft manufacturing orders directly from the work order planning Gantt view when those draft orders are present. This reduces extra navigation and helps teams move planned production into confirmed execution more quickly.
Original PR description
The work order Gantt view could contain work orders from draft manufacturing orders, but users could not confirm those orders directly from the view. This commit adds a conditional Confirm Planning button that confirms the draft manufacturing orders represented by the current Gantt records. This commit's changes: - create a getter for draft manufacturing order IDs - display Confirm Planning only when draft orders are present - call `action_confirm` on draft orders when the Confirm Planning button is clicked. task-6446072
Enterprise sales and accounting screens now align with recent core improvements to how products and descriptions are handled. This keeps related workflows more consistent across apps and reduces confusion when editing orders, invoices, subscriptions, and localized accounting documents.
Original PR description
Adapt enterprise overrides of the product and description logic to follow the cleaner and more consistent logic introduced in the community changes. task-6241473 See also: - https://github.com/odoo/odoo/pull/286196
Mobile users can now use the Log out button directly from the Barcode app. This improves convenience for shared or handheld devices, and helps users return to the Barcode main screen after logging back in on smaller displays.
Original PR description
The existing 'Log out' button intended for scoped apps is now enabled for mobile use as well. Using it from the normal web interface will make the next login redirect to the same Barcode main screen if the device display is sufficiently small. Task ID: [6472390](https://www.odoo.com/odoo/my-tasks/6472390)
The VoIP interface now uses the existing phone icon name instead of a duplicate call icon name. This keeps the interface visually unchanged while simplifying maintenance and reducing unnecessary duplication.
Original PR description
odoo/odoo@36bf562 added the call icon to the subset. However the phone icon was already in it and is exactly the same. This commit replaces the `call` icon occurences in `voip` to the `phone` icon. + Community PR: odoo/odoo#287792
Financial reports can now show consolidation-specific variants when multiple companies are selected, making group-level reporting easier to access. Multi-company filtering is also more precise, so country and chart-of-accounts report variants are based on the main company rather than secondary companies.
Original PR description
1) Add a new variant availability "consolidation" which makes the report visible only if it is impacted by several companies (company selector has at least 2 companies selected and options['companies'] is more than 1. This new type of variant should prioritize the other types in the selection. 2) Activate by default the "consolidation" filter in multi-company. 3) In multi-company, the variants of availability type "Coa match" or "Country match" should only be visible if they match the main company, not the secondary ones. task-6398453
Odoo’s core web server now uses a more robust request-handling component for its gevent-based server. This should improve stability and maintainability for deployments without changing day-to-day user workflows.
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
Purchasing teams can now create vendor-specific purchase agreement templates that contain standard terms, sections, and notes without requiring predefined products. This makes recurring purchase forms easier to reuse while keeping product choices flexible for each order.
Original PR description
In this commit we allow preconfigured purchase templates without products; just with terms and conditions/sections and notes to give the user the flexibility of having a template with the same form everytime from a specific vendor while not being tied down by a product. Task: 4391726 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Manufacturing teams can now see work center block and unblock actions recorded in the activity history, improving traceability. Users also get cleaner bills of materials screens and color-coded availability information, making it easier to spot whether stock is sufficient for sales and production decisions.
Original PR description
This commit's changes: - Log work center block and unblock actions in the chatter. - Hide the Operations Performance smart button on BoMs without operations. - Display forecasted and available quantities in green when sufficient and red when insufficient. task-4277084 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
When scheduling an employee's end of collaboration, the employee contract end date is now automatically filled using the departure date. This reduces manual work and helps HR teams keep employee payroll and contract information consistent after departures are planned.
Original PR description
Currently, after creating an end of collaboration, the contract end date on employee is not defaulted. Since, the end date results comes from complex calculation process. In this, PR expected to help user by defaulting the contract end date based on the departure date from the end of collaboration wizard. How to test: 1. Open employee app 2. Select any employee, 3. Click gear button next to "New" 3. Select End of collaboration 4. Click Schedule 5. Look at the payroll tab task-6396218 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
Cancelled manufacturing orders remain accessible from the related sales order smart button. This helps users find and review cancelled production records directly from the sales order instead of losing that link.
Original PR description
Keep cancelled MOs linked to the SO smart button so the cancelled MO remains visible and users can access it directly from the SO. TaskID-6479345
Belgian payroll settings now capture additional external provider information, including worker accident insurance, group insurance, and prevention/protection service details. This improves payroll documentation and reporting, while demo data is corrected to avoid a validation error for a Belgian employee payslip.
Original PR description
Add fields for the infos of accident insurance for workers, group insurance, External Service for Prevention and Protection at Work Name (SEPPT). Rename the old accidental insurance fields to indicate that they're for employees. Task-6562739
Belgian payroll users can now mark a sickness relapse directly when managing time off in the Gantt schedule view. This makes the scheduling view consistent with the time off form and reduces extra steps for HR teams.
Original PR description
Sickness relapse was already introduced in the time off form but it couldn't be set from the gantt view. This commit adds the option to the gantt view. Task-6544579
Users can now drag an item by clicking anywhere on its row in the Gantt side panel, including the name, instead of needing to grab a small handle icon. This makes scheduling items faster and more intuitive, especially when working with many events.
Original PR description
Previously, users could only drag an event to schedule it by grabbing the handle icon next to its name. Clicking and dragging the event name itself did nothing. Now the whole row is draggable, not just the handle icon, making it easier to schedule events from the side panel. Task-6458712
The grid views used for timesheets have been visually refined to better match the redesigned Odoo interface. Columns now have clearer spacing, softer rounded styling, and improved readability, making timesheet grids easier and more pleasant to scan.
Original PR description
This PR aims to finetune the `web_grid` design after the webclient one to ensure it remains consistent. This first step address the most striking changes, adding a consistent roundness and a small gap in-between each column. task-6517392 ### My timesheet | Post redesign | This PR | |--------|--------| | <img width="1724" height="893" alt="image" src="https://github.com/user-attachments/assets/6311fa71-0ef2-425c-a158-059893a79296" /> | <img width="1719" height="820" alt="image" src="https://github.com/user-attachments/assets/f963f586-c86e-4624-bef2-b5cb2f5a97ed" /> | ### All timesheet | Post redesign | This PR | |--------|--------| | <img width="1722" height="922" alt="image" src="https://github.com/user-attachments/assets/67099abe-460c-4bed-aacd-62f5af3b639a" /> | <img width="1726" height="926" alt="image" src="https://github.com/user-attachments/assets/50742ff1-580c-4e76-b925-d3cddd01f6fc" /> |
Website editors can now use the AI chat while working on product pages, including product variants. This helps users generate content or images in context and keeps them on the correct product page when AI actions trigger a reload.
Original PR description
The Website Builder AI chat was only available on `website.page` records, so users could not ask the AI for help while editing a product page. Extend `isPageAiEditable` to `product.template`, add dedicated `ai.composer` records for the product page and its variants (with a "Help me generate an image" prompt button and the website builder agent so it uses the builder tools), and patch the Website Builder to launch the AI chat scoped to the current product — the currently displayed variant when the storefront exposes it, otherwise the template. Also edit the `reload` client tool to the builder plugin's iframe reload whenever the builder is open, so tool-triggered reloads keep the current product page instead of soft-reloading the whole builder action back to the homepage. task-6229094
When scheduling an end of collaboration in Belgian payroll, the employee contract end date is now filled in automatically from the departure date. This reduces manual follow-up and helps keep payroll records accurate after an employee leaves.
Original PR description
Currently, after creating an end of collaboration, the contract end date on employee is not defaulted. Since, the end date results comes from complex calculation process. In this, PR expected to help user by defaulting the contract end date based on the departure date from the end of collaboration wizard. How to test: 1. Open employee app 2. Select any employee, 3. Click gear button next to "New" 3. Select End of collaboration 4. Click Schedule 5. Look at the payroll tab task-6396218
The base system now returns the identifier of a newly generated API key, supporting OAuth server integration work. This helps connected services reliably reference and manage newly created keys, improving integration flows for upcoming authentication features.
Original PR description
Introduce OAuth server. For the architecutre, check commit message. Enterprise PR: https://github.com/odoo/enterprise/pull/125132 IAP PR: https://github.com/odoo/iap-apps/pull/1838 task-6312868
Odoo Studio now makes it easier to rearrange notebook tabs when customizing forms. This improves the form editing experience by letting users organize tab layouts more smoothly and fixes related tab selection behavior during editing.
Payroll calculation internals were adjusted to avoid automatically injecting salary rule categories into the calculation context. This helps make payroll rules clearer and more predictable, with related Belgian payroll data updated to match the new behavior.
The VoIP softphone interface has been refreshed with clearer keypad buttons, updated tab layouts, improved spacing, and a subtle background gradient. These changes make calling tools easier to scan and more polished for users, while reducing cramped layouts and unnecessary scrolling.
Original PR description
- Keypad: "circle" centered buttons (color contrast to review) - Tab entries: boxes instead of flat borders (grouped/ungrouped) - Tab buttons at the bottom: prettier active state - Trying other spacings (avoid scrolls, etc) - Trying slight gradient background
This update refreshes the spreadsheet component and allows spreadsheet sessions to be reloaded when needed by the server. This helps users recover from situations where the spreadsheet state needs to be synchronized again, improving stability and continuity.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/a0cd1e19e [IMP] session: allow server to force reload [task: 6236595](https://www.odoo.com/odoo/2328/tasks/6236595) 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
The Documents app now lets users preview documents directly from the secondary list used when adding files. The view is also simplified by hiding extra section actions that were not needed there, reducing confusion and helping users choose the right documents faster.
Original PR description
- Hide the searchpanel section actions in the secondary list view, as the primary purpose of this list is to add documents. Displaying these actions is unnecessary and can be confusing. - Add document preview functionality to the secondary list view. Task-6293704
This update adds a notes field to system views, giving teams a place to record context or guidance about view customizations. It helps administrators and implementers document changes more clearly without affecting day-to-day users.
Original PR description
Task~6571312 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
Website forms now offer a Send a Copy option so visitors can receive an email record of what they submitted. The feature reuses an existing email field when available, adds one when needed, and includes safeguards such as rate limiting and excluding uploaded file attachments to reduce abuse risk.
Original PR description
**Previously,** website forms did not allow visitors to receive a copy of their submission by email. This reduced transparency and created extra effort when visitors needed to keep a record of…
**Previously,** website forms did not allow visitors to receive a copy of their submission by email. This reduced transparency and created extra effort when visitors needed to keep a record of submitted data. **After this improvement,** all website forms include a "Send a Copy" option. When enabled, the form sends a copy of the submission to the email address provided in the "Send a Copy Email" field. ### Behavior of the option: - If the form already contains an email field, it is reused as the "Send a Copy Email" field. - If no email field exists, a new optional email field is added automatically. - Once a field is designated as the "Send a Copy Email" field, the following restrictions apply: - Duplicate and Delete actions are disabled for that field. - "Type" and "Input Type" options are no longer editable. - If the email field is optional and left empty, no email will be sent. ### Security considerations: - A rate limit is applied to prevent abuse, such as mail bombing. - Users are advised to configure CAPTCHA on forms when using this feature. - To avoid sending malicious content, uploaded files are not attached. Instead, only file information is included as text. Upgrade PR: https://github.com/odoo/upgrade/pull/9808 task-[4364668](https://www.odoo.com/odoo/all-tasks/4364668) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Customers can now see task tracking logs, such as stage changes and who made them, directly in the customer portal. This improves transparency and collaboration by sharing relevant task updates that were previously hidden as internal notes.
Original PR description
Currently, customers are lacking an overview of the changes that were done to a task, namely when the stage was changed and by whom. This makes collaboration difficult, as these tracking logs traditionally default to internal notes that are hidden from external users. task: 6453523 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Calendar users can now review and send cancellation emails from more places, including list and appointment views, with edits preserved before sending. A new draft state lets organizers save unfinished events without notifying attendees or syncing them to external calendars until the event is confirmed.
Original PR description
\* = google_calendar, microsoft_calendar, web This PR allows the edition and sending of the cancellation email when deleting and archiving calendar events everywhere these actions can be triggered…
\* = google_calendar, microsoft_calendar, web This PR allows the edition and sending of the cancellation email when deleting and archiving calendar events everywhere these actions can be triggered from the UI. Previously, it was only available on the calendar and form views. From now on, it can also be triggered from the list view and appointment's views. The existing codes allowing the deletion and to display the email composer is rewritten to make it more reusable as it is expected on more views. This PR also creates the draft state for the calendar events. When it is set, it prevents notifications from being sent to the attendees of the event and allows the authors to save the events without notifying attendees with incomplete information as they may need more time to gather all the information about the event. The draft state can only be set at the creation of the events. Otherwise, some issues can occur with the flow of events' notifications, and could prevent sending the cancellation email for booked events for instance. Draft recurring events are not allowed for a technical reason. The draft state cannot appeard in the form as users should not be able the reset it, so when it is unset it is not possible to easily propagate that change to the other events of the recurrence. Draft events are not synchronized with the external calendar as some of the them do not have that feature and will sent confirmation emails for the draft events but it should not be the case as they must not yet be confirmed to their attendees. Enterprise PR: https://github.com/odoo/enterprise/pull/110517 Upgrade PR: https://github.com/odoo/upgrade/pull/10271/ Task-5914191
Service teams can now open a service request form and plan unplanned shifts directly from there. The planning view opens with the right resource grouping and role filter, and the shift to schedule is highlighted at the top so planners can act faster.
Original PR description
Allow service requests to be planned directly from their form. - Make the service request list non-editable and open the form view. - Add a Plan button for shifts without a planned date. - Open the Gantt view grouped by resource with the selected role as default filter. - Display the To Schedule side panel with the shift to plan highlighted and displayed at the top of the list. task-6393079
The Ecuadorian localization settings have been moved higher on the Accounting settings page. This makes key electronic invoicing configuration visible immediately when users are redirected from dashboards or warnings, reducing time spent searching or scrolling.
Original PR description
Purpose: Moving the Ecuadorian 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-6571794
Users can now review and send cancellation emails when deleting appointment-related calendar events from more places in the interface. The change also prevents appointments from being saved as drafts, reducing process complexity and keeping appointment status handling more consistent.
Original PR description
This PR allows the edition and sending of the cancellation email when deleting calendar events everywhere these actions can be triggered from the UI. This PR also prevents appointments from being saved as draft. Otherwise, it may create complexities related to the appointment_status and archive attributes and the draft does not bring much in the process of the appointments. Community PR: https://github.com/odoo/odoo/pull/253345/ Upgrade PR: https://github.com/odoo/upgrade/pull/10271/ Task-5914191
The worksheet template setup now labels the section as "Worksheet Fields" and adds short guidance explaining that these are the fields technicians complete. It also shows each field’s type directly in the list, making templates easier to review and configure without opening each field.
Original PR description
- Rename `Worksheets Properties` to `Worksheet Fields` and add italic muted help between the header and the properties: the fields technicians will fill out for this worksheet. - Display the type icon and label beside worksheet properties so the selected field type is visible without opening the definition. task-6542816
Restaurant appointment lists now better support moving several records at once through drag and drop. This keeps the appointment scheduling interface aligned with the latest list reordering behavior, making bulk organization smoother for users.
Original PR description
This commit adapts the moveRecord override to the new multi-resequence code added in https://github.com/odoo/odoo/pull/284988 task-6432283
Users can now select several records and move them together in list and kanban views. This speeds up organizing work across rows, groups, and columns while preserving the selected records' order.
Original PR description
*: account, crm, mrp, sale_management This commit adds support for selecting and dragging multiple records simultaneously in both list and kanban views. **Key Features:** * **Unified Drag Payload:** Selected records are visually gathered into a single generic row/card element during the drag sequence. * **Sequence Preservation:** Maintains the relative order of all selected records upon drop. * **Cross-Group Support:** Seamlessly handles moving multi-record selections across different groups or columns. task-6432283
Some Odoo interface icons were not appearing for users on Safari and iOS browsers because of how those browsers handled icon names with hyphens. This update ensures those icons display correctly, improving navigation and visual clarity across Apple devices.
Original PR description
__Problem__ Since `odoo_ui_icons` moved to ligatures, 42 of its 203 icons render as nothing on iOS (Safari and Chrome) and macOS Safari, `oi_view-kanban` among them. Chromium is fine. __Reason__ WebKit treats `-` as a line-break opportunity and splits the text run there, so the ligature never forms. Only names whose prefix is not itself an icon break: `oi_x-square` survives because `oi_x` exists, `oi_view-kanban` does not. Nothing is painted at all, rather than the raw string, because the font's letter glyphs are empty and zero-advance: they exist only so ligature components resolve. Hence the silent breakage. __Fix__ `word-break: keep-all` keeps the run intact.
This change fixes a small display issue in sales orders by ensuring the Description field has the proper column label when product and description fields are stacked. It also re-enables an accounting-related test to help prevent this issue from returning.
Original PR description
This commit enables a previously skipped test that was expected to be fixed by 1e35b9a. It also adds the column name for the Description field in the stacked product and description fields in the sale app. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Managers in multi-company setups can now open employee records and expense items without being blocked by access errors caused by related employees in other companies. Expense team approvers also gain more flexibility to create expenses for their subordinates across company boundaries where allowed.
Original PR description
_(updates on July-17th and July-28th for points 2. and 3. in `hr_expense`)_ # Introduction **1\.** A fix to `hr_org_chart` was initially proposed. I think it is mergeable because it fixes the…
_(updates on July-17th and July-28th for points 2. and 3. in `hr_expense`)_ # Introduction **1\.** A fix to `hr_org_chart` was initially proposed. I think it is mergeable because it fixes the user-experience properly like expected in Odoo standard. Other commits are suggested to `hr_expense`. They were designed to allow more flexibility in the management of `hr_employee.company_id` (in multi-company context) and allow not to duplicate the `hr.employee` of each companies of the `res.users`. **2\.** The [FIX] silences a multi-company access error when searching for Expense validators => it seems safe **3\.** The [IMP] largely allow more flexibility for a "Expense: Team Approver" when creating expenses on behalf of its subordinates # 1. in hr_org_chart [FIX] Prevents multi-company error when recursively searching for ancestors. <img width="1035" height="789" alt="image" src="https://github.com/user-attachments/assets/d5517f79-7efc-4223-ae77-0af8b25a3d1e" /> ### Issue description In a multi-company environment, when one of the `hr_employee.company_id` of a hierarchy is not in the allowed companies of a Manager's `res_users.company_ids`, this Manager can view `hr.employee` in the list view but cannot open their forms. This happens when: - `hr_org_chart` module is installed - the Org Chart is displayed on the 1st page of the `hr.employee` form, like when the HR settings "Skills Management" is disabled (in `res.settings`) => thus the whole form becomes inaccessible from the manager When a `hr.employee` form is opened, a multi-company access error is thrown to him, even if the `company_id` of the opened `hr.employee` is in the user's `res_users.company_ids`, because of the hierarchy's `company_id`. It should be expected that the part of the Org Chart which is not allowed to be seen would just be hidden. ### Steps to reproduce Data setup: - Employee "A" in company A - Manager "M" in company A, manager of "Employee A" - Manager of manager "MM" in company A, manager of "Manager M" - And now, in company B (let's say a Holding), the "Director" is manager of "Manager MM" - "Manager M" is only given access access to Company A - the module "hr_org_chart" is installed Actions: - Login with Manager M - Browse to Employees list and try and open the form of "Employee A" (up to tab _"Professional information"_, if it is not the 1st of the notebook) ### Proposed fix This PR re-uses the already existing method `_check_employee` which contains all the logic to solve the issue. Maybe the call to this method was forgotten? This PR simply call this method when finding an ancestor, in the controller of `hr_org_chart`. This fix is thus very limited to the call to the public method `hr_org_chart.get_org_chart()` made by the Org Chart widget. ### Desired behavior after PR is merged The part of the Org Chart not allowed to be seen by "Manager M" is hidden. # 2. hr_expense [FIX] <img width="541" height="415" alt="image" src="https://github.com/user-attachments/assets/d594815b-2b77-4088-878b-9b192b64d6a3" /> ### Issue description As an employee, I click on the button "View Report" on my expense. I get a multi-company access error, preventing me to view and edit my expense report. This is because the manager of the department I belong is in a company I'm not allowed to see. This can also happen just when opening my Expense (instead of Expense Report). ### Current behavior before this PR The employee is blocked to continue editing its Expense or to submit it to a Report. ### Current behavior after this PR The employee can edit and submit its Expense no matter the `company_id` of its hierarchy. Technically: the `can_approve` field on the expense sheet uses a localized `.sudo()` method to bypass multi-company limits when searching if the current user is a validator. # 3. hr_expense [IMP] <img width="1028" height="549" alt="image" src="https://github.com/user-attachments/assets/1096c0d4-d025-46a9-8559-6bab5de71577" /> ### Improvement summary In multi-company environment, allow a "Expense: Team Approver" to create Expenses for its subordinates (`hr_expense.employee_id`) **no matter the `hr_employee.company_id` of its subordinates**. The domain of `hr_expense.employee_id` keeps the security of `check_company=True` => thus the Manager only sees `hr.employee` having their `company_id` in the manager's allowed companies (`res_users.company_ids`). ### Current behavior before this PR Context: a 8-companies environment where the `hr.employee` of each hierarchy chains are splitted in many different companies, like: - top-level (admin board): 1 company - middle management: approx. 2 companies - down level: the other companies The "down level" have `hr.employee` but no `res.users`. The "middle management" have `res.users` and must create the Expenses of their "down level" subordinates on their behalf. Issue: as a manager, as per Odoo proposal, I need to have a `hr.employee` in the same company of my subordinates to be able to create Expense of their behalf. However, this is very inconvenient because as a Manager, I can have employees in various companies. And my own manager it not in the same company than me, so the same issue applies recursively. ### Behavior after this PR is merged The domain of the field `expense_id.employee_id` is more permissive. As a Manager, it allows me to select the Employee I manage in my active company, no matter if I have or not myself a `hr.employee` in this company. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#286293 Forward-Port-Of: odoo/odoo#266261
Return checks are now editable only when the related return's main company is active. This avoids repeated permission checks for each visible record, reducing the risk of intermittent connection issues and making the experience more reliable.
Original PR description
…company Simplify the JS logic for the return checks to make them editable only if the main company of the return is active. It used to make an access right call for each visible record, leading to some connection issue hard to reproduce.
The sales rental stock forecast icon now turns red when a product is unavailable, instead of incorrectly staying green. This helps sales users quickly spot stock availability problems on rental sale orders and avoid misleading confirmations.
Original PR description
## Issue Before This Commit: The forecasted report icon stays green instead of red for an out-of-stock product (forecast issue) on a sale order line when sale_stock_renting is installed. ## Steps to…
## Issue Before This Commit:
The forecasted report icon stays green instead of red for an
out-of-stock product (forecast issue) on a sale order line
when sale_stock_renting is installed.
## Steps to Reproduce:
- Install `sale_stock_renting`,
- Create a new sale order,
- Add an out-of-stock product to the sale order,
- Observe the forecasted report icon on the sale order line,
The icon appears green.
## Cause of the Issue:
As part of the Owl 3 migration in PR [#270478](https://github.com/odoo/odoo/pull/270478), `calcData` was
changed from a regular object to a computed value:
`this.calcData = {}` was replaced with
`calcData = computed(() => this.initCalcData())`.
The corresponding template usage was not updated and continued to
access `calcData` as a property instead of calling the computed
value. As a result, `this.calcData.forecasted_issue` evaluated to
`undefined`, preventing the `text-danger` class from being applied
when there was a forecast issue.
## With This Commit:
The template now invokes `this.calcData()` correctly, allowing
`forecasted_issue` to be evaluated and ensuring that the forecasted
report icon turns red when the product is unavailable.Users who follow a private project task can now open it even when older or mismatched attachments are missing their expected document link. The fix prevents an internal document eligibility check from causing an access error while preserving normal permissions for attachments and documents.
Original PR description
Issue: A user following a task in a private project can be allowed to read the task without having access to its parent project. If the task contains a legacy or desynchronized attachment without a…
Issue: A user following a task in a private project can be allowed to read the task without having access to its parent project. If the task contains a legacy or desynchronized attachment without a related document, opening the task can nevertheless raise an AccessError while loading the chatter. Steps to reproduce: - Create a follower only private project and a task in that project - Add an internal user as a follower of the task but not of the project - Leave a task attachment without its expected documents.document link - Open the task as that follower Cause: When computing the attachment's linked document, `_exclude_documents_mixin()` calls `_check_create_documents()` on the linked business record with the requesting user's permissions. That eligibility hook may consult protected records such as the task's private project, even though it is only used to classify the attachment. https://github.com/odoo/enterprise/blob/656469d08453a823979153200cddd3688f815468/documents/models/ir_attachment.py#L41-L53 Solution: Evaluate only the document creation eligibility hook with elevated rights. This keeps chatter metadata independent from access to the hook's related configuration while leaving attachment access, document lookup, and explicit document creation checks under the requesting user's permissions. opw-6479654 Forward-Port-Of: odoo/enterprise#128929
This fix keeps Odoo's Greek e-invoicing records aligned with actions already completed by the external provider, even if a later Odoo step fails. It also updates QR code generation so invoice QR images continue to work correctly after recent platform changes.
Original PR description
e-invoo operations occur outside the Odoo transaction, so a later failure could roll back local state while the corresponding external operation had already occurred. Commit the provider issuance result at the respective transaction boundaries. Also adapt the QR code generation as here in 19.3 upwards it doesn't use base64.b64encode anymore, but rather pass the image bytes directly. Note: regarding the commit thing, this is partially what we already have in 18.0 till 19.2, we just removed it from 19.3 at the time because it was failing the ci/style test and it needed an exception from the framework team but we didn't have the time back then we needed it to be merged asap, that's why we're adding them again right now. related: https://github.com/odoo/odoo/pull/281739 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#285581
Users with the Invoicing and Banks role can now use bank reconciliation actions that were previously blocked by access rules. This restores the intended workflow without changing access for higher-level accounting users.
Original PR description
The bank reconciliation "set account" button and the auto-reconcile wizard create account.select.account.line and bank.rec.auto.reconcile.wizard records, but their ACLs only granted access to group_account_user. Grant both ACLs to group_account_basic (Invoicing and Banks) instead, so these users can perform bank reconciliation as intended; group_account_user still inherits the access through group implication. no-task-id
The AI module now skips processing content chunks that do not yet have an embedding model assigned. This prevents avoidable setup-time errors while allowing the normal scheduled process to assign the correct model later.
Original PR description
When the AI module is installed, the `embedding_model` of default agents is left empty to avoid an API call to IAP. This means that we can have embedding chunks without an embedding model set. We shouldn't try to embed those chunks as it will fail with an "Invalid embedding model" error. These chunks will automatically get a proper embedding model set when the cron that checks embedding model deprecation runs.
This fixes exports of binary file data so they use the expected base64 format again. It helps preserve compatibility with existing exports, integrations, and data handling processes that rely on that format.
Original PR description
Export base64 data like we used to do. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#288195
Copying a manufacturing work order now keeps the production step name exactly as entered instead of adding “(copy)”. This avoids confusing labels on backorders and makes manufacturing steps easier to recognize.
Original PR description
Main The “name” field in `mrp.workorder` did not have an explicit `copy` attribute, so it inherited the generic behavior of any `Char` field named “name” (fields_textual.py:531-533), where the suffix helps distinguish the original from the copy. https://github.com/odoo/odoo/blob/808ed2e6d2aeba502e2e92d1343c2004745525b0/odoo/orm/fields_textual.py#L529-L534 Before: When copying a work order, the name of the production step was automatically suffixed with “(copy)”. Example: A work order with the step “Cutting” generates a backorder with steps named “Cutting (copy)”. After: The step name is copied as-is, without a suffix. Example: The backorder retains “Cutting”. [Task 6571512](https://www.odoo.com/odoo/project/966/tasks/6571512) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The U.S. accounting setup now classifies cash difference gains and cash discount gains as other income instead of regular income. This improves financial reporting accuracy by placing these gains in the more appropriate income category.
Original PR description
Switch the account type of Cash Difference Gain and Cash Discount Gain from income to income_other. task-6468767
The expense report print action now shows the clearer label "Print" instead of "Expenses Report". Printing an expense without a name no longer causes an error, improving reliability for users handling incomplete expense entries.
Original PR description
This commit fixes 2 issues 1) The expense report action label was "Expenses Report" while it should be "Print" 2) When an expense is attempted to be printed while having no name, a traceback was shown
Completed or cancelled stock transfers no longer show a secondary Validate button. This avoids confusing users with an action that is no longer needed once a transfer is finished or cancelled.
Original PR description
Issue Before This Commit: ======================== The secondary Validate button is displayed on pickings in the done or cancelled state, even though no further validation is required once a picking has reached either of these states. Steps to Reproduce: ========================= 1. Install the stock module. 2. Create a picking and validate or cancel it. 3. The secondary Validate button is still visible. Cause of the issue: ========================= A change introduced by [PR](https://github.com/odoo/odoo/pull/285240), _compute_validate_button_style to set validate_button_style to secondary for pickings in the done or cancelled state. As a result, the secondary Validate button remains visible. After This Commit: ======================== Update _compute_validate_button_style to ensure that the secondary Validate button is no longer displayed when the picking is in the done or cancelled state.
Financial reports now correctly round the Change column when users switch the report rounding unit during amount-based comparisons. This keeps comparison figures consistent with the rest of the report and avoids misleading precision in financial reviews.
Original PR description
When doing a comparison on any report in `Amount` and then changing the rounding unit results in the `Change` column not being rounded to the correct unit. steps to reproduce: 1. Open balance sheet 2. Click Comparison button 3. in Comparison click `Previous Period` and set `Comparison in` to Amount 4. Change the rounding unit of the report Expected behaviour: The change column rounds its values to the chosen rounding unit Actual behaviour: The values inside the Change column keep their original rounding
The website AI composer menu now places the “Select Elements” option after document-related attachment actions. This keeps similar document options together, making the menu easier to understand and use.
Original PR description
Before this commit, "Select Elements" tool appeared between "Attach Files" and "Add from Documents" -when Documents is installed. This change should change the ordering so both Document attachment options appear next to each other for better semantic grouping. Given the current sequences assigned for both options, a sequence value of 30 should stay below them without colliding with other options.
Odoo now handles empty or incomplete image attachments safely when users open the media dialog or use the chatter. This prevents an error screen caused by failed uploads or malformed email attachments and lets the interface continue loading normally.
Original PR description
Problem: Interrupted uploads or malformed email payloads can create 0-byte binary `ir.attachment` records where the `checksum` is `False`. Accessing the computed `image_src` field on these records…
Problem:
Interrupted uploads or malformed email payloads can create 0-byte binary `ir.attachment` records where the `checksum` is `False`. Accessing the computed `image_src` field on these records triggers a `TypeError: 'bool' object is not subscriptable` when attempting to slice `attachment.checksum[:8]`. This crashes the Media Dialog and Chatter.
Purpose:
Add a fallback boolean guard to `attachment.checksum` inside `_compute_image_src` so that empty attachments evaluate safely to a string ('0') instead of raising a traceback, allowing the UI to render gracefully.
Steps to Reproduce on Runbot:
1. Go to Settings > Technical > Database Structure > Attachments.
2. Create a new record: Name: `test.png`, Type: `File` (Binary), File Content: [leave empty], Is public document: Checked.
3. Open any record with a Chatter (e.g., Contact or CRM Lead) and click "Insert Image" to open the Media Dialog.
4. The system attempts to evaluate `image_src` and throws the `TypeError`.
Notes:
A test (`test_compute_image_src_empty_checksum`) was added to `test_ir_attachment.py`
opw-6482674
Forward-Port-Of: odoo/odoo#287953
Forward-Port-Of: odoo/odoo#287444Users can now create and sign requests from shared Sign templates even when the template contains custom fields restricted to another group. This prevents an access error in valid signing workflows while keeping field selection restrictions in place for template setup.
Original PR description
Version-19.5 Steps to reproduce: - As Administrator, go to Sign > Templates and create a template. - Add a custom field (e.g. 'B-day'), uncheck 'Shared' and set 'Used by' to a group the sender/signer…
Version-19.5 Steps to reproduce: - As Administrator, go to Sign > Templates and create a template. - Add a custom field (e.g. 'B-day'), uncheck 'Shared' and set 'Used by' to a group the sender/signer does not belong to (e.g. an HR group). - Place the field on the document and save. - Share the template via its 'Authorized Groups' field (not 'Authorized Users') with a group the sending user belongs to. - Log in as that user, open the template, click "Sign now", assign a signer and sign now. Issue: `_check_send_ready()` and `_populate_constant_items()` read `item.type_id.item_type` without `sudo()`. A custom field type restricted to a specific group is unreadable by users who only have template access via "Authorized Groups", so creating a SR through 'Sign Now' raised an AccessError despite full access to the template. Fix: Read the field type through `sudo()` in both methods, since checking its technical type/name is an internal check and shouldn't be gated by the field 'Used by' restriction, which only controls who can pick that field type while building templates. Taskid-6574543
The appointments calendar now opens on the next upcoming booking instead of jumping to the most distant future booking. This makes it easier for staff to review imminent appointments without manually navigating back through the calendar.
Original PR description
Problem: The bookings calendar of an appointment type opens on the week of the most distant booking instead of the next one, even when a booking exists later the same day. Cause:…
Problem: The bookings calendar of an appointment type opens on the week of the most distant booking instead of the next one, even when a booking exists later the same day. Cause: `action_calendar_meetings` sets the landing date from `appointments[0].start`, where `appointments` is `self.meeting_ids.filtered_domain(domain)`. `calendar.event` is ordered on `start desc` and a one2many is read in the order of its comodel, so the first record is the furthest booking rather than the next one. The original `search([...], order='start')` was replaced by the one2many in 14b5caccc325 (odoo/enterprise#23191). Solution: Sort the filtered bookings on `start` in `action_calendar_meetings`. That method is the only place the initial date is built, and `action_calendar_event_view_request` reuses it for the gantt start date, so both entry points are covered. `calendar.event` keeps its `start desc` order, which the booking list views rely on. Steps to reproduce: - Go to Appointments. - Open the appointment type "Schedule a Demo" and click Appointments. - Click New, set the date to later today, save and go back. - Click New, set the date to one year from now, save and go back. - Go back to Appointments, reopen "Schedule a Demo" and click Appointments. - Switch to the calendar view. - Observe that the calendar opens on the week of the booking one year from now. Ticket [link](https://www.odoo.com/odoo/project.task/6480029) opw-6480029 Forward-Port-Of: odoo/enterprise#130385 Forward-Port-Of: odoo/enterprise#129000
The Send to eTransport button is now shown when a Romanian stock transfer is ready as well as when it is completed. This lets users prepare required eTransport reporting at the right stage of the delivery process instead of waiting until after completion.
Original PR description
Currently, the Send to eTransport button on `stock.picking` is only visible when picking is done. This PR fixes this behaviour and makes it visible when picking is ready or done both. task-5930984 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#285429 Forward-Port-Of: odoo/odoo#257321
Fixed an issue where receiving a very long message could leave a chat channel scrolled to the end of that message instead of showing the start of the new message. This improves readability and keeps users oriented when new messages arrive, including cases with hidden notifications or delayed message rendering.
Original PR description
Before this commit, receiving a very long message in a channel scrolled at the bottom could move the message list to the end of that message instead of to its beginning. Every message received…
Before this commit, receiving a very long message in a channel scrolled at the bottom could move the message list to the end of that message instead of to its beginning. Every message received afterwards then kept the list at the end. The test "should scroll to bottom on receiving new message if the list is initially scrolled to bottom (asc order)" fails on runbot with:
10. [toBeGreaterThan] expected value to be strictly greater
> Minimum: 20762
> Received: 5190.500
This happens because `applyScroll` also runs outside of a patch, on a resize of the message list or on a loaded image, i.e. while a received message is in the store and not rendered yet. Such a run finds no element for the message, scrolls to the bottom of the list, and records the message as the newest one the scroll was applied on. The patch that renders the message then finds no newer message, and keeps the list at the bottom.
This commit fixes the issue by keeping the newest message `applyScroll` recorded when the first newer message has no element yet, so that the patch that renders the message applies the scroll.
Note that the added test delays the registration of the message element, as a resize cannot be timed between the store update and the patch.
https://runbot.odoo.com/odoo/error/946929
Forward-Port-Of: odoo/odoo#287985
Forward-Port-Of: odoo/odoo#286759This fixes a setup issue in the Panama localization by ensuring the Contacts app is included when needed. It helps prevent menu or installation problems related to local administrative areas.
Original PR description
The modules anchored a dedicated "corregimiento" menu within the `contacts.menu_localisation` without depending on `contacts` module. runbot-947185
Product route diagrams now open reliably instead of showing a JavaScript error. Users can view the diagram and follow its links to related records, avoiding interruption when reviewing product logistics setup.
Original PR description
Issue before this commit: ========================= Opening a product's route diagram raises an uncaught JavaScript error, preventing the report from being opened correctly. Steps to Reproduce: =================== - Create a product. - Open the product form and go to the Inventory tab. - Click on View Diagram. - An uncaught JavaScript error is raised over the diagram. Cause of the issue: =================== The report viewer moves each clickable element into a link wrapper, making the wrapper its new parentNode. The subsequent operation then tries to insert the wrapper into itself, causing a JavaScript error. With this commit: ================= Users can open the route diagram without an error and navigate to the related records through its links.
Manufacturing orders now apply their selected date to all finished product movements, preventing inconsistent inventory dates. This reduces intermittent failures and helps keep manufacturing and stock records aligned.
Original PR description
Followup to #279316, which describes this bug and fixes it incompletely, only covering zero-quantity/unconsumed moves instead of the finished ones (which get overwritten in `_post_inventory()`). This fix writes the set date value to all finished moves. This issue manifests as a heisenbug with the test `test_component_addition_to_finished_mo` nondeterministically breaking, as the fix and the test focused on the newly added component moves and didn't take the initial move into account. Task ID: [6226710](https://www.odoo.com/odoo/my-tasks/6226710) Runbot error: [945505](https://runbot.odoo.com/odoo/error/945505)
Quotation templates now correctly show price, discount, and tax columns for lines that have a description and price but no product. This prevents users from thinking saved prices were lost when reopening templates.
Original PR description
Steps to reproduce: - On a quotation, add a line with product description + unit price only. - Action menu > Save as template, to create a full quotation template. - Open that template: Price/Discount/Taxes columns are hidden on the productless line, as if the price was lost. Before this commit, `_compute_has_productless_lines` looped on `self` but read lines from `self.sale_order_template_line_ids` instead of `template.sale_order_template_line_ids`. Recomputing several templates in one batch made every template share the same aggregated result, hiding the price columns even though `price_unit` was stored correctly. After this commit, the compute reads `template.sale_order_template_line_ids`, so each template gets its own value. opw-6566552 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Quotation template names in Sales can now be shown in each user's preferred language when translations are provided. This fixes cases where template names always appeared in the original language they were entered in, improving clarity for multilingual sales teams.
Original PR description
The Template name field on `sale.order.template` was a plain Char, so it always displayed in whichever language it was typed in, regardless of the viewing user's language. Add `translate=True` so users can provide a per-language name via the standard Translate dialog. opw-6561520 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Live chat information panels now show chatbot answers even before the related conversation messages are loaded. Free-text chatbot responses are also displayed as clean plain text, improving readability and preventing layout issues.
Original PR description
Chatbot answers were read from the messages loaded in the thread, so the info panel listed them only once the message holding them was fetched. They are now stored on the channel itself, independently of its messages. Free input answers are html fields: render them as plain text, otherwise the markup adds a block element that pushes the answer off the vertical center of its icon and prevents it from being truncated. task-6449288
Manufacturing order overviews now include the cost of subcontracted product components, making estimated production costs more accurate when subcontracting is involved. A related display issue in debug mode was also fixed so the overview works reliably for these manufacturing scenarios.
Original PR description
In the MO overview, when one of the components is subcontracted, and the linked RFQ/PO is displayed, the cost of the PO does not include the components of the BoM. The total estimated cost of the MO is therefore not accurate. Other than that, a props issue was fixed for an OWL component. task-6516013 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Signed quotation PDFs created through the customer portal are now saved as automated entries rather than editable customer comments. This prevents customers from accidentally deleting the signed document before the order is confirmed, preserving an important business record while leaving normal comments unchanged.
Original PR description
Issue: A customer who signs a quotation can delete the chatter entry containing the generated signed PDF. For quotations awaiting a wire transfer, this can remove the only retrievable snapshot of the…
Issue: A customer who signs a quotation can delete the chatter entry containing the generated signed PDF. For quotations awaiting a wire transfer, this can remove the only retrievable snapshot of the signed quotation before the order is confirmed. Steps to reproduce: - Create a quotation requiring an online signature and payment. - Sign it from the customer portal and select wire transfer. - Delete the "Order signed by ..." entry from the portal communication history. Cause: The signing endpoint posts the generated PDF as a regular customer authored comment. Portal chatter allows customers to update their own comments, and deleting one clears its attachments, so the signed PDF is physically removed. https://github.com/odoo/odoo/blob/e479111294b11058038defc31505cc81ac1f1821/addons/sale/controllers/portal.py#L348-L358 Solution: Classify the signed document entry as an automated comment. This keeps it visible and attributed to the customer while ensuring that both the portal interface and backend message rules treat its content and attachment as immutable. Regular customer comments keep their existing behavior. opw-6466029 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#287478 Forward-Port-Of: odoo/odoo#283595
Fixes an error that could stop the Forum app from being installed when website cookie and third-party tracking blocking settings were enabled. The website now reuses already available cookie preference information during page/template processing, improving reliability for setup and module installation flows.
Original PR description
**Steps to reproduce:** - Install Website app - Go to Settings - Enable `Cookies Bar` and `Block tracking 3rd-party services` - Try to install Forum app (`website_forum`) - `RPC_ERROR: Odoo Server…
**Steps to reproduce:**
- Install Website app
- Go to Settings
- Enable `Cookies Bar` and `Block tracking 3rd-party services`
- Try to install Forum app (`website_forum`)
- `RPC_ERROR: Odoo Server Error`
**Issue:**
During `_render_template`, `RuntimeError: request not bound` is raised due to `self.env['ir.http']._is_allowed_cookie('optional')` in `_should_remove_third_party_trackers` depending on `request`, which is not available (unbound `<LocalProxy>`).
This was introduced by [1] where the value is recomputed instead of relying on the context.
In previous versions, the flow was not triggered as `website_id` was not in the context of `_post_processing_att`,
but it was added by [2].
Before [2] `_prepare_frontend_environment` was being restricted to calls made with `request` set (in < 19.4
versions), but now the context is always set so it triggers `_should_remove_third_party_trackers` check.
Also post 19.4 we have [3] which now sets the editable variable to `true` when `translatable` is `True` and
`edit_translations` is not present in the context. This changes the branding mode from `inherit_branding_auto`
to `inherit_branding`, which short-circuits `_post_processing_att` and prevents the problematic behavior.
**Fix:**
Use the context `cookies_allowed` value that is computed in `website.py` by `_render_template`.
[1] https://github.com/odoo/odoo/commit/0c1799f81bc70a35c8dc429c7425d3c8109ea75a
[2] https://github.com/odoo/odoo/commit/b4d852a250801921ab899eff805ab078c98c374f
[3] https://github.com/odoo/odoo/commit/05c2fb1f364ca61adc65c2b87d020885f8184a9a
opw-6477558
Forward-Port-Of: odoo/odoo#283133Canadian CPA payment bank records without a selected financial institution no longer trigger the institution number validation. This prevents unnecessary errors when bank details are incomplete or do not include an institution.
Original PR description
Don't apply the constraint when there is no financial institution on the bank. runbot-947001
The Timesheet Assistant now updates immediately when a timesheet date is changed from a linked task. This prevents users from seeing outdated timesheet information and avoids needing to manually refresh the page.
Original PR description
Steps to Reproduce: - Install timesheet_grid and activate Timesheet Assistant - Open a timesheet and click the task external link - Change the timesheet date from the task form and save Issue: When the timesheet date is changed from the task, the assistant still shows the old date until the page is refreshed Fix: Reload assistant timesheets after the linked task is saved and refresh or clear the selected timesheet based on the new date task-6454988 Forward-Port-Of: odoo/enterprise#131029 Forward-Port-Of: odoo/enterprise#130265
This fix prevents Turkish payroll payments from failing when a payslip configuration does not include stamp tax. The system now treats missing stamp tax as zero, allowing MUHSGK V2 payments to complete reliably.
Original PR description
## Steps to Reproduce: - Install the `l10n_tr_hr_payroll` and `hr_attendance` modules with demo data. - Switch to the company "My Turkish Company". - Settings > Set `Tax Responsible` and `SGK Workspace Registration Number`. - Pay Structures > `Türkiye: Monthly Pay` > remove `Stamp Tax Deduction (STAX)`. - Create and validate any employee's payslip. - Pay the payslip using the `MUHSGK V2` mode. ## Error: `TypeError: bad operand type for abs(): 'NoneType'` ## Cause: When the STAX code is missing from `totals_per_code`, it returns None. And calling `abs()` on this value raises a TypeError. ## Fix: Use `0` as the default value when STAX is missing. Align with the other values retrieved from `totals_per_code`, such as BTNET, CURTAXABLE. sentry-7719230995 Forward-Port-Of: odoo/enterprise#131360
Fixes an issue where the View and Unreconcile buttons in the invoice payment popover could fail with an error. The popover now also shows payment dates in the user's localized format, improving clarity for invoice review.
Original PR description
When clicking the "View" or "Unreconcile" buttons in the payment popover of the invoice payments widget, a TypeError was raised: `TypeError: ctx.this.props._onOpenMove is not a function`. Use `useProps()` without arguments on `AccountPaymentPopOver` so that all dynamic incoming props are properly bound to `this.props`. Additionally, display `this.props.formattedDate` instead of the raw `date` string in the popover template, aligning with commit 82f6098eedd1 to ensure the date is displayed in the user's localized format. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes an issue where suggested combo items in Point of Sale could be priced as zero and where combo prices were shown incorrectly in product details. Cashiers and customers now see accurate combo pricing during sales, reducing checkout errors.
Original PR description
Applying a suggested combo set the converted lines' price to 0, and the product info popup showed wrong prices incl for combos In this PR (https://github.com/odoo/odoo/pull/286576) `computeComboItems()` became `getComboPrice()` and its `parentProduct` argument became `this`, which is passed to `getPrice()`` as the variant. `getPrice()` reads `lst_price`, a field that only exists on product.product But `this` is a template when called from createComboFromLines() and getComboTaxDetails(), so the price was NaN and got rounded to 0 FIX: Find the variant first task-id: 6566915 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes an issue where Point of Sale could fail to open after a related module had been uninstalled. The system now skips outdated stored data for missing modules, helping shops get back into their Point of Sale without errors.
Original PR description
Models from uninstalled modules that were previously loaded in the indexDB of a PoS config were raising a traceback when opening the config again, as the PoS was still trying to load them. We now avoid trying to load them if they are not present anymore. task-6567097
This fixes a display issue in the Time Off calendar where icons and text in the leave details card were misaligned. The card now uses the correct styling so managers and employees can read time-off details more clearly.
Original PR description
Bug reproduction: - Install hr_holidays go to the timeoff app and then to the overview tab - Open calendar mode, click to some timeoff - Aligning of the icons and texts are not proper Bug cause: - In the other leave cards or timeoff request popups: -- there is o_hr_leave_form and inside of it there is o_inner_group -- o_inner_group keeps the icons and texts in the same row - Since modal is opened as small one and that class is not there -- for hr_leave_report_calendar_view_form -- modal-sm styling collapses grid to a single column Bug solution: - New card class o_leave_report_card that includes o_inner_group -- for hr_leave_report_calendar_view_form task-6545420 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
Fixed an issue where the payment information popup on invoices could appear empty after reconciliation. This restores access to payment details and actions like viewing or unreconciling payments, preventing errors for accounting users.
Original PR description
odoo/odoo#287426 (commit `22de645`) replaces static `props` with `useProps`, not allowing the content popover to receive its dynamic props. The commit mentions that empty `props` definition should be removed, which was the case in AccountPaymentPopOver. Instead, it was replaced with `useProps(popoverProps)` which is the outer `web.Popover` component. By removing the props definition, we restore the preceding behaviour. Steps to Reproduce 1. Create an invoice. 2. Post it. 3. Go to the Accounting Dashboard and click `Transactions` to open the reconciliation widget. 4. Click `Create` to add a bank statement line with an amount sufficient to cover the invoice. 5. Ensure the statement line and the invoice are fully reconciled. 6. Open the invoice and click the info icon `(i)` next to `Paid on X`. pad-accountingv20
This fix makes required, invalid, and read-only fields display correctly when multiple fields are grouped in one list cell. Users now get clearer visual cues and more reliable keyboard navigation, reducing confusion when editing records and saving forms.
Original PR description
*: account, project, sale, sale_project Fields stacked in a single cell with the <column> tag were never styled when required or invalid: o_required_modifier and o_invalid_cell were only computed for…
*: account, project, sale, sale_project Fields stacked in a single cell with the <column> tag were never styled when required or invalid: o_required_modifier and o_invalid_cell were only computed for columns of type "field", so a required sub-field showed no underline and, left empty, stayed unhighlighted while still blocking the save. Mark the wrapper of the sub-field rather than the whole cell, as a column group cell may display several fields of which only one is required or invalid. Readonly modifiers (o_readonly_modifier and text-muted) were not computed for the fields stacked in a single cell with the <column> tag, so a readonly sub-field was rendered as an editable one. Compute them on each sub-field wrapper, as a column group cell may display several fields of which only one is readonly. The keyboard navigation looked for that class on the first child of the cell, which never matched a stacked cell. As a result, Tab could land on a readonly sub-field holding a tabable element, e.g. the link of a readonly many2one. Skip a stacked cell when all of its sub-fields are readonly, and otherwise ignore the readonly ones when picking the element to focus. For consistency sake, isCellReadonly is renamed into isFieldReadonly in consequence to these changes. task-6564093
Fixed an issue in the HTML editor where dragging an image onto its current position could trigger an error in Chrome. This improves editing reliability by safely handling no-change drag-and-drop actions without disrupting the page content.
Original PR description
Steps to reproduce: - Insert an image as the last child of a paragraph. - Drag and drop it below or after itself. Description of the issue: - A traceback occurs. Cause: - When dropping an image below or after itself `document.caretPositionFromPoint()` computes a drop offset equal to the current node size. - The image is then removed from the DOM before being reinserted. Since it is the last child of its parent, removing it shrinks the parent, making the previously computed offset out of bounds. - Restoring the selection at that stale offset results in a traceback. Solution: - Treat dropping the image at its current position as a no-op and skip the remove/reinsert process, since it would not change the DOM. - Clamp the drop offset to the current node size before restoring the selection preventing out-of-bounds offsets. task-6435091 Forward-Port-Of: odoo/odoo#286613 Forward-Port-Of: odoo/odoo#280612
Users on tablets and other touch screens can now resize list view columns without the action being interrupted by page scrolling. This makes list views easier to adjust and use on touch-based devices.
Original PR description
Steps to reproduce ================== - Use a tablet (touch screen) - Open any list view - Try to resize a column by dragging the column header's right edge => The resize doesn't work properly: it gets interrupted an we can only move a few pixels at a time Cause of the issue ================== The resize handle relies on pointerdown/pointermove/pointerup to run and stop the drag, but nothing tells the browser to opt out of its native touch gestures. On a tablet, the drag can get hijacked as a page scroll, which fires pointercancel instead of pointerup. That event was not listened to, leaving the pointermove handler attached and the resize state stuck. Solution ======== - Set touch-action: none on the resize handle so a touch drag isn't interpreted as scrolling - Listen to pointercancel to properly stop the resize when the browser takes over the gesture anyway Forward-Port-Of: odoo/odoo#288046
Fixed an error that could occur when managers opened a new time off request using calendar-day counting before an employee was selected. This keeps the leave creation flow usable and avoids interruptions for HR teams configuring or managing sick leave.
Original PR description
BUG :
- choose a US company
- in sick leave timeoff type , make to count days as "calendar days"
- open management and try to create a leave -> traceback
REASON :
- when you open the timoff form view for the first time , the employee_id in empty this causes work_time_per_day_mapped to be empty, => work_time_per_day_mapped[leave.date_from, leave.date_to, include_public, calendar] this fails because there is no entry in the dict
FIX:
- add a safeguard at line 653 , to prevent the computations when the leave has no employees , in this case we should fall back to the else in line 739, this acts as way to prevent tracebacks, during calculation , because in the database itself you could never have a leave with no employee assigned to it.
task-6411996
Forward-Port-Of: odoo/odoo#279028Maintenance requests must now have both a start and end schedule, or neither, preventing planning screens from failing when schedule information is only partly filled in. This helps manufacturing teams open work order planning reliably even when maintenance data is being entered or edited.
Original PR description
#### Issue: Opening the MRP planning view could raise a traceback when a maintenance request had a `schedule_end` but no `schedule_date`. `TypeError: '<' not supported between instances of 'NoneType'…
#### Issue: Opening the MRP planning view could raise a traceback when a maintenance request had a `schedule_end` but no `schedule_date`. `TypeError: '<' not supported between instances of 'NoneType' and 'datetime.datetime'` #### Steps to reproduce: 1. Install maintenance, mrp, and mrp_maintenance. 2. Create a work center. 3. Create a maintenance request linked to that work center. 4. set a `Scheduled end` and Leave `Scheduled Date` empty. 5. Go to MRP > Planning > Work Orders. #### Cause: `maintenance.request` stores `schedule_end` as a writable field, but no constraint enforces that `schedule_date` and `schedule_end` must be set together. Later, `mrp_maintenance` in `_get_maintenances_intervals` fetches maintenance intervals for the gantt view without filtering null bounds. If a request has `(schedule_date, schedule_end)` = `(False, datetime)`, that interval is passed to `Intervals(...)`, which crashes when comparing `None` with a `datetime`. #### Fix: Add a constraint on `maintenance.request` to require `schedule_date` and `schedule_end` to either both be set or both be empty. Also filter out incomplete intervals in the MRP maintenance gantt query in this enterprise PR: https://github.com/odoo/enterprise/pull/117710 opw-6225772 enterprise PR: https://github.com/odoo/enterprise/pull/117710 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#276633 Forward-Port-Of: odoo/odoo#265208
Installing the Belgian payroll localization no longer fails when a company already has sick leave records. This prevents users from ending up with Payroll partly installed while the Belgian localization is missing.
Original PR description
Since the sickness relapse origin became a stored computed field, the ORM recomputes it on every existing leave when the module is installed. That happens while the models are reflected, i.e. before the module data files are loaded, so the sickness_relapse_period_days rule parameter does not exist yet and the compute raised:
UserError: No rule parameter with code "sickness_relapse_period_days"
was found for 2026-09-21
The installation aborted there, after hr_payroll had been committed: the user saw an "Invalid Operation" dialog and ended up with Payroll installed but the Belgian localization missing.
Look the parameter up with raise_if_not_found=False, as _compute_is_meal_voucher_valid already does, and keep whatever origin is stored on the leave when the relapse period is not known yet.This fixes an issue where AI service callbacks could fail when the system could not identify the right database from the request alone. By including the database name in callback setup, external service responses can reach the correct Odoo database more reliably.
Original PR description
IAP callbacks have no browser session and can return 404 when Odoo cannot select a single database from the hostname. Send webhook_dbname so IAP can route callbacks with the X-Odoo-Database header.
The MRP planning view now ignores maintenance entries with only one scheduled date filled in, preventing an error that could block users from opening the plan. This keeps production planning accessible while related validation ensures future maintenance requests use complete scheduling information.
Original PR description
#### Issue: Opening the MRP planning view could raise a traceback when a maintenance request had a ``Scheduled End`` but no ``Scheduled Date``. ```TypeError: '<' not supported between instances of 'NoneType' and 'datetime.datetime'``` #### Cause: In `_get_maintenances_intervals`, `mrp_maintenance` loaded maintenance intervals for gantt unavailability without filtering out incomplete rows. If an interval like False, datetime reached Intervals, it crashed when comparing None with a datetime. #### Fix: Filter out incomplete maintenance intervals in the gantt query. Also added a constraint on `maintenance.request` to require `schedule_date` and `schedule_end` to either both be set or both be empty in this community PR: https://github.com/odoo/odoo/pull/265208 opw-6225772 Forward-Port-Of: odoo/enterprise#124516 Forward-Port-Of: odoo/enterprise#117710
The Phone app no longer lets users start creating call flows from phone number destination selectors, which previously opened an unusable blank setup screen. Users can still create call flows from the dedicated Call Flows configuration area, ensuring setup happens in the correct place.
Original PR description
Steps to reproduce: 1. Install Phone on a fresh database. 2. Buy a phone number. 3. Open the phone number form. 4. Set the destination type to "Call Flow". 5. Open the destination selector when no call flow exists. 6. Click "Create". Before this commit, an unusable empty form opened because call flows are intended to be configured through their dedicated editor. Disable call flow creation from PBX destination selectors. Call flows can still be created from Phone > Configuration > Call Flows. task-6574014
Odoo now handles requests with overly long web addresses more gracefully, even when the server rejects them before reading request details. This avoids an internal error during the rejection process and helps keep the system response stable.
Original PR description
- When the request URI is too long, the HTTP server rejects the request before parsing the headers. As a result, `self.headers` is not available when the WebSocket compatibility code in `send_header()` and `end_headers()` is executed. - Access `self.headers` safely to avoid an AttributeError while handling the 414 response. **opw-6501275** --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#286806 Forward-Port-Of: odoo/odoo#285870
The commission reporting logic now uses simpler row-based identifiers instead of longer string-based IDs. This helps keep the report data cleaner and avoids unnecessary complexity without changing the business meaning of the commission reports.
Original PR description
Unlike achievement report ids, commission report ids do not need to identify source records. ROW_NUMBER() is enough to identify the grouped rows and avoids using string ids. Forward-Port-Of: odoo/enterprise#127018 Forward-Port-Of: odoo/enterprise#126851
A website shop performance test was updated to include extra checks triggered by out-of-stock product labels. This keeps automated testing accurate and helps prevent false failures while maintaining confidence in shop page performance.
Original PR description
The "Out of stock" ribbon auto-assignment resolves the first available combination of the multi-variant test product to know whether all its variants are out of stock, costing 3 extra `product_template_attribute_value` queries that were not accounted for in `TestWebsiteSalePerformanceNoPricelist`. Breaking PR: https://github.com/odoo/odoo/pull/254869
This fixes an issue that could prevent users from opening or reading Italian electronic invoices due to an access rights error. Invoice document type information is now read safely in the background, improving reliability without changing user workflows.
Original PR description
Field l10n_it_available_document_type_ids on account.move is computed and not stored, so it's not in compute_sudo by default This commit adds the compute_sudo to the field to ensure there's no access error when reading the invoice runbot-947080
This update fixes errors that could appear when users opened the Miscellaneous tab or clicked the popover in the Bill of Materials form. The change ensures the popover is only shown when data is available and aligns the manufacturing customization with the updated button-based interface.
Original PR description
This commit fixes some issues, following changes done in [^1]: 1. The template override done in MRP targeted a `<a>` element which was replaced by a `<button>` element; 2. The props for the MRP override of this widget were added but most of them are optional (in fact, the only one which is required was the only one marked as optional, it is the opposite); 3. The widget were rendered no matter what, even when `json_popover` was empty. Issue 1 caused a traceback when trying to display the "Miscellaneous" tab in the BoM form view and issues 2 and 3 caused another traceback when clicking on the widget from this view. [^1]: https://github.com/odoo/odoo/pull/287605
OSS sales in the Spanish VAT report are now assigned to the correct Modelo 303 reporting box, casilla 123 instead of casilla 124. This helps ensure reported VAT amounts appear in the legally expected place and reduces the risk of incorrect tax filings.
Original PR description
OSS sales were being mapped to mod_303_casilla_124_balance where it should be mapped to mod_303_casilla_123_balance. These amounts must be reported values in casilla 123. This commit updates es_assec, es_common, es_full and es_pymes tax templates from 124 to 123 and updates test_country_tag_from_spain. task-6360387 I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#284984
This fix prevents the Pay on Site option from being automatically re-enabled when the Website Sale Collect app is upgraded. Merchants' payment settings are now preserved, helping avoid unpaid checkout orders being offered unintentionally.
Original PR description
Steps to reproduce: =================== 1. Go to the payment providers and set "Pay on Site" to disabled. 2. Go to Apps, clear the filter, look up "website_sale_collect" and upgrade it. This also…
Steps to reproduce:
===================
1. Go to the payment providers and set "Pay on Site" to disabled.
2. Go to Apps, clear the filter, look up "website_sale_collect" and upgrade it. This also happens on its own, as upgrading any custom module that depends on it upgrades it too.
3. Go back to the payment providers.
=> "Pay on Site" is enabled again, and published as well from 19.0 on. Customers are offered it at checkout and place orders that are never paid, without the merchant ever enabling anything.
Root cause:
===========
`data/payment_provider_data.xml` is loaded in update mode because it carries no `noupdate`, and it hardcodes the state of the provider:
<field name="state">enabled</field>
So every upgrade of the module writes that value back over whatever the merchant configured. Every other provider ships its data with `noupdate="1"` and leaves the state alone, this module is the exception.
The file has been loaded this way since the module was added:
- [1] created the module with an updatable provider record.
Fix:
====
Load the file with `noupdate="1"`. The record is still created, enabled, when the module is installed, it is simply not written again on later upgrades. The flag is read from the file rather than from the `ir.model.data` row, so databases where the provider already exists are covered on their next upgrade, no data migration needed.
[1]: 087c48c4ed2e
opw-6528110
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#286913This fix prevents an error in Manufacturing planning when users switch from sample data to real work orders by changing filters. It makes the transition smoother and avoids disruptive tracebacks in the work orders list view.
Original PR description
Go to Manufacturing > Planning > Workorders > Planning > list view. Sample data are displayed. Remove a filter such that real records match the domain. Tracebacks are displayed because we call…
Go to Manufacturing > Planning > Workorders > Planning > list view. Sample data are displayed. Remove a filter such that real records match the domain. Tracebacks are displayed because we call `get_duration` on records that don't exist. The `useRecordObserver` of MrpTimerField subscribes the callback to the `useSampleModel` flag and to the `record`. When the filter is removed, the model is reloaded and, atomically, both the flag and the root and updated on the model. As the flag is toggled, the callback is executed. However, the props of the MrpTimerField aren't updated yet, so the `record` used in the callback is still the old, sample, one. One could argue that there's a design flaw in the model as at some point, a `record` could contain sample data while it's model states that we're not in sample mode (`record.model.useSampleModel` is false). That's true and that's something we'll change in the future, but in master. We fix this issue with an easier patch, which consists in accessing the `useSampleModel` flag with `untrack`, i.e. to not subscribe to that flag's changes, as in that case, the component will be destroyed anyway. 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#288015
The online shop wishlist heart button now keeps a consistent square size in Safari. This prevents visual misalignment in product listings, giving shoppers a cleaner and more consistent browsing experience.
Original PR description
The wishlist button on the shop page is misaligned in Safari Steps to reproduce: (in Safari) 1. Install eCommerce 2. Go to the shop 3. The wishlist button (heart icon in the top right corner of each product) is misaligned Issue: The wishlist button (`.o_add_wishlist`) is positioned with `position: absolute` with only top and right offsets set (through the `o-position-absolute` mixin), leaving its width and height on `auto`. https://github.com/odoo/odoo/blob/c4de5361fb207916175332dcf6815c0814ecf09c/addons/website_sale_wishlist/static/src/scss/website_sale_wishlist.options.scss#L62-L65 In other browsers, the button resolves to a 38 x 38px square box but in Safari, it is not a square which misaligns it in the product grid. Solution: Force width and height on `.o_add_wishlist`, so the button resolves to the same box size in every browser. opw-6456552 Forward-Port-Of: odoo/odoo#287940 Forward-Port-Of: odoo/odoo#281935
Point of Sale now correctly includes product variant extra charges when a discount pricelist is based on another pricelist. This prevents undercharging at checkout and helps ensure displayed and charged prices match the intended product setup.
Original PR description
## Steps to reproduce: - Create a product, with never variant, the variant has an extra price of 100 - Make Pricelist 1, just leave it as default - Make Pricelist 2, make it a discount, based on Pricelist 1, for all products - Go to the PoS, click on the created product - Change the pricelist to Pricelist 2 -> the price does not take the extra price into account ## Why the fix: When we have a pricelist based on another pricelist, we recursively calculate the price on the base pricelist. Before this commit, in the recursive call, we gave 0 as the extra price. We now give the extra price in the recursive function call. opw-6500086 Forward-Port-Of: odoo/odoo#286608 Forward-Port-Of: odoo/odoo#285371
Fixed an issue where selling and invoicing a shared product in Point of Sale could fail when vendor or replenishment data from another company was cached. This helps multi-company users complete POS sales reliably without access errors caused by records from another company.
Original PR description
**Steps to reproduce:** - Install PoS and Purchase - Make 2 companies, A and B - On product "Office Lamp" that is accessed by both companies, put Partner A in the vendor tab for company B - Company A…
**Steps to reproduce:**
- Install PoS and Purchase
- Make 2 companies, A and B
- On product "Office Lamp" that is accessed by both companies, put Partner A in the vendor tab for company B
- Company A should have a Partner A and Partner B in this tab
- In the stock, set a replenishment for company A, with Partner A on Office Lamp
- Go to company B and open the PoS
- Try to buy Office Lamp while requesting an invoice
- An access error appears
**Why the fix:**
When requesting an invoice in the PoS, we try to create the stock picking. Doing so will trigger the replenishment rules linked to the product to be recomputed.
Those are executed when we **flush_all()**, processing Company A's replenishments as sudo(), meaning all of Company A's **seller_id** are fetched and cached. This means the product's **seller_ids** now contains Company A's **seller_id**, even though we are currently in Company B.
While trying to get the product's code, we iterate over **product.seller_ids**, but we do not have access to every record in that product.
https://github.com/odoo/odoo/blob/b8e5291d103d9f43bd8db6d2dfe708076a57ea37/addons/product/models/product_product.py#L337-L343
As we don't have access to those, we get an access error when we stumble upon it.
To avoid those errors, we now filter the sellers to only have the ones compatible with our current Company in the given product we are currently buying.
Another solution would be to do **product.invalidate_recordset(['seller_ids'])** before looping over it, but feels more like a band-aid than the current fix IMO.
We could also write **self.lines.product_id.mapped('code')** in **_create_order_picking(self)** to have the solution be in PoS directly, but the error might arise from somewhere else at some point, and this just hides the issue by adding the code to the cache so that we don't have to fetch it again later.
opw-6308182
Forward-Port-Of: odoo/odoo#286656
Forward-Port-Of: odoo/odoo#275354The Navarra SII tax agency service link has been updated to the current endpoint after the previous one stopped working. This helps Spanish electronic VAT reporting continue to connect correctly for companies using the Navarra tax service.
Original PR description
The WSDL URL used for the Navarra tax agency SII web service was no longer working. It has been replaced with the updated endpoint 'ssii_1_1'. task-6457647 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#285544 Forward-Port-Of: odoo/odoo#285049
Check templates now handle cases where an account filter finds no matching accounts without causing an error. This prevents interruptions when running accounting reports with restrictive or unmatched template rules.
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.
Belgian payroll users can now open the Payroll Time Offs Gantt view for employees on flexible working schedules without hitting an error. The change removes duplicate payroll calendar logic now handled centrally, improving reliability without changing user workflows.
Original PR description
Steps to reproduce: - On a Belgian company, set an employee's working schedule to Flexible Hours (no calendar, hours/week set). - Open Payroll > Time Offs. Current behavior: AttributeError: 'hr.version' object has no attribute 'l10n_be_reference_calendar_id'. Expected behavior: The Gantt view loads normally task-6569832
When a chart of accounts is installed for an existing company, required tax returns are now created automatically instead of requiring a manual refresh. The update also ensures archived returns stay hidden from reporting summaries, reducing confusion for users reviewing return status.
Original PR description
1) Create a company without any country
2) Go to the settings, install a CoA on it that uses returns (like the Belgian one) 3) Go to the returns of that company
====> Nothing has been created, you need to click "Refresh" manually to get them.
This is wrong, returns should be created by default in this case.The time off Gantt quick-add menu now follows the configured ordering of leave types instead of showing options unpredictably. This keeps common choices like paid or unpaid time off visible ahead of less frequently used options, making payroll time off entry more consistent for users.
Original PR description
The quick-add widget on the time off gantt view (in payroll) picked its displayed presets somewhat randomly. This let rarely-used types (e.g. the two work accident allocations) push more common ones (e.g. paid/unpaid time off) out of visibility. Use the work entry type's `sequence` as a sort key (use it as a tie-breaker for allocated types, and as the sole sort key for non-allocated types), so the widget reflects the configured ordering of time off types. task-6515958
The Belgian payroll working schedule change wizard now correctly carries over calculated time-off allocation hours when a change takes effect immediately. This prevents employees from receiving allocations with zero hours, improving accuracy in payroll and leave records.
Original PR description
to reproduce: - Open the "Working Schedule Change" wizard on a BE employee's contract and confirm it for a change that applies immediately (not scheduled for a future date). - Open the resulting time off allocation: its hours are 0. Issue: `time_off_allocation` and `time_off_allocation_hours` are computed together by `_compute_time_off_allocation`, but only `time_off_allocation` is user-editable (`readonly=False`). On save, the ORM protects a whole compute group from recomputation as soon as one of its fields is given explicitly, so `time_off_allocation_hours` is never sent nor recomputed and stays at its 0 default. The wizard then writes `number_of_hours: 0` on the allocation. Fix: Make `time_off_allocation_hours` `readonly=False` too, and add it (invisible) to the view, so its last computed value is actually saved alongside its sibling field. Task-6571882
Belgian payroll demo employees now have the correct work locations set, preventing setup issues in demo payroll scenarios. The warning for missing work locations was also adjusted to avoid access errors when multiple companies are involved.
Original PR description
Set work locations for Belgian demo employees and avoid multi-company access errors in the work location warning. task: 6569897
Payroll configuration now also applies to the India corporate chart of accounts template. This prevents setup errors and helps companies using that template run payroll accounting correctly.
Original PR description
A new chart template `in_sch_3` was added for corporate entities, so payroll also needs to be configured for this template. This commit configures payroll for the `in_sch_3` chart template as well. runbot error: https://runbot.odoo.com/odoo/error/947113
Mexican payroll now checks an employee's daily wage when applying minimum wage protections, preventing incorrect social security deductions when minimum wage workers receive extra pay. It also rounds schedule days and fixes subsidy eligibility so unpaid absences do not wrongly disqualify employees from benefits.
Original PR description
According to LSS Art. 36, minimum wage workers are exempt from IMSS deductions. Previously, the system evaluated the period's total gross wage instead of the daily wage, which caused incorrect…
According to LSS Art. 36, minimum wage workers are exempt from IMSS deductions. Previously, the system evaluated the period's total gross wage instead of the daily wage, which caused incorrect withholdings when a minimum wage employee received extra pay (like commissions). We now evaluate the `l10n_mx_daily_salary` directly to protect minimum wage workers while ensuring correct deductions for higher earners with unpaid leaves. Since calculations rely on `schedule_days` retrieved from the schedule table, users commonly adjust these values (e.g., from 15 to 15.2, or 30 to 30.4). To prevent discrepancies caused by this practice, we now round the `schedule_days`. Finally, this commit fixes the employment subsidy eligibility threshold. Previously, the limit was incorrectly reduced by unpaid absences. This caused a double-counting effect (since absences already lower the actual gross wage) and wrongly disqualified employees. The subsidy limit is now based strictly on the full payroll schedule length, while the ISR minimum wage exemption correctly continues to consider actual worked days. target: 19.0 task-6370959 Forward-Port-Of: odoo/enterprise#130706 Forward-Port-Of: odoo/enterprise#125061
The demo payroll data now sets the time off allocation to match the year of the demo leave. This prevents installation errors in January or February and keeps Belgian payroll demo data usable for testing and demonstrations.
Original PR description
The "Long weekend" demo time off is placed two months in the past, while its allocation was only valid for the current calendar year. Installing demo data in January or February left the leave uncovered, raising "You do not have any allocation for this time type". Start the allocation on January 1st of the leave's own year instead. related-taskid-6519088 runbot-error-946849
The Indian salary configurator now shows only one Gross salary line and keeps the Monthly Equivalent total accurate. This prevents duplicate salary information and gives HR teams and employees a clearer, more reliable compensation view.
Original PR description
Issue: - The salary configurator displays two 'Gross' lines for Indian payroll structures. - The generic salary resume uses the `wage` code, while the Indian payroll defines a structure-specific…
Issue: - The salary configurator displays two 'Gross' lines for Indian payroll structures. - The generic salary resume uses the `wage` code, while the Indian payroll defines a structure-specific 'Gross' resume using the 'GROSS' payslip rule. Both resumes were included in the salary configurator, resulting in duplicate 'Gross' entries. - The 'Monthly Equivalent' total shown in the configurator was also affected, as it included the generic 'wage' amount on top of the actual payslip values. Cause: - The generic 'wage' resume was still included for the Indian payroll structure alongside the India-specific 'GROSS' payslip resume. - The generic 'wage' resume also counts towards the 'Monthly Equivalent' total shown in the configurator, so removing only the duplicate line left this total incorrect. Fix: - Exclude the generic 'wage' resume from the salary configurator results when the selected structure is the Indian employee payroll structure. - This keeps the India-specific 'Gross' resume based on the 'GROSS' payslip rule while preventing the generic contract wage from being displayed as a duplicate. - Subtract the removed 'wage' amount from the 'Monthly Equivalent' total so it stays correct after the duplicate line is removed. task-6511413 Forward-Port-Of: odoo/enterprise#129518
Fixed an issue that could prevent users from creating a new product from the purchase catalog when a vendor was prefilled. This keeps the purchasing workflow running smoothly and avoids an unexpected error screen in the product creation form.
Original PR description
Opening a product creation form from the purchase catalog raises a traceback. ### Steps to Reproduce 1. Go to **Purchase > Orders** (or Requests for Quotation). 2. Open any order with a **Vendor**…
Opening a product creation form from the purchase catalog raises a
traceback.
### Steps to Reproduce
1. Go to **Purchase > Orders** (or Requests for Quotation).
2. Open any order with a **Vendor** selected.
3. Click **Catalog** on the order lines table.
4. Search for any non-existent product to trigger the empty state.
5. Click **Create a product** from the no content helper.
### Traceback
```pytb
Traceback (most recent call last):
File "odoo/addons/web/models/models.py", line 2232, in onchange
defaults = self.default_get(missing_names)
File "odoo/orm/models.py", line 1401, in default_get
defaults[fname] = field.convert_to_write(value, self)
File "odoo/orm/fields_relational.py", line 759, in convert_to_write
if record != origin:
File "odoo/orm/models.py", line 6117, in __eq__
return self._name == other._name and set(self._ids) == set(other._ids)
TypeError: cannot use 'dict' as a set element (unhashable type: 'dict')
```
### Issue
The purchase catalog action helper (PR odoo/odoo#164131) sets the
current vendor as default on the new product using:
```python
context = {'default_seller_ids': [{'partner_id': vendor_id}]}
```
In commit 188c81575130 (PR odoo/odoo#272499), a check was added to
`convert_to_cache()` to optimize lists of record ids (`[1, 2, 3]`):
```python
elif isinstance(value, list) and value and not isinstance(value[0], (tuple, list)):
```
The PR assumed all relational commands are tuples or lists
(like `(0, 0, vals)` or `[0, 0, vals]`), and that anything else must
be an id. However, x2many command values can also be
dictionaries (`[{'partner_id': vendor_id}]`), which the method
explicitly supports further down (`elif isinstance(command, dict):`).
Because a dictionary is neither a tuple nor a list, the check mistakenly
treated `{'partner_id': vendor_id}` as a record id and placed it inside
`record._ids`. When the ORM subsequently compares records
(`record != origin`), it attempts to create a `set()` of the ids and
crashes because dictionaries cannot be hashed.
### Fix
Exclude `dict` from the check:
```python
elif isinstance(value, list) and value and not isinstance(value[0], (tuple, list, dict)):
```
This ensures lists of dictionaries fall through to `elif isinstance(command, dict):`
and are properly instantiated as new in-memory records.
Related: odoo/odoo#272499
Related: odoo/odoo#164131The expense settings now prevent users from selecting payment methods that do not match the relevant company configuration. This reduces setup errors and helps keep expense processing data accurate.
Original PR description
Add domain to company_expense_allowed_payment_method_line_ids field to avoid selecting inconsistent data @Tecnativa TT64416 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#287131
Fixes an issue where editing purchase or invoice line descriptions could accidentally add the internal product name before vendor-specific or translated product details. This keeps printed orders and invoices cleaner and avoids confusing duplicate product names for vendors and customers.
Original PR description
\* = point_of_sale, purchase_requisition **Steps to reproduce:** 1. Install purchase app 2. Create a product, and in the purchase tab set a vendor and specify product name/code (e.g., "VENDOR-CODE")…
\* = point_of_sale, purchase_requisition **Steps to reproduce:** 1. Install purchase app 2. Create a product, and in the purchase tab set a vendor and specify product name/code (e.g., "VENDOR-CODE") 3. Create a purchase order, select that product and vendor 4. The PO line shows: "VENDOR-CODE\n[Product Description]" 5. Edit the description in the line and print the invoice **Issue:** Two related issues with product name/description handling in invoice and purchase order lines: 1. **Vendor Product Name Issue:** When a purchase line has a vendor product name/code, editing the description causes the original internal product name to be prepended, resulting in: `[Product Name]\n[Vendor Code]\n[Description]` 2. **Translation Issue:** When a customer has a different language, editing the product description causes the original product name to be prepended to the invoice line: `[Original Name]\n[Translated Name]\n[Translated Description] [1] **Why this happens:** The widget (`ProductLabelSectionAndNoteField`) was using the `productName` (untranslated/base name) to detect what to strip from the label, but in the two scenarios this didn't match: - **Vendor flow:** `productName` = "Product A" but the label contains vendor code "VENDOR-CODE" - **Translation flow:** `productName` = "Product A" (English) but the label contains "Produit A" (French) When neither matched, the truncation logic wouldn't work, and `parseLabel()` would later prepend the original product name blindly. **Expected behaviour:** - Original product name should not be prepended in both scenarios **The fix:** 1. Added computed field to `pos.order.line` since it uses the same widget and needs to have the field dependency [2] 2. Added computed field to `purchase.requisition.line` since it uses the same widget and needs to have the field dependency 3. Modified `ProductLabelSectionAndNoteField.parseLabel()` to: - Only concatenate product name when `translatedProductName == productName` (indicating same language/no vendor override) since it would have been truncated by `get label()` - Otherwise, return the value as-is (no concatenation needed since `get label()` didn't truncate) This handles the flows: - **Vendor flow:** `translated_product_name` contains vendor name/code (≠ productName) → no concatenation - **Translation flow:** `translated_product_name` differs from `productName` → no concatenation - **Same language/no vendor:** `translated_product_name` == `productName` → concatenates → maintains existing behavior **Related:** - [1] - #248401 - [2] - #254158 opw-6391501
This fixes a problem that could block users when setting a partner's country to Saudi Arabia after entering a Company ID. The change keeps partner record updates working smoothly and avoids an unexpected error in Saudi Arabia localization workflows.
Original PR description
Currently, an error occurs when the user sets the partner's country to Saudi Arabia. **Steps to Reproduce:** - Install the `l10n_sa` module with demo data. - Switch to `My Saudi Arabia Company`. -…
Currently, an error occurs when the user sets the partner's country to Saudi Arabia. **Steps to Reproduce:** - Install the `l10n_sa` module with demo data. - Switch to `My Saudi Arabia Company`. - Create a `partner` and click the `+` icon next to the VAT Number. - Select `Company ID`, set any `value`. - Set the partner's country to `Saudi Arabia`. `KeyError: 'OTHER'` After the [recent commit], OTHER is removed from vals [1] when at least one other EN identifier, excluding OTHER, is available. If a user selects OTHER (Company ID) as an additional identifier and then changes the partner's country to Saudi Arabia, the available additional identifier metadata is recomputed. With the [second commit], it checks whether the stored additional identifier is applicable to Saudi Arabia by looking up its metadata [2]. However, since OTHER was removed from the available additional identifier metadata because another EN identifier is available, directly accessing the metadata for OTHER raises a KeyError. This commit ensures that the additional identifier is safely accessed in the metadata. [recent commit]: https://github.com/odoo/odoo/commit/9087c2ddc1de3e9ef9431188a9b6dddbd6b58552 [second commit]: https://github.com/odoo/odoo/commit/fddf7653ba898f5db9d97ae3cd9f885c6c5c658a [1]- https://github.com/odoo/odoo/blob/1d50ff71a1edf2c4226cb2f68cf3bbe4e39485f6/odoo/addons/base/models/res_partner.py#L1423-L1425 [2]- https://github.com/odoo/odoo/blob/1d50ff71a1edf2c4226cb2f68cf3bbe4e39485f6/addons/l10n_sa/models/res_partner.py#L17-L18 sentry-7717445803 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#287384
Point of Sale sessions now handle outdated cached data from older installations or removed modules without failing. This prevents users from being blocked when opening POS after model changes or module uninstallations, avoiding the need for manual cache reloads.
Original PR description
In PR-#[225341](https://github.com/odoo/odoo/pull/225341) we started passing all the models which are cached on the front end directly to the back end, but if the database existed before and the front end cached models which no longer exist, either because the model name changes (such as pos.product.template.snooze -> pos.snooze), or because a module was uninstalled (removing pos_restaurant_appointment), the front end would ask the back end for models which no longer exist, and that would error. When we do the reload data, all the local cache would be deleted and then we could launch the POS. To fix it, now the back end will check whether the model exists before trying to filter on it, and just ignore it if it doesn't exist Task-[6562705](https://www.odoo.com/odoo/project/1737/tasks/6562705) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The point of sale now ignores old cached references to features or models that no longer exist, instead of failing during startup. This helps businesses continue loading POS sessions after upgrades, renames, or module removals without needing a manual cache reset.
Original PR description
In PR-#[225341](https://github.com/odoo/odoo/pull/225341) we started passing all the models which are cached on the front end directly to the back end, but if the database existed before and the front end cached models which no longer exist, either because the model name changes (such as pos.product.template.snooze -> pos.snooze), or because a module was uninstalled (removing pos_restaurant_appointment), the front end would ask the back end for models which no longer exist, and that would error. When we do the reload data, all the local cache would be deleted and then we could launch the POS. To fix it, now the back end will check whether the model exists before trying to filter on it, and just ignore it if it doesn't exist Task-[6562705](https://www.odoo.com/odoo/project/1737/tasks/6562705) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix removes an unnecessary language switch in a website editing test and adds a check that the editor is ready before continuing. It helps prevent intermittent test failures, improving confidence in website editing stability without changing user-facing behavior.
Original PR description
In [this commit][1] some steps were added to resolve non-deterministic errors. Just before `...clickOnEditAndWaitEditModeInTranslatedPage(),` three steps were added that switch the language back to…
In [this commit][1] some steps were added to resolve non-deterministic errors. Just before `...clickOnEditAndWaitEditModeInTranslatedPage(),` three steps were added that switch the language back to parseltongue. This is most likely since the function call implies we are on a translated page. The choice for this function was most likely due to a race condition. As the language was switched to English recently, the edit button might not have time to have switched. To recreate the race condition, remove the step added in this commit but leave the rest of the changes. Run the tour and it will hang up on the first step of `...clickOnEditAndWaitEditMode()` because the Edit button is still in "translation" mode. This commit removes the redundant language change and adds an extra step to check the Edit button is in the correct "mode" before continuing. [1]: https://github.com/odoo/odoo/commit/7f7cc9617381b1a2f61af0875e7b60ab0b7ab3a0 task-5951393 Forward-Port-Of: odoo/odoo#288035 Forward-Port-Of: odoo/odoo#286764
Fixes an error that occurred when users applied an inventory date in the Stock reporting view while using Arabic. The system now saves the selected date in a standard format, preventing crashes and allowing stock reports to load correctly across languages.
Original PR description
Currently, an error occurs when applying the inventory date in the Stock reporting view. Steps to Reproduce: - Install the `stock` module with demo data. - Go to `Settings` > `Languages`, add…
Currently, an error occurs when applying the inventory date in the Stock reporting view. Steps to Reproduce: - Install the `stock` module with demo data. - Go to `Settings` > `Languages`, add `Arabic`, and switch to it. - Go to `Inventory` > `Reporting` > `Stock`. - In the `left-side panel`, enter an `Inventory at Date` and click `Apply`. `ValueError: time data '٢٠٢٦-٠٩-٠٩ ٠٥:١٨:٠٠' does not match format '%Y-%m-%d %H:%M:%S'` After the [recent commit] that added a date picker to the Stock report search panel, when user enters a date using Arabic numerals, the text is displayed from right to left [1]. This date is then added to the context [2]. When computing the quantities, the date value from the context [3] is passed to it, where it is converted to a datetime [4]. However, the conversion expects the date to use Latin numerals. Since the date is in Arabic numerals, this raises the error. This commit ensures that the date is serialized using serializeDateTime [5], which also uses the UTC timezone and the Latin numbering system (latn) as expected by the system. [recent commit]: https://github.com/odoo/odoo/commit/52bfa5b9bebbcb4f8042daa183edc39865036605 [1]- https://github.com/odoo/odoo/blob/7ef98548726f36856d78c745679b14b0165803ba/addons/stock/static/src/views/search/stock_report_search_panel.js#L39-L40 [2]: https://github.com/odoo/odoo/blob/7ef98548726f36856d78c745679b14b0165803ba/addons/stock/static/src/views/search/stock_report_search_model.js#L52-L53 [3]: https://github.com/odoo/odoo/blob/7ef98548726f36856d78c745679b14b0165803ba/addons/stock/models/product.py#L146 [4]- https://github.com/odoo/odoo/blob/7ef98548726f36856d78c745679b14b0165803ba/addons/stock/models/product.py#L162 [5]: https://github.com/odoo/odoo/blob/7ef98548726f36856d78c745679b14b0165803ba/addons/web/static/src/core/l10n/dates.js#L552-L560 sentry-7629069474 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#287181
Payment providers now appear with installed options before uninstalled ones again. This makes payment setup clearer for users and restores the expected ordering after a recent platform ordering change.
Original PR description
Currently payment providers are displayed with uninstalled providers first, this should not be the case This behavior is caused by a recent change to ordering of selection fields with this pr: https://github.com/odoo/odoo/pull/280940 Previously, selection fields were ordered by the alphabetical value of their underlying text key. Now these are ordered by the sequence in which the options are written in the field declaration. Since `ir.module`'s state field, which is related to the `module_state` field that is used for ordering payment providers is declared in this way: https://github.com/odoo/odoo/blob/e94da89ffd32487233992385badd9f5fa2ab77ec/odoo/addons/base/models/ir_module.py#L143-L150 sorting alphabetically puts 'installed' before 'uninstalled' however sorting by declaration order sorts the other way around this commit updates payment_provider's `_order` value to match that change. opw-6511304
Odoo now correctly carries the payment reference from imported CII XML invoices into the generated vendor bill. This helps accounting teams avoid missing payment information and reduces manual corrections after invoice import.
Original PR description
### Issue before this commit: When importing a CII XML invoice containing a PaymentReference, the value is not transferred to the generated vendor bill in Odoo. ### Steps to reproduce the issue: 1. Download Accounting 2. Try to import the invoice in the ticket 3. See that in the tab other info the payment reference is not imported ### Cause of the issue: During a previous refactoring (ffbdf29a816d0ff4136488d26b55b9707fc37fc6), the helper function responsible for extracting the payment reference during the import process was omitted. ### Reason to introduce the fix: Add the missing extraction logic to ensure the payment reference is correctly retrieved from the XML and assigned to the Odoo invoice. opw-6530627 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#287216
Opening the Miscellaneous tab in a Bill of Materials could show an error because the screen was looking for an outdated page element. This fix updates the view so the tab opens normally, preventing disruption for manufacturing users.
Original PR description
In this [PR](https://github.com/odoo/odoo/pull/287605), the referenced element was changed from `<a>` to `<button>`. However, the inherited view was still targeting the `<a>` element. Due to this change, the inherited view no longer targets the correct element, resulting in a traceback when accessing the Miscellaneous tab in the Bill of Materials. This PR updates the inherited view to target the appropriate `<button>` element. TaskId: 6573251
This fix prevents Hong Kong payroll payment reports from crashing when an employee has no ID or passport number. It also adds clearer validation for required AutoPay information so payroll and batch payment files are not generated with missing bank-required data.
Original PR description
When both identification_id and passport_id are empty (False), re.sub() receives a bool and raises: TypeError: expected string or bytes-like object, got 'bool'. Fall back to an empty string and normalize the passport fallback the same way as the HKID. The HSBC/Hang Seng (l10n_hk_mri) AutoPay file format requires a Payment Set Code, a First Party Reference and a per-payment identifier (HKID or passport number); without them the file was silently generated with missing data. Validate these in l10n_hk.bank.format._validate() so the check is shared by both consumers of the format: the payroll payment report and the generic batch payment export. Add the matching Party Reference check to l10n_hk_payment_autopay's journal validation so batch payments get a proper RedirectWarning to the journal instead of a bare error. Task-6536846 Forward-Port-Of: odoo/enterprise#130894
This fix restores binary field exports to use the expected base64 format, matching earlier behavior. It helps prevent compatibility issues for businesses that export files or data from Odoo and rely on those exports being readable by existing tools or integrations.
Original PR description
Export base64 data like we used to do. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix ensures that changes made in forms with related line items keep all needed background data in sync. It prevents inconsistent values from appearing after an automatic form update, improving reliability for users working with complex records.
Original PR description
If we copy only the fields that are in the spec, we miss fields that are used during computes in the trigger tree. The example is `test_onchange_one2many_with_domain_on_related_field` that may miss the m2o field in test_orm.emailmessage._inherits. Following that change, we see that the value sent in the onchange did not invalidate values depending on it. The data was inconsistent. Actually, for new records, a call to `update` does all invalidations we need. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Fixed an inventory issue where products packed separately could appear under the same package on the final delivery when delivery steps were merged. This helps warehouse teams keep package tracking accurate and prevents confusion during shipping.
Original PR description
Steps to reproduce --- 1. Set the warehouse to deliver in 3 steps. 2. Create a delivery pick not tied to a procurement group (not from a sale order) with a consumable product, and validate it. 3. On…
Steps to reproduce --- 1. Set the warehouse to deliver in 3 steps. 2. Create a delivery pick not tied to a procurement group (not from a sale order) with a consumable product, and validate it. 3. On the pack transfer, put the goods in a package and validate. 4. Duplicate the pick, validate it, put its goods in a second package on the pack transfer, and validate. 5. Open the final delivery: both lines sit in the same package instead of one line per package. Issue --- The two picks share no procurement group, so their delivery moves merge onto a single move keyed by partner. Validating the second pack tops up that already partially reserved move: for a consumable, `_action_assign` builds its lines from `_get_available_move_lines`, which reports the availability of every upstream package without discounting what the move already reserved. https://github.com/odoo/odoo/blob/05af9e6877fd0f044bb46c983fe7300eb1db9307/addons/stock/models/stock_move.py#L1907-L1909 The package already reserved on the first line is therefore offered again and reused, collapsing both lines onto one package. The reserved-product branch below already subtracts the move's own reservation before allocating; doing the same here leaves each package on its own line. opw-6498532 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#287935 Forward-Port-Of: odoo/odoo#284956
Quantity-based delivery pricing rules now display cleaner names by omitting an invalid placeholder where no unit applies. This prevents confusing rule labels for users configuring shipping methods based on rules.
Original PR description
Quantity-based delivery pricing rules have no unit. The computed name formatted the empty value directly, displaying `False` in the rule name. Use an empty string when the computed variable unit is not defined. Steps to reproduce: 1. Open a delivery method configured as Based on Rules. 2. Add a pricing rule using Quantity as its condition. 3. Observe `False` after the quantity in the generated rule name. Before this commit: Quantity-based pricing rules displayed `False` as their unit. After this commit: Quantity-based pricing rules no longer display an invalid unit. 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#287873
This fix ensures Odoo regularly checks and closes unused database connections, even when the system is busy. It helps prevent idle connections from staying open longer than intended, improving resource management and reducing the risk of connection pool pressure.
Original PR description
Every `borrow()` used to push `_check_free_at` forward, so a busy pool never ran the periodic full idle scan. Oldest idle connections then stayed open until the pool filled. Reset the timer only when that full scan actually runs. I think it is the reason that we have to REV the code here https://github.com/odoo/odoo/pull/287008 for non-blocking connection pool Forward-Port-Of: odoo/odoo#288067
Orders shared between trusted Point of Sale configurations could keep the wrong session information when the restaurant app was installed, causing valid payments to be rejected. This fix preserves the synchronization data so shared orders use the correct session and can be paid with the appropriate payment methods.
Original PR description
**TL;DR** - in certain cases, Session is not updated on order shared on trusted pos Steps to reproduce: - Install pos_restaurant with demo data. - Have two configs: Cloth Shop and Furniture Shop. -…
**TL;DR** - in certain cases, Session is not updated on order shared on trusted pos Steps to reproduce: - Install pos_restaurant with demo data. - Have two configs: Cloth Shop and Furniture Shop. - Ensure both configs have their own individual payment method (e.g., CASH). - In Cloth Shop, add Furniture Shop as a trusted PoS. - In Cloth Shop, enable "Log in with Employee". - Open Cloth Shop and Furniture Shop in separate browsers (different users). - Refresh Cloth Shop once. - In Cloth Shop, create and save an order. - In Furniture Shop, open that order and try to pay with "CASH". Observation: * A validation error is raised: "The payment method selected is not allowed in the config of the POS session." <img width="320" height="201" alt="image" src="https://github.com/user-attachments/assets/8ca80575-76bf-4ecf-a739-08b03d543ed6" /> - although we can pay the order by a shared payment method Cause: - Refreshing Cloth Shop triggers `notify_synchronisation` due to `setCashierUpdateSession` , which pushes Cloth Shop's `pos.session` record into Furniture Shop's IndexedDB (because Cloth Shop trusts Furniture Shop). https://github.com/odoo/odoo/blob/6a3655c8efd2de68754ace38bd1ab5eb6499faca/addons/pos_hr/static/src/app/services/pos_store.js#L61-L63 - When Cloth Shop saves an order, sync also pushes a copy of that order into Furniture Shop, and passed through `processDynamicRecords` - `processDynamicRecords` ensures that the Record created is in sync with server data, as Furniture Shop now has a local record of session of Cloth Shop, the record keeps `session_id` pointing to Cloth Shop's session, else it would have been left `undefined` - from the `res` we get, we set the session_id on `pos.order ` https://github.com/odoo/odoo/blob/6a3655c8efd2de68754ace38bd1ab5eb6499faca/addons/point_of_sale/static/src/app/utils/devices_synchronisation.js#L127-L139 - However with pos_restaurant installed we get its orveride which stores the result of super() and only returns result early when there are no` pos.order ` records in dynamicRecords. When pos.order records are present (our case), the method proceeds with its own logic but never returns result (or its own output) at the end https://github.com/odoo/odoo/blob/6a3655c8efd2de68754ace38bd1ab5eb6499faca/addons/pos_restaurant/static/src/app/utils/devices_synchronisation.js#L5-L9 - so the corrected data from the super call is silently dropped. - we do not get a change to update the session id - The order keeps Cloth Shop's session ID - Furniture Shop's payment validation checks the order against its session's allowed payment methods, but since the session is still Cloth Shop's, the check fails for methods not shared between Cloth Shop and Furniture Shop (e.g., CASH). Why this is hidden in other cases: - without pos_restaurant, or if Furniture Shop had no prior knowledge of Cloth Shop's session (we made is possible by `Log in with Employee` feature, session_id would stay `undefined` and later get correctly set toFurniture Shop's session in PosOrder.setup(). https://github.com/odoo/odoo/blob/6a3655c8efd2de68754ace38bd1ab5eb6499faca/addons/point_of_sale/static/src/app/models/pos_order.js#L27-L30 or from here https://github.com/odoo/odoo/blob/6a3655c8efd2de68754ace38bd1ab5eb6499faca/addons/point_of_sale/static/src/app/utils/devices_synchronisation.js#L127-L139 - Both safety nets happen to be bypassed here. Fix: * Tighten the early return condition so that data is only discarded when the current configuration is not a restaurant configuration. * Also, A trusted PoS configuration cannot be a restaurant, so not returning later makes sense. opw-6465228 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#287574 Forward-Port-Of: odoo/odoo#282962
Preparation tickets printed through an Obox-connected printer are now excluded from the kiosk’s own local printing list. This prevents the same kitchen or preparation ticket from being printed twice, reducing paper waste and staff confusion.
Original PR description
A preparation printer proxied through an Obox is not reachable by the customer device: `pos.order._send_order` queues its ticket server side. Now that the kiosk prints its preparation ticket again, such a printer must be left out of the ones the device prints on itself, otherwise the ticket is printed twice. `hasProxyPreparationPrinters` is superseded by `localPreparationPrinters` and is left deprecated here, to be removed in master. Task-6537765 Related : https://github.com/odoo/odoo/pull/269216
Updated the help text for the Linphone provisioning QR code in VoIP user settings. This makes phone setup guidance clearer for users and reduces confusion during configuration.
This fix makes an automated rental shop test wait for the calendar to finish updating before choosing a date. It helps prevent false test failures, improving confidence that rental pricing and checkout flows are working as expected.
Original PR description
The shop_buy_rental_stock_product tour can select a day from the previous month's grid before the date picker finishes rendering the next month. This can leave the rental period unchanged and cause the cart price assertion to fail. Wait for an animation frame after clicking "next month" before selecting a day. runbot-240903 Forward-Port-Of: odoo/enterprise#131467 Forward-Port-Of: odoo/enterprise#130822
The UAE payroll update process now restores required payroll structure data in the correct order before updating salary rules. This prevents scheduled payroll maintenance from failing when UAE payroll structures or structure types were previously deleted.
Original PR description
Currently, an error occurs when the Payroll Update Data schedule action is run. **Steps to Reproduce:** - Install the `l10n_ae_hr_payroll` module without demo data. - Create a new company with the…
Currently, an error occurs when the Payroll Update Data schedule action is run. **Steps to Reproduce:** - Install the `l10n_ae_hr_payroll` module without demo data. - Create a new company with the country set to `United Arab Emirates`. - Switch to that company. - Go to `Payroll` > `Configuration` > `salary` > `Structures`. - Delete all salary structures related to the `United Arab Emirates`. - Go to `Scheduled Actions` and run `Payroll: Update Data`. `ValueError: External ID not found in the system: l10n_ae_hr_payroll.uae_employee_payroll_structure.` After this [recent commit], hr_rule_parameter_data and hr_salary_rule_data were added to _get_data_files_to_update. If the user deletes the salary structure and then updates the data files [1], an error is raised because the structure is missing. This commit ensures that the salary structure data is updated before updating the salary rule data. It also ensures that the salary structure type data is updated beforehand, as the structure depends on it and the user can delete the structure type data. [recent commit]: https://github.com/odoo/enterprise/commit/f3316e056da817ca31fecdc04e0f8df000f0f038 [1]- https://github.com/odoo/enterprise/blob/0a0b3a50a81df062ddee5c310ce06aaa4533a8a8/l10n_ae_hr_payroll/models/hr_payslip.py#L98-L105 sentry-7496380516 Forward-Port-Of: odoo/enterprise#130654
The voice message recorder in Discuss now aligns correctly when used in AI chat. Recording action buttons have been adjusted to appear as consistent circular controls, and the download icon display has been corrected for a cleaner user experience.
Original PR description
If we start a voice message in the AI chat the `o-mail-VoiceRecorder` is vertically misaligned. Also the cancel and validate recording buttons were not perfect circles, they now match the other buttons sizes and style. task-6565360 | Before | After | |--------|--------| | <img width="782" height="641" alt="image" src="https://github.com/user-attachments/assets/6f0a73ec-7fd5-466a-a909-269c7a734087" /> | <img width="786" height="638" alt="image" src="https://github.com/user-attachments/assets/145d8d17-c9a6-4a2a-8efa-2c43288b3960" /> | --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
A bug was fixed so grouped search options update correctly after recent interface changes. This helps prevent incorrect or stale search dropdown behavior for users working with grouped views.
Original PR description
See commit messages for details. - Runbot [945677](https://runbot.odoo.com/odoo/error/945677) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The Point of Sale code now relies on an existing local storage mechanism for temporary order information instead of keeping a separate extra data field. This reduces duplicate storage logic and helps keep POS-related localization features easier to maintain without changing day-to-day cashier workflows.
Original PR description
Since `uiState` is also stored in `indexedDB` and can be used instead, we remove `PosOrder.extraField`. see odoo/enterprise#129862 task-6487351
Payroll work entry types have been renamed and reorganized to match Partena conventions, making it easier for Belgian payroll users to move from Partena software to Odoo. Duplicate time types were cleaned up and some entries were replaced with broader categories, improving consistency across payslips and payroll reporting.
The point of sale settlement flow now relies on already stored interface state instead of keeping a separate extra data field on orders. This reduces duplicate stored information and helps keep the payment validation process easier to maintain without changing the cashier experience.
Original PR description
Since `uiState` is also stored in `indexedDB` and can be used instead, we remove `PosOrder.extraField`. see odoo/odoo#285668 task-6487351
This updates internal editor and in-app purchase components to use the newer component property handling expected by the underlying web framework. It helps keep these areas maintainable and better validated without changing day-to-day user workflows.
Original PR description
- https://github.com/odoo/enterprise/pull/131126 See commit messages for details. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update modernizes internal component definitions used by the HTML editor, AI-assisted media tools, website sales editor integrations, and Knowledge cover dialogs. It helps keep these areas compatible with the latest interface framework and improves validation without changing user-facing workflows.
Original PR description
- https://github.com/odoo/odoo/pull/287592 See commit messages for details. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Product and description information now uses Odoo's standard stacked field layout across documents such as sales, purchases, invoices, and stock moves. This reduces custom interface behavior, improves consistency, and helps avoid display issues when editing product descriptions.
Original PR description
Replace the shared `product_and_description.js` widget, used by SOL, POL, AML and stock moves, with the framework's native support for stacking multiple fields in a single column. The product and…
Replace the shared `product_and_description.js` widget, used by SOL, POL, AML and stock moves, with the framework's native support for stacking multiple fields in a single column. The product and description are now rendered through the `product_and_description` column using the `product_label_section_and_note_field_o2m` field. This provides product label support when available and preserves section/note handling without requiring custom product/description rendering logic. Centralize column-group visibility through `isColumnGroupFieldVisible()` and remove the custom column manipulation previously handled by `ProductNameAndDescriptionListRendererMixin`. Remove description-specific logic from `ProductLabelSectionAndNoteField` and rename the field widget to `AccountProductField`, limiting it to handling product clickability based on the current conditions. `SectionAndNoteListRenderer` continues to treat `product_and_description` as the title field, while `description_picking` retains its previous behaviour. This removes the need to render the description inside the product field, eliminating the associated `AutoResize` issues and allowing the framework to handle description rendering and column layout natively. This is the follow-up JS cleanup to the [previous PR](https://github.com/odoo/odoo/pull/273948) that removed the product name from the description (name) field. task-6241473 See also: - https://github.com/odoo/enterprise/pull/130154 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update aligns accounting and helpdesk list views with a recent platform naming change. It is an internal cleanup that helps keep these screens compatible and maintainable, with no expected change to day-to-day user workflows.
Original PR description
This commit is the direct consequence of the rename of isCellReadonly into isFieldReadonly operated in https://github.com/odoo/odoo/pull/287378 due to the nature of stacked fields in list view. task-6564093
This pull request reorganizes and updates Odoo's internal ORM test models. It helps maintain product quality by making core automated tests easier to manage, with no expected direct change for everyday users.
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
The HR module now uses one shared method to determine an employee's reference working calendar, including for a specific date. This reduces duplicated logic and helps keep schedule-related behavior consistent across HR and payroll-related processes.
Original PR description
hr.employee._get_flexible_reference_calendar and hr.version._get_reference_calendar (added by hr_payroll) resolved a fallback calendar the same way. Move the logic to hr.version as the single _get_reference_calendar, accepting an optional date to resolve the employee's version on that date, and drop the now-unused employee-level hook. task-6569832
Payroll warning messages have been rewritten to be easier to understand and less distracting in the interface. This helps payroll users identify and resolve issues more quickly, especially in Belgian payroll workflows.
Original PR description
Warning messages from hr_payroll and l10n_be_hr_payroll module have been reformulating to increase clarity and lighten the UI. Task: 6523051
This update reorganizes how navigation item styling is handled in the web notebook component. It should not change what users see, but it reduces duplication and makes future interface fixes safer and easier to apply.
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