Tuesday, September 15, 2026
11 changes · master
New 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
## 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
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
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.
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
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
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.
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
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