Thursday, September 24, 2026
18 changes · master
Enhancements to existing features
This change removes duplicate calendar access rules that did not grant any additional permissions beyond what internal users already had. It reduces administrative clutter and makes access settings easier to maintain and customize across related Odoo modules.
Original PR description
This commits removes redundant access rights (ir.model.access), that are not really adding any extra rights when compared to those added to all internal users by the `calendar` module: * xmlid:…
This commits removes redundant access rights (ir.model.access), that are not really adding any extra rights when compared to those added to all internal users by the `calendar` module: * xmlid: `calendar.access_calendar_event_all_employee` * xmlid: `calendar.access_calendar_event_type_all` * xmlid: `calendar.access_calendar_attendee_employee` As this is just noise that adds no value, it's better to remove them in order to make it easier to maintain and customize them. **Screenshots:** In red, the removed Access Rights <img width="1350" alt="Screenshot 2024-02-21 at 16 07 10" src="https://github.com/odoo/odoo/assets/1914185/29e40b85-eb91-405d-8120-495c5aa8942c"> <img width="1348" alt="Screenshot 2024-02-21 at 16 11 03 1" src="https://github.com/odoo/odoo/assets/1914185/11c743d1-82c7-4f3c-9c17-fa9251350cb0"> <img width="1348" alt="Screenshot 2024-02-21 at 16 11 55" src="https://github.com/odoo/odoo/assets/1914185/c6914a89-4b12-4acd-a61b-d4eb4ab3fbe0"> --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Adds automated checks to ensure default values are preserved correctly when one record inherits data from another. This helps prevent confusing or inconsistent form behavior for users and reduces the risk of this issue returning in future versions.
Original PR description
Add unit tests to prove a bug. No fix yet.. The added test is self explainatory, but here's some more context:…
Add unit tests to prove a bug. No fix yet.. The added test is self explainatory, but here's some more context: [EmailMessage](https://github.com/odoo/odoo/blob/c0ce5619ada6952261fd44f28108108040629d81/odoo/addons/test_new_api/models/test_new_api.py#L216) inherits from [Message](https://github.com/odoo/odoo/blob/c0ce5619ada6952261fd44f28108108040629d81/odoo/addons/test_new_api/models/test_new_api.py#L127) through its `message` field. It's impossible to set a default value for this field, as it gets set back to `False` during the `onchange`. It's even worse, the results are unpredictable. Related inherited fields will reference the value of the parent `message`, but the message itself will be `False`. (see `self.assertEqual(form.label, message.label)`) I couldn't find a fix yet, but I tracked it down to this: - https://github.com/odoo/odoo/blob/c0ce5619ada6952261fd44f28108108040629d81/odoo/models.py#L6415-L6418 Which makes the `record`, `snapshot0` and `snapshot1` to have a `NewId` value for `message` in the end, that gets converted to `False` during `convert_to_write` -- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Barcode rendering now supports SVG in addition to the existing PNG option. This lets barcodes be resized for very small or large labels without losing print quality, while keeping PNG as the default for existing uses.
Original PR description
**Description of the issue/feature this PR addresses:** Introduce a new `format` parameter which can be used to choose among 'png' (default) and 'svg' for the barcode rendering. SVGs have unlimited scaling capabilities, which is great when printing really small or really big barcodes in labels, etc; as there's absolutely no quality loss when resizing --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update removes an unnecessary customization in the Purchase app. It keeps the codebase simpler and easier to maintain without changing day-to-day purchasing workflows.
Original PR description
**Description of the issue/feature this PR addresses:** Remove useless method override --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Demo user and employee profile pictures have been refreshed with newer illustrations and a more efficient image format, reducing the overall file size while improving image resolution. Employee photos are also better preserved when a related user's avatar changes, avoiding accidental overwrites.
Original PR description
*: base,crm_livechat,hr,im_livechat,mail,sale_timesheet, stock, website_event, website_hr_recruitment_livechat A very needed update of the photo avatars. | files | size -- | -- | -- removed | 57 (8 png, 49 jpg) | 623 KB added | 57 webp | 212 KB net | ±0 | −411 KB (−66.0 %) Increased images' width x height from 128x128 to 200x200 px Switch from .jpg/.png to .webp. New illustrations for user avatars. Changes made to `hr/models/res_users.py` mean an employee photo survives a change of the user's avatar. task-6538183 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#290046
Spanish Veri*Factu invoice issues that were previously hidden are now shown directly on the sales journal dashboard. This helps accounting teams find invoices that are invalid or rejected sooner, reducing the risk of unnoticed compliance problems.
Original PR description
Users had no easy way to spot sale invoices that are broken from a Veri*Factu standpoint. Invoices that fail local validation before anything is sent (e.g. more than one main tax on a line) generate…
Users had no easy way to spot sale invoices that are broken from a Veri*Factu standpoint. Invoices that fail local validation before anything is sent (e.g. more than one main tax on a line) generate a l10n_es_edi_verifactu.document that could never be generated or sent to the AEAT. These never showed up as broken anywhere and could sit unnoticed until someone opened the invoice's Veri*Factu tab. Add an 'invalid' state to l10n_es_edi_verifactu.document, set when a document ends up with errors because it could not be generated (local validation, XSD, chaining...), next to the existing 'rejected' state (document actually sent to and rejected by the AEAT). Keeping the two states distinct and on the document itself matters: 'rejected' keeps its documented meaning of "sent and rejected", and only a real AEAT rejection makes the next submission carry Subsanacion/RechazoPrevio. Add a "Veri*Factu Error(s)" entry to the sale journal's dashboard kanban card, with its own search filter, matching both 'rejected' and 'invalid' invoices, so they are visible from the accounting dashboard without having to open each one individually. task-6463206 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#289583
This improves the website footer configuration by making the content width option depend on the selected footer template. It helps keep footer layouts more consistent and easier to manage across website designs.
Original PR description
WIP 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
Accounting tax detail calculations have been simplified to run much faster on large datasets, especially for complex localization scenarios such as India. This improves reporting performance while preserving correct handling of special tax cases like Luxembourg Ecotrel taxes.
Original PR description
The tax details query was very complicated for basically the affect base amount cases and with the enduring perf problems in India we decided to simplify. Also, the only case where we know this is…
The tax details query was very complicated for basically the affect base amount cases and with the enduring perf problems in India we decided to simplify. Also, the only case where we know this is needed, is the one for Ecotrel taxes in LU. Those however, can be reported diffently: if you have 100€ + 2% + 21%, as we have the tax_i on the tax line of 2%, the 2% can also be reported as a regular invoice line (at least in SAF-T) with 21% tax. So, in the query, we basically add the 2% tax line as well as base line and the query automatically calculates what is needed. However, we need to match the tax_ids of the base line with the tax_ids of the tax line such that if you have 100€ + 2% + 21% and 100€ + 2% + 6%, the 2%s are correctly matched. Before, the query had a fallback in case the base and tax lines do not match. Here we just make sure that when the repartition line has no account, we check that the base line has the same account as the tax line. As in the query, we need to make sure that one base line per child tax only goes to one tax line. In terms of perf, checking on a 18 db for l10n_in where it was already rather slow with the same domain, we go from 1m32 with the old query to 14s with this new simplified one. This is on a real database with many amls for the period. (400k) Testing locally with 10M amls, the old query just does not pass, but the simplified still does in a little more than 200s. task-3941950 Enterprise PR - https://github.com/odoo/enterprise/pull/126867 Forward-Port-Of: odoo/odoo#289238
This change speeds up internal test invoice creation for Argentina localization reports by avoiding a slower form-based process. It reduces test setup time and database queries while keeping report results unchanged, helping development and validation run more efficiently.
Original PR description
The use_current_date=False branch of _create_test_invoices_like_demo built 18 invoices through Form, which reruns the whole move onchange for every field of every line. It was two thirds of the l10n_ar_reports class setup. Create them with _create_invoice from the fields the Form set, like the other branch does. The accounting date is now the invoice date on every invoice, the report output is unchanged. With the l10n_ar_reports counterpart: | l10n_ar_reports, runbot 18.0 L10n | before (3 builds) | after | |------------------------------------|-------------------|-------| | TestArReports setUpClass | 78-103s | 31s | | module test time | 80-106s | 33s | | queries | 45.4k | 28.4k | Forward-Port-Of: odoo/odoo#290123 Forward-Port-Of: odoo/odoo#290111
This update improves the speed of an internal data operation used by Odoo, especially when working with large collections of records. It reduces processing overhead without changing business behavior, helping larger workloads run more efficiently.
Original PR description
`OrderedSet` inherited `-` from `collections.abc.Set`, which builds the result via a generator and, when the other operand is itself a `Set` (including another `OrderedSet`), tests membership through…
`OrderedSet` inherited `-` from `collections.abc.Set`, which builds the result via a generator and, when the other operand is itself a `Set` (including another `OrderedSet`), tests membership through `OrderedSet.__contains__` for every element - a Python-level call per test instead of a raw dict lookup. Specialize `__sub__`, mirroring the existing `__and__`: unwrap an `OrderedSet` operand to its backing dict, use a plain `set`/`frozenset` operand as-is, and only convert other iterables. This keeps membership tests at dict/set speed in every case without adding a copy where one isn't needed. Benchmarking comparing the __sub__ operation of OrderedSet to OrderedSets and on other iterables (Ordered set - othertype). The other object contains 1/2 of the objects in the original OrderedSet. The time values are averaged across 200 runs. | OrderedSet Size | Other Type | Old Time (µs) | New Time (µs) | |---|---|---|---| | 100 | OrderedSet | 6.8 | 4.6 | | 100 | Set | 3.4 | 3.4 | | 100 | FrozenSet | 3.7 | 3.4 | | 100 | list | 8.4 | 4.3 | | 10,000 | OrderedSet | 574.3 | 293.9 | | 10,000 | Set | 288.0 | 274.6 | | 10,000 | FrozenSet | 285.2 | 271.5 | | 10,000 | list | 742.3 | 343.0 | | 100,000 | OrderedSet | 5,851.7 | 2,968.0 | | 100,000 | Set | 2,876.7 | 2,787.7 | | 100,000 | FrozenSet | 2,864.3 | 2,787.7 | | 100,000 | list | 7,692.2 | 3,678.5 | | 1,000,000 | OrderedSet | 61,629.1 | 32,759.28 | | 1,000,000 | Set | 31,377.5 | 30,295.9 | | 1,000,000 | FrozenSet | 31,330.4 | 30,540.1 | | 1,000,000 | list | 99,383.1 | 55.381.4 |
The Belgian payroll employee Sub-type field now shows the descriptive name instead of the numeric DMFA code when available. This makes employee records easier to understand and aligns the interface with the updated terminology.
Original PR description
The employee Sub-type field currently displays the numeric DMFA code. As the concept was renamed from 'worker code' to 'sub-type', displaying the name is more relevant for users. This commit updates `l10n.be.worker.code` to display its name by default (falling back to the code if empty) and updates the form placeholder accordingly. Task: 6586101 Forward-Port-Of: odoo/enterprise#132354
The General Ledger report now calculates opening balances separately from period activity so it can reuse stored snapshots. This should make the report faster to load and easier to use, especially for companies with large accounting histories.
Original PR description
Forward-Port-Of: odoo/enterprise#132788
Demo user avatars across several Odoo apps were refreshed with new illustrated images. The image format was changed to WebP and duplicate files were removed, reducing the overall file size while improving visual quality.
Original PR description
Indian GSTR-1 return exports now use a more efficient data retrieval approach that reduces memory use and processing time for large reports. This helps businesses complete high-volume GST filings more reliably without hitting system limits.
Original PR description
Current Implementation: ======================= The current implementation of _get_l10n_in_gstr1_json relies on multiple iterations over ORM recordsets. Since the ORM loads multiple fields rather…
Current Implementation: ======================= The current implementation of _get_l10n_in_gstr1_json relies on multiple iterations over ORM recordsets. Since the ORM loads multiple fields rather than only the required fields, memory consumption grows significantly for large datasets (around 700 MB for 150K account move lines). Additionally, the method builds a single large dictionary from _get_tax_details that is tailored for the Indian GST reporting logic. Constructing and holding this intermediate data structure further increases memory usage. The combination of repeated Python loops, ORM overhead, and the large intermediate dictionary results in high execution time and memory consumption, causing the process to exceed the available time and memory limits for large exports. Solution: ========= Instead of processing tax details through the ORM, create a sql query that return result that group by base line and select other info that we need for GSTR1 JSON Also use dictfetchmany with limit so we not have process the data in batch This approach bypasses the ORM, fetching only the required columns instead of entire records. Eliminates the need to build the large _get_tax_details dictionary. This significantly reduces memory usage, improves execution speed, and makes the implementation simpler and easier to maintain. task-3941950 Community PR - https://github.com/odoo/odoo/pull/289238 Forward-Port-Of: odoo/enterprise#126867
This update adds automated test coverage for creating invoices from helpdesk tickets. It helps ensure invoices are only created when tickets are eligible, reducing the risk of duplicate or invalid billing.
Original PR description
Add a test covering invoice creation from helpdesk tickets.
**The test verifies:**
- Non-billable tickets cannot create an invoice.
- Tickets linked to an already invoiced sale order cannot create another invoice.
- A mix of billable and non-billable tickets prevents invoice creation.
- A billable ticket can create an invoice.
Part of this task-4243781
task-6594785
Forward-Port-Of: odoo/enterprise#132747Indian localization reports no longer show warnings tied to the repealed Income Tax Act, 1961. This keeps report messaging aligned with current legislation and avoids unnecessary alerts for users.
Original PR description
As the Income Tax Act, 1961 has been repealed completely, remove the warning mechanism for reports related to the old act. Forward-Port-Of: odoo/enterprise#132544
The Argentine reports test setup now creates sample vendor bills more directly, avoiding unnecessary repeated processing. This reduces automated test time and database work while keeping the accounting report results unchanged.
Original PR description
Same as the l10n_ar fixture: the 10 demo vendor bills were built through Form, rerunning the whole move onchange for every field of every line. Create them with _create_invoice from the fields the Form set. The accounting date is now the invoice date on every bill, the report output is unchanged. With the l10n_ar counterpart: | l10n_ar_reports, runbot 18.0 L10n | before (3 builds) | after | |------------------------------------|-------------------|-------| | TestArReports setUpClass | 78-103s | 31s | | module test time | 80-106s | 33s | | queries | 45.4k | 28.4k | Forward-Port-Of: odoo/enterprise#132841 Forward-Port-Of: odoo/enterprise#132697
Reports can now offer dropdown-style choices in editable cells, helping users pick from approved options instead of typing free text. This is applied to France's 2069 RCI Fiscal Declaration so tax credit types are selected from predefined values, reducing entry errors and improving consistency.
Original PR description
This PR is divided in two commits which does following things: 1. It adds a new support for adding selection type values in report line cells. This will allow the users to select any one option among the given choices (just like date, boolean, literal values). 2. With the introduction of this new selection values, it adapts this feature into France's 2069 RCI Fiscal Declaration Report. task-6159824 Forward-Port-Of: odoo/enterprise#116926
*: documents, hr_contract_salary, hr_payroll, l10n_*_hr_payroll, planning, social_push, test_l10n_be_hr_payroll_account, website_event_social, website_helpdesk_livechat A very needed update of the avatars | files | size -- | -- | -- removed | 71 (1 png, 70 jpg) | 534 KB added | 45 webp | 174 KB net | −26 files | −360 KB (−67.4 %) Increased images' width x height from 128x128 to 200x200 px Remove duplicate images in the l10n_*_hr_payroll files, just one copy in the hr_payroll module. Switch from .jpg/.png to .webp. Added illustrated avatars for users. task-6538183 Forward-Port-Of: odoo/enterprise#132623