Thursday, September 24, 2026
81 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
Resolved issues and error corrections
Cancelling accounting entries that were still in draft now deletes them instead of creating reversal entries. This avoids recording financial amounts that were never actually posted, especially when periods have already been locked.
Original PR description
_unlink_or_reverse relies on _can_be_unlinked, which only looks at the hash and the lock dates. A draft entry dated in a locked period thus lands in the reversal branch: it is copied, the copy is posted after the lock date and the draft stays behind. The reversal books amounts that were never posted in the first place. Lock dates protect what has been booked. An entry that was never posted can be deleted whatever its date. Seen with hr_payroll_account when a payslip is cancelled after the accountant locked the period without posting the salary entry. Any caller of _unlink_or_reverse (assets, loans, deferred entries) behaves the same. Forward-Port-Of: odoo/odoo#290210 Forward-Port-Of: odoo/odoo#289980
Features or functions removed from Odoo
The Indian localization no longer includes legacy TCS and TDS tax entries tied to the repealed Income Tax Act, 1961. This keeps new Odoo databases aligned with the Income Tax Act, 2025, without changing existing databases.
Original PR description
As the Income Tax Act, 1961 has been repealed and replaced by the Income Tax Act, 2025, the taxes related to the old TCS and TDS sections are no longer needed. In this commit, the old TCS and TDS taxes and their tax group are removed. No migration is added, as these taxes are only removed for new databases. Forward-Port-Of: odoo/odoo#289832
Code cleanup and technical improvements
This update consolidates how work entry type labels and color indicators are displayed across HR screens. It removes duplicate internal code, making the interface easier to maintain while keeping the visible experience consistent for users.
Original PR description
Unify the work entry type rendering logic to eliminate duplicate files and code: - Remove redundant `work_entry_type_badge_field.js` and `work_entry_type_badge_field.xml`. - Extend the `hr_work_entry.WorkEntryType` QWeb template to accept an optional `label` parameter, enabling it to render either a standalone color pill or a pill with an adjacent label. - Move `WorkEntryTypeBadgeField` into `work_entry_type_field.js` to keep all related field registrations in a single component directory. - Update `hr_work_entry.WorkEntryTypeBadgeField` and `hr_work_entry.Many2OneWorkEntryTypeField` templates to call the unified sub-template with their respective data. Task:6578031 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#289144
*: 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
When a Belgian partner's VAT number is changed, the related BCE/KBO identifier is now updated automatically instead of keeping the old value. This keeps business identity data consistent and helps dependent services, such as electronic invoicing endpoints, use the correct information.
Original PR description
Steps to reproduce: * Install **Accounting** module. * Create a Belgian partner. * Assign a VAT number (e.g. BE0477472701). * The BCE/KBO field in Multi ID is correctly populated. * Modify the VAT…
Steps to reproduce:
* Install **Accounting** module.
* Create a Belgian partner.
* Assign a VAT number (e.g. BE0477472701).
* The BCE/KBO field in Multi ID is correctly populated.
* Modify the VAT number.
Observed behavior:
* The BCE/KBO (BE_EN) in Multi ID keeps the old value.
Cause:
* `_deduce_additional_identifiers_from_vat` skipped any identifier key that already existed in `additional_identifiers`: new_identifiers = {k: v for k, v in deduced.items() if k not in identifiers}
* On the first VAT save, BE_EN is written correctly.
* On subsequent VAT changes, BE_EN already exists, so the condition short-circuits and the old value is preserved.
Fix:
* Replace the key-presence guard with a value-equality check so that deduced identifiers are always overwritten when their value would change: updated = {k: v for k, v in deduced.items() if identifiers.get(k) != v}
* Since BE_EN is fully derived from the VAT (it is the VAT with the country prefix stripped), it must always mirror the current VAT.
* The Peppol endpoint is already declared as depending on `additional_identifiers`, so it recomputes automatically once BE_EN is corrected — no further change needed there.
opw-6545770
Forward-Port-Of: odoo/odoo#290348
Forward-Port-Of: odoo/odoo#288057Discuss calls now return to the expected view after a user leaves the meeting layout. This prevents the call from staying stuck on a spotlighted participant when it should show the pinned person, shared screen, chat focus, or tile view.
Original PR description
In the meeting view, the call layouts pick which participant fills the main window from the recent speakers and store it in activeRtcSession. That choice was kept after going back to Discuss (ESC, minimize, or the Discuss layout), so a call that showed tiles stayed in spotlight. Now, when the meeting view closes, the focus is reset to what Discuss would show on its own: the pinned participant, then a shared screen, then the chat window auto-focus, and otherwise the tile view. View in Discuss app (before opening Meeting view) <img width="685" height="245" alt="Screenshot 2026-09-23 at 21 31 09" src="https://github.com/user-attachments/assets/7a915629-3291-4035-9a67-c8cf4045691a" /> View in Discuss app (after leaving Meeting view) <img width="1920" height="641" alt="Screenshot 2026-09-23 at 21 32 31" src="https://github.com/user-attachments/assets/bda7a386-c7a2-4327-ae5a-9f967c716de7" /> Forward-Port-Of: odoo/odoo#290381
Users will no longer receive both an in-app browser alert and a native push notification for the same mention when their Odoo tab is open but not focused. This reduces notification noise and keeps alerts consistent with the user's notification preferences.
Original PR description
Steps to reproduce: - Grant browser notification permission (subscribes to web push). - Set user A's `notification_type` to `inbox` in preferences and reload. - Keep A's tab open but unfocused. - As user B, post an @-mention on a non-channel chatter record targeting A. A receives two alerts: the JS one from the `mail.message/inbox` bus event and the native notification from web push. `OutOfFocusService.notify()` gated JS skip on `message.thread.model`, but the server never sends `mail.thread`, so chatter fell through. Replace it with a `message_type` + `!isSelfAuthored` filter mirroring the server side `_notify_get_recipients_for_extra_notifications`. Also swap the `isInbox` SW handshake workaround added by [1] when the user is busy. [1]: https://github.com/odoo/odoo/pull/232431 Forward-Port-Of: odoo/odoo#290410 Forward-Port-Of: odoo/odoo#282981
This fix ensures amounts in currencies without decimal places, such as Japanese yen, display the full number instead of dropping meaningful zeroes. It prevents confusing monetary summaries like 100 appearing as 1, improving accuracy in financial information shown to users.
Original PR description
Description of the issue/feature this PR addresses: In Odoo 19.0, format_amount(..., trailing_zeroes=False) removes significant integer zeroes when the currency has no decimal places, such as JPY.…
Description of the issue/feature this PR addresses:
In Odoo 19.0, format_amount(..., trailing_zeroes=False) removes
significant integer zeroes when the currency has no decimal places,
such as JPY. Project update monetary summaries use this formatter
with trailing_zeroes disabled.
Steps to reproduce in an Odoo shell with the default JPY configuration:
```python
from odoo.tools.misc import format_amount
currency = env.ref('base.JPY')
format_amount(env, 100, currency, trailing_zeroes=False)
format_amount(env, 0, currency, trailing_zeroes=False)
```
Current behavior before PR:
The numeric part of 100 becomes 1, and the numeric part of 0
disappears. Grouped amounts can also lose digits and leave an
incomplete thousands group.
Desired behavior after PR is merged:
Preserve all integer digits for currencies without decimal places.
Only strip trailing zeroes when a fractional part is present.
Regression coverage includes zero, positive, negative and grouped
amounts, both currency symbol positions, and languages with distinct
or identical decimal and thousands separators.
Validation:
- Before the fix: the new regression test fails in 20 subcases.
- After the fix: all 9 tests in TestFormatAmountFunction and
TestFormatLangDate pass on an isolated PostgreSQL 16 database.
- git diff --check passes.
Test selection:
--test-tags=/base:TestFormatAmountFunction,/base:TestFormatLangDate
This PR also includes my signed Individual Contributor License
Agreement in doc/cla/individual/ysnkucuker.md.
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#290374The messaging menu now visually distinguishes non-chat items from regular chats. Notification prompts use an informational blue background, while failure items use a warning color, making the Chats tab easier to understand at a glance.
Original PR description
Failures and "Turn on notifications" are shown in the "Chats" tab. These items are quite different from usual chat, and it's confusing when they look very similar to chats. This commit fixes the issue by putting a background color on the non-chat items: - info (blue) for the "Turn on notifications" - warning (yellow / orange) for the "Failures" items <img width="1927" height="589" alt="Screenshot 2026-09-23 at 20 45 37" src="https://github.com/user-attachments/assets/8e36f956-d9f0-443c-ae0f-9718e7b21d3f" /> Forward-Port-Of: odoo/odoo#290372
Hungarian electronic invoice XML sent to NAV no longer includes cash rounding as a separate invoice line. This keeps reported invoices aligned with Hungarian legal guidance and prevents rounding differences from being treated like taxable goods or services.
Original PR description
Global cash rounding can be applied to customer invoices. Before this commit, the rounding would be included in the XML file sent to NAV. It would be included as a new invoice line (same as the products lines) and the ATK tax is applied on it. As stated in the legal Hungarian Documentation, an invoice line should always relate to the supply of a good or the service provided. In this case, a cash rounding (which is not a financial advantage or disadvantage) will be considered by the law as a settlement difference, that is not part of the invoice. So, this commit removes cash rounding lines from the NAV XML. Moreover, it uses base_lines for the amounts computation instead of line_ids. task-6527383 Forward-Port-Of: odoo/odoo#290375 Forward-Port-Of: odoo/odoo#286258
This fixes reconciliation cases where no exchange difference is needed by ensuring the company currency is used. It helps prevent small remaining balances from being left in company currency after reconciling foreign-currency entries.
Original PR description
When doing reconciliation with no exchange difference, the currency used should always be the company currency. Using foreign currency in that case could leave residual amounts in company currency. task-6582723 Forward-Port-Of: odoo/odoo#289237
The Sales Spreadsheet Dashboard no longer checks for a subscription-related product field that may not exist in this setup. This prevents an error from being logged when users open or edit the sales dashboard, improving reliability without changing dashboard functionality.
Original PR description
Currently an error occurs in the log when the user tries to open dashboard
Steps to Reproduce:
---
1. Install the `spreadsheet_dashboard_sale` module
2. Navigate to Dashboards > Sales Dashboard.
3. Open or click on Edit for the Sales Spreadsheet Dashboard.
Error:
---
`ValueError: Invalid field product.template.recurring_invoice in condition ('recurring_invoice', '!=', True)`
Cause:
---
The recently added commit [1] adds a domain using the
`product_tmpl_id.recurring_invoice` field. However, this field belongs to
the `sale_subscription` module, which is not a dependency of the current module.
Fix:
---
Remove the non-existing `product_tmpl_id.recurring_invoice` field filter from the domain
[1]: https://github.com/odoo/odoo/commit/10fe64e63987b93e42e28cc6fb8319af326ab8be
sentry-7752145163
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#290507The mail call settings dialog was adjusted to remove an unwanted visual separator. This keeps the dialog aligned with the updated Frost design and provides a cleaner, more consistent user experience.
Original PR description
The call settings dialog contains a separator that is not desirable with the frost design.
Remove the separator span altogether to keep the dialog consistent with the updated design.
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#290477The blog page header spacing has been adjusted so it lines up consistently with other website pages such as Shop and Events. This creates a cleaner, more uniform browsing experience for visitors without changing functionality.
Original PR description
The blogs navbar has a top margin (`mt-3`). It was added so the navbar is not too close to the top of the page (before the title was added with commit [1]), but it made it unaligned to other pages navbar, like /shop and /events. This commit removes this margin so all the pages are aligned. [1]: https://github.com/odoo/odoo/commit/5a4d93901ee9a19fb6bf29fdb46bfa68987850f4 Related to task-3083656 Forward-Port-Of: odoo/odoo#290192
Website cards configured with both a link and a background image now remain clickable as expected. This prevents broken navigation on published pages and helps editors use visual card designs without losing link behavior.
Original PR description
**Problem** Clickable cards do not work if they have an image as background. **How to reproduce** Drop a `s_cards_grid` snippet, select a card, enable "Make it clickable", set a URL, then set a background image on the card. Save. The card is no longer clickable. **Why does it happen** When a background image is set, the card gets the `oe_img_bg` class. This class, through `%o-we-background-layer-parent`, sets `position: relative` on every one of its direct children. This is done to keep the background image behind the snippet's own content, but it interferes with the `a.stretched-link` element, making the card not clickable. **Fix** Exclude `.stretched-link` from the children targeted by `%o-we-background-layer-parent`. task-6462339 Forward-Port-Of: odoo/odoo#289620
The Source PO button now appears only on the subcontractor resupply receipt where it is relevant. This prevents unrelated purchase receipts from showing misleading links, helping users identify the correct purchase order in subcontracting workflows.
Original PR description
After a recent change, the smart button for Source POs uses the reference_ids on a stock.picking. This altered the logic to fetch all orders from any picking that has the same reference. However,…
After a recent change, the smart button for Source POs uses the reference_ids on a stock.picking. This altered the logic to fetch all orders from any picking that has the same reference. However, `subcontracting_source_purchase_count` should specifically relate to the resupply of subcontractor picking to their subcontracted purchase order. **Steps to Reproduce:** 1. Enable multi-step routes and subcontracting 2. Unarchive the MTO route 3. Create 4 products Finished Product, A, B, C, and set MTO on both A and B 4. Put 10 units of C in stock 5. Create a BoM for Finished Product using A and B as components 6. Create a subcontracted BoM for B using C as a component 7. Set the purchase vendor for product A as the vendor 8. Set the purchase vendor for product B as the subcontractor 9. Create and confirm a manufacturing order for Finished Product 10. Confirm the POs The two POs are: 1. Purchase Product A from its vendor 2. Subcontract Product B from its subcontractor and use Product C as a component **Current Functionality:** - Product A's receipt has a **Source PO** smart button pointing to the subcontracting PO for Product B (BUG) - Product B's receipt has a **Source PO** smart button pointing to its own PO (BUG) - Product C's picking has a **Source PO** smart button pointing to its own PO **New functionality:** - Product A's receipt has no **Source PO** smart button - Product B's receipt has no **Source PO** smart button - Product C's receipt has a **Source PO** smart button pointing to its own PO opw-6420168 Forward-Port-Of: odoo/odoo#289710 Forward-Port-Of: odoo/odoo#278908
A missing field was restored in the Project task view. This prevents errors when users assign someone to a task, keeping task management workflows running smoothly.
Original PR description
Commit [1] introduced adaptations to the project kanban card and accidentally removed the `project_sharing_portal_user_ids` field, which causes an error when a user tries to assign someone to a task. This commit reintroduces the missing field. [1]: https://github.com/odoo/odoo/commit/d241bd70fe01b51f9cec6cc8140753d14ccd2af8 task-3462435 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#290162
This fixes a mobile display issue in Point of Sale where order search filter options, such as Date or Customer, were hidden behind the order list. Mobile users can now choose the correct search field reliably, making it easier to find past orders on small screens.
Original PR description
Steps to reproduce: - Open a PoS session on a small screen (mobile app or mobile browser) - Register at least one order, so the order list is not empty - Go to the Orders screen and type a term in…
Steps to reproduce: - Open a PoS session on a small screen (mobile app or mobile browser) - Register at least one order, so the order list is not empty - Go to the Orders screen and type a term in the search bar Issue: On a desktop the search bar drops down the list of fields to search on (Reference, Receipt Number, Invoice Number, Date, Customer). On a small screen that list never shows up, so the search silently falls back to the first field and there is no way to search by Date or by Customer. Cause: The list is rendered, but painted behind the order list. Under the media-breakpoint-down(sm) block of ticket_screen.scss the order list becomes `position: sticky; z-index: 1`, so a sibling rule raised `.search .fields` to `z-index: 2` to keep the dropdown on top. The `z-1` utility class put on that dropdown in 07f743843830 compiles to `z-index: 1 !important` and overrides the rule. Both elements end up at `z-index: 1` in the same stacking context, and the order list wins the paint order because it comes later in the DOM. Fix: Drop the `z-1` utility and declare `z-index: 2` on `.fields` in the search bar's own stylesheet, which makes the small-screen override in ticket_screen.scss redundant. The stacking of the dropdown now lives in a single place, next to the rest of its styling, so a utility class added to that element cannot silently disable it again. A tour clicks its target element directly and so cannot see a purely visual overlap, which is why the existing MobileTestUi runs of TicketScreen.search() never caught this. The added assertion checks that a suggestion is the topmost element at its own center. opw-6540466 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#289082 Forward-Port-Of: odoo/odoo#286983
Company-paid expenses created from a project now apply the project analytic allocation only to the actual expense line, not to balancing lines. This prevents project expense reporting from incorrectly cancelling itself out and gives businesses more accurate project cost visibility.
Original PR description
### Current behavior: Creating a company-paid expense from the Project overview posts a journal entry with the project analytic on both the expense and outstanding lines, so the analytic balance nets to zero ### Expected behavior: Analytic distribution should only be on the P&L (expense) line ### Steps to reproduce: 1. Open a project overview and create a company-paid expense 2. Submit, approve, and post it 3. Open the journal entry: analytic is on debit and credit lines ### Cause of the issue: `project_id` stays in the context after `clean_context` during `_create_company_paid_moves`. With `sale_project`, AML analytic compute then applies the project distribution to outstanding/tax lines as well ### Fix: Removed `project_id` from the context when creating company-paid moves opw-6368848 Forward-Port-Of: odoo/odoo#287299 Forward-Port-Of: odoo/odoo#280256
This fixes an internal data model issue where a non-stored related many-to-many field could incorrectly keep a database relationship. The change helps prevent one custom field from accidentally affecting another when reading related records, improving data consistency for customized Odoo setups.
Original PR description
When we setup a many2many field which is not stored, it must not have a relation. This is already done for nonrelated fields, but we must do it also for related fields. Otherwise, we may have…
When we setup a many2many field which is not stored, it must not have a relation. This is already done for nonrelated fields, but we must do it also for related fields. Otherwise, we may have side-effects like finding sibling fields in 20.0: in the code below, reading categories would fill roles.
```py
model_id = self.env["ir.model"]._get("test_new_api.foo")
fields = [{
"name": "x_partner_id",
"ttype": "many2one",
"relation": "res.partner",
}, {
"name": "x_role_ids",
"ttype": "many2many",
"relation": "res.partner.category",
}, {
"name": "x_partner_category_ids",
"ttype": "many2many",
"relation": "res.partner.category",
"related": "x_partner_id.category_id",
"store": False,
"readonly": True
}]
for f in fields:
f["model_id"] = model_id.id
self.env["ir.model.fields"].create(fields)
env['test_new_api.foo']._fields['x_partner_category_ids'].relation # should be None
```
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#290286
Forward-Port-Of: odoo/odoo#290067This fixes an issue where product images could disappear when importing or creating several variants of the same product at once. Businesses can now rely on bulk product imports to keep images on the product and its variants, reducing manual cleanup after catalog updates.
Original PR description
Steps to reproduce: - Import a product CSV with one row per attribute value ("Product Values" column) and an image URL on every row, or create several variants of the same template in one `create()`…
Steps to reproduce:
- Import a product CSV with one row per attribute value ("Product Values" column) and an image URL on every row, or create several variants of the same template in one `create()` call with an image.
- Open the product: neither the template nor the variants have an image. Products without attribute values imported in the same file are fine.
The import creates all variants of a template in a single batch. The inverse of `image_1920` is applied record by record: the first variant finds no image on the template and writes its image there. Writing `image_1920` on the template invalidates the image cache of every product.product, including the sibling variants being created, whose `image_1920` is protected during the inverse and therefore reads back as empty. The next variant then takes the "clear the image from the template" branch and writes `False` on the template, undoing the first write. Nothing is stored.
Read the value to inverse for every record before writing anything, so the invalidation triggered by the template write cannot change what the following records write.
opw-6545651
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#290171
Forward-Port-Of: odoo/odoo#287419Shipment cancellations now send each delivery carrier only the shipments that belong to it. This prevents duplicate cancellation attempts and reduces the risk of carrier API errors or cancelling the wrong shipment.
Original PR description
When cancelling shipments for multiple pickings with different delivery carriers, passing the entire recordset (self) instead of the individual picking to the carrier's cancel_shipment method causes each carrier to receive tracking references that do not belong to it. This results in API errors or silent wrong cancellations at the carrier level, and each shipment being cancelled N times instead of once, where N is the total number of pickings being processed. Forward-Port-Of: odoo/odoo#289809
Fixes an issue where printing labels from the stock allocation report could produce too few labels after partial allocations. The label count now uses the most up-to-date allocation data, helping warehouse teams print the correct number of product labels.
Original PR description
Issue ===== Sometime, when printing product's labels from the allocation report, some labels are missing, the print file doesn't have the right amount. How to reproduce ================ 1. Create a…
Issue
=====
Sometime, when printing product's labels from the allocation report, some labels are missing, the print file doesn't have the right amount.
How to reproduce
================
1. Create a stored product;
2. For this product, create and confirm 3 deliveries (or sale orders):
- 1 for 4 units;
- 1 for 5 units;
- 1 for 6 units;
3. Create and confirm a receipt for 10 units;
4. From this receipt, click on "Allocation" to open the allocation report;
5. In this order, assign:
- 4 units;
- 5 units;
- 1 / 6 units; (Note that 4 + 5 + 1 = 10 units.)
6. Click on "Print Labels" => Only 9 labels are printed.
Cause of the issue & solution
=============================
In the `AllocationReport` `onClickPrintLabels` method, we compute the amount of label to print but this amount was computed based on not correctly updated values.
This commit changes that to base this compute on `productLinesById` which is correctly up to date.
Also, this commit fixes a minor issue by replacing `is_waiting` by `waiting` (when checking move's state) since `waiting` is the right string.
Issue reported during the v 20.0 logistic testing day by VBOL.
Forward-Port-Of: odoo/odoo#289676Stock move references can no longer be edited from list views. This prevents accidental changes to important inventory identifiers and helps keep stock records consistent.
Original PR description
Reference should not be editable in stock move list views Forward-Port-Of: odoo/odoo#290265
This fixes calendar filtering so empty attendee or calendar selections are ignored when building filters. It helps prevent incorrect or confusing calendar results for users working with attendee calendars.
Original PR description
Adds a check when computing filters domain to avoid partner_ids and calendar_id filter. Task-6591658 Forward-Port-Of: odoo/odoo#290199
Time off requests for fully flexible employees now show the correct number of days when the request spans multiple days. This prevents multi-day leave, such as Monday to Friday, from being incorrectly displayed and processed as only one day, while still accounting for public holidays and half-day boundaries.
Original PR description
Steps to reproduce: ------------------------------------ 1. Install Time off module 2. Create New Fully Flexible Employee 3. Click on the Time off smart button 4. Create time off for multiple days…
Steps to reproduce: ------------------------------------ 1. Install Time off module 2. Create New Fully Flexible Employee 3. Click on the Time off smart button 4. Create time off for multiple days (eg. Mon - Friday) Observation: ------------------------------------ Number of days still shows 1 Days. Issue: ------------------------------------ Issue occurs because `work_time_per_day_mapped` returns one interval per day for standard and flexible schedules in multi-day time off requests, so the interval count correctly matches the number of leave days. https://github.com/odoo/odoo/blob/d73e5662a0af7c549008661f743ba5d51f765339/addons/hr_holidays/models/hr_leave.py#L460-L461 However, for fully flexible schedules, it returns a single interval containing the total hours across all days, causing the leave duration to always be computed as 1 day regardless of the actual number of days requested. Solution: ------------------------------------ For fully flexible employees, count the actual calendar days and subtract public holidays when applicable. opw-6060552 Forward-Port-Of: odoo/odoo#255826
This fix improves how Odoo handles searches that exclude certain values, especially when the search follows linked records. Users should see more complete and accurate results when filtering records across sales, inventory, HR, mail, website, and related areas.
Original PR description
Most of the time, when implementing a search method that resolves a
relation, the search method should not support negative operators.
Instead let the ORM inverse correctly the domain.
A domain `[('a.b', op, val)]` when op is negative, we should searh `b`
with the positive operator and negate the domain to have a complete
result.
https://github.com/odoo/enterprise/pull/132619
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#289955Odoo now shows active calls more consistently across the messaging menu, call menu, and member list. This makes it easier for users to recognize when a conversation is in a call, with improved spacing, clearer icons, and better dark mode visibility.
Original PR description
The messaging menu item, the call menu and the member list each showed that a channel is in a call differently. This commit gives them the same call frame and speaker icon, with a stronger frame in dark mode, tucks the messaging menu badge inside the avatar and evens out their spacing and avatar shapes. The messaging menu call participants can only be collapsed from 2 participants on, keeping the toggle room otherwise, and are expanded when reaching that threshold while in the call. <img width="2872" height="908" alt="in-call-hints-full-before-after" src="https://github.com/user-attachments/assets/069a2251-095e-4967-8ad4-cd96030218e9" /> Forward-Port-Of: odoo/odoo#290099
Message cards in the Mail app no longer show extra spacing inside their borders. This makes conversations look cleaner and keeps message content aligned properly with the card edge.
Original PR description
Message cards incorrectly displayed extra padding inside their borders. This commit removes the unnecessary padding so the content aligns properly with the card boundary. **Before/After:** <img width="396" height="146" alt="image" src="https://github.com/user-attachments/assets/8ee0e5a0-54f7-483d-8c25-aa7618263ceb" /> <img width="393" height="129" alt="image" src="https://github.com/user-attachments/assets/620a229e-443f-408c-935d-eff46226a0b5" /> --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#290293
New demo databases will no longer show sample SMS and email failure alerts under the administrator account. These demo failures are now assigned to the demo user, keeping administrator demos cleaner while preserving the example failures for users who need to view them.
Original PR description
Before this commit, a new database with demo data shows "SMS Failure: Contact" and "Email Failure: Contact" in the messaging menu of the administrator, which is the user of most demos. This happens because the sms demo messages with a failed notification are authored by the administrator, and the messaging menu lists the failures of the messages authored by the current user. This commit fixes the issue by giving these messages and their notifications to the demo user, so the failures can still be shown by logging in as that user. Forward-Port-Of: odoo/odoo#290191
Starting or joining a meeting call now shows either the permission dialog or the warning popover, not both at once. This reduces visual clutter and makes it easier for users to respond to microphone or camera permission prompts.
Original PR description
Before this commit, permission dialog and the permission warning popover were displayed at the same time. When starting or joining a meeting call this bloated the UI unnecessarily. Before https://github.com/user-attachments/assets/e4faf5ce-b49a-4fee-a01b-990d0f21ff2b After https://github.com/user-attachments/assets/c6da1e02-e694-4c31-ba0d-b92bf1697877 Forward-Port-Of: odoo/odoo#289865
The file viewer toolbar has been updated with a rounded border and clearer disabled icon styling to better match the current visual design. This improves visibility when users preview files and prevents disabled toolbar items from blending with the document underneath.
Original PR description
- rounded + border on toolbar for improved visibility with viewing file - muted icon look instead of opacity on disabled toolbar item, so that this doesn't show viewing file below <img width="2226" height="690" alt="Screenshot 2026-09-22 at 14 45 34" src="https://github.com/user-attachments/assets/d8a1814e-d227-41d9-964b-1c75316ba205" /> _(icon of Reset Zoom is the same as the "before")_ Forward-Port-Of: odoo/odoo#289917
The Discuss app now keeps the New button available in the channel overview, even after all channels have been deleted. This prevents users from getting stuck when they need to recreate or add channels from the kanban view.
Original PR description
Steps to Reproduce : 1. Install Discuss module. 2. Delete all the existing channels. 3. Try to create new channel from kanban view. Observation : New button is disabled on discuss.channel kanban view only when all records are deleted. With one or more records present the button works fine. List view is unaffected as it has no isNewButtonDisabled logic. Cause: KanbanController.isNewButtonDisabled returns true when the view is grouped by a many2one field, has zero groups, and group_create is enabled (defaults to true). discuss_channel_view_kanban uses discuss_category_id (many2one) as default_group_by, so deleting all records empties all groups and triggers this condition. Fix : Add group_create="0" to the kanban arch tag in discuss_channel_view_kanban to break the isNewButtonDisabled condition, keeping the New button always enabled regardless of group count. Forward-Port-Of: odoo/odoo#290131
Chat bubbles in Mail will no longer bounce just because an existing important message count changes or appears when opened. They now animate only when there is a genuinely new important message, reducing unnecessary visual distractions for users.
Original PR description
Before this commit, chat bubbles were bouncing whenever the important counter changed or they were mounted with an important counter. This made the chat bubbles bounce more often than necessary. This commit limits the bounce when transition from newer important counter. This now limits the bounce to when the chat bubble has actually something important and new right now. https://github.com/user-attachments/assets/a19f3742-3e82-4d4d-880c-e6f08e0d0f2e Forward-Port-Of: odoo/odoo#289958
This update adds missing declarations needed by parts of Discuss, Point of Sale, and Restaurant Point of Sale. It prevents runtime errors that could interrupt users while using these areas of Odoo.
Original PR description
* mail,point_of_sale,pos_restaurant This commit adds missing props declarations which cause runtime errors. Forward-Port-Of: odoo/odoo#290303
Several dropdown menus in the web interface have been adjusted to match the Frost redesign. This improves visual consistency and usability in areas such as autocomplete, navigation, company switching, and tag avatar fields.
Original PR description
This commit adjusts missing dropdowns related to the Frost redesign. task-6589485 | Before | After | |--------|--------| | <img width="258" height="291" alt="Screenshot 2026-09-22 at 10 34 49"…
This commit adjusts missing dropdowns related to the Frost redesign. task-6589485 | Before | After | |--------|--------| | <img width="258" height="291" alt="Screenshot 2026-09-22 at 10 34 49" src="https://github.com/user-attachments/assets/3987f460-11fa-4c15-bebf-1482ad4a6b1e" /> | <img width="244" height="311" alt="Screenshot 2026-09-22 at 10 45 31" src="https://github.com/user-attachments/assets/f86793f9-7dfb-4517-a812-0f7bdd91eefd" /> | | <img width="399" height="213" alt="Screenshot 2026-09-22 at 10 46 00" src="https://github.com/user-attachments/assets/0728dddf-f44f-4c47-946d-30a065b84f6a" /> | <img width="402" height="216" alt="Screenshot 2026-09-22 at 10 45 52" src="https://github.com/user-attachments/assets/9c60190e-1808-466e-badb-413025986e95" /> | | <img width="356" height="339" alt="image" src="https://github.com/user-attachments/assets/40372169-80c2-42df-b527-8b0d5479f936" /> | <img width="396" height="330" alt="Screenshot 2026-09-22 at 15 50 19" src="https://github.com/user-attachments/assets/09eaa1ce-fe42-4e1e-b918-0b0c4c84bece" /> | Requires: - https://github.com/odoo/enterprise/pull/132727 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#289833
Discuss calls now switch the main view to a newly joined participant when the user was previously alone in an automatic-layout call. This makes one-to-one calls feel more natural while still showing clear feedback when the user is speaking.
Original PR description
Before this commit, when starting a discuss call and being alone in the call with "auto" call layout, the spotlight stayed on self user rather than move to the new participant. This happens because…
Before this commit, when starting a discuss call and being alone in the call with "auto" call layout, the spotlight stayed on self user rather than move to the new participant. This happens because the spotlight in "Auto" mode relies on speaker, and when no one speaks this defaults to oldest participant which is self. However when in this scenario, the most important is seeing the other person as soon as they join. This commit fixes the issue by having spotlight show the other participant. Note that with this change affects the showing that self is talking and other people can hear us, as the lack of showing of the self card means we don't see the talking bars on ouselves. This commit solves this problem by mixing the mic "^" quick settings button with the self talking bar, similarly to the Call Menu. That way, when in a call in the meeting view, this is made very clear when we are self talking at this is properly registered in the call. <img width="1220" height="996" alt="Screenshot 2026-09-23 at 17 55 46" src="https://github.com/user-attachments/assets/a9c1df9a-0f7c-4bac-83e9-f0b5a6219d3d" /> Forward-Port-Of: odoo/odoo#290334
This fixes an issue where some grid views could appear empty after the page content was recreated while already scrolled. The grid now refreshes its displayed rows and columns immediately, reducing confusion and avoiding the need for users to scroll or resize the window to see data again.
Original PR description
See commit messages for details. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#289997 Forward-Port-Of: odoo/odoo#281721
Image edit and clear buttons now remain visible over light images and in dark mode. Their round shape is also applied consistently across the standard image, avatar, and editor variants, making image management clearer for users.
Original PR description
Before this commit, the edit and clear buttons overlaying an image field sat on a near-white chip that vanished over pale pictures, and that dark mode turned into the same grey as everything around it. Whether you could see them came down to the picture behind them. They were also slightly oval rather than round, because the sizing they relied on only applied to the plain image widget and never reached the avatar or editor variants. This commit makes them readable over any image in both light and dark mode, and hands the shape to the shared circle button style so every variant gets it. task-6578284 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#288746
This fixes portal dashboard cards so counters are not shown on the '/my' page when they are not relevant. Business users see a cleaner, more accurate portal experience without misleading numbers on cards.
Original PR description
Purpose ======= Fix the portal card counters which are displayed on the '/my' page even though they shouldn't. Specification ============= Following odoo/odoo#270066 , the precise discuss count have…
Purpose ======= Fix the portal card counters which are displayed on the '/my' page even though they shouldn't. Specification ============= Following odoo/odoo#270066 , the precise discuss count have been displayed on its portal card in a danger badge. The badge is declared in the template with the 'd-none' class, then the JS interaction calls the '/my/counters' route to get the counters and removes this 'd-none' class if the counter is > 0 and if the counter/card should be displayed. The issue is that this 'd-none' class is removed from the 'documentsCounterEl' element which is not necessarily the expected discuss badge. If the card is not the discuss one, the element selector matches the counter meant to be displayed on the card when the portal entry is an 'alert'. Removing the 'd-none' in this case results in cards having their count displayed on them for no reason (they're not alerts nor discuss badge). => Making sure the 'documentsCounterEl' element is the expected 'badge' before removing its 'd-none' class. Task-6584207 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#290238
Maintenance request statuses now show as circular indicators in the card-style request view instead of rounded labels. This restores the intended visual cue, making request states easier to scan and consistent with the app design.
Original PR description
Issue Before this Commit: ======================== The maintenance request state is displayed as a rounded pill in the kanban view instead of a circular indicator. <img width="500" height="150"…
Issue Before this Commit: ======================== The maintenance request state is displayed as a rounded pill in the kanban view instead of a circular indicator. <img width="500" height="150" alt="image" src="https://github.com/user-attachments/assets/84fe84ef-ff58-4873-bb73-1f375774f149" /> Steps to reproduce ======================== 1. Open the Maintenance app. 2. Open Maintenance Requests. 3. Observe the maintenance request state. The state is displayed as a rounded pill instead of a circular indicator. Cause of the issue: ======================== In the [PR](https://github.com/odoo/odoo/pull/260098), the view type of maintenance requests was changed from `kanban` to `cards`, but the `MaintenanceRequestStateSelection` component still checks for `kanban` in its `isKanbanOrMobileView` method. As a result, it uses the `rounded-pill` styling instead of the circular styling. After this Commit: ======================== Update the condition to correctly check `card` as the view type, so the maintenance request state is displayed as a circular indicator. <img width="500" height="150" alt="image" src="https://github.com/user-attachments/assets/e01b5898-2ec3-45b3-aa79-f7ed7c8e9e9f" /> Forward-Port-Of: odoo/odoo#290048 Forward-Port-Of: odoo/odoo#289132
The unread message banner in Discuss is now less visually intense when using dark theme. This reduces distraction for users while keeping the banner visible and useful.
Original PR description
Warning alert are very catchy in dark theme, compared to white theme. This made the unread banner far too present in Discuss app in dark theme. This commit mixes the color of alert-warning with black, so that the color matches more closely to the old color palette and matches well with a dark version of the white theme variant. <img width="1968" height="601" alt="Screenshot 2026-09-22 at 18 03 53" src="https://github.com/user-attachments/assets/f4d8847b-29f9-4252-b915-d8a883e43079" /> Forward-Port-Of: odoo/odoo#289983
This update stabilizes an internal Mail test by freezing the test clock at the right moment. It helps prevent false failures in automated testing, improving confidence in release validation without changing user-facing behavior.
Original PR description
Before this commit, the test "CallDebrief: active call uses the current time" could fail on a loaded runbot: ``` [toBeCloseTo] expected values to be close to the given value > Expected: 50 > Received: 49.760 ``` This happens because the mocked date keeps running with the real clock, from the mockDate call at the start of the test until the widget reads DateTime.now() to compute the call duration. The 0.1 margin on the segment width allows less than half a second between the two. This commit fixes the issue by mocking the date and freezing the time right before opening the view, once start() no longer needs the timers. https://runbot.odoo.com/odoo/error/947256 Forward-Port-Of: odoo/odoo#290183
The channel invitation window in Discuss has been visually adjusted to better match the current Frost design. Users will see a cleaner copy-link button, better grouped search suggestions, clearer hover feedback, aligned search icons, and tighter spacing around the invite link.
Original PR description
To match frost design: - copy link button is circled button - suggested items in search are in a single rounded container - hover effect on selected item is clearer - search icons are now alined with search - reduced spacing between "Invite" button and invitation link <img width="2576" height="1066" alt="master-channel-invitation-copy-button-aku" src="https://github.com/user-attachments/assets/a99adb12-7f36-4530-a0eb-19cc90295f37" /> https://github.com/odoo/enterprise/pull/132692 Forward-Port-Of: odoo/odoo#288961
This fix improves how action buttons are arranged in the Point of Sale product screen modal, especially on tablets and screens with unusual proportions. It prevents buttons such as Cancel from appearing awkwardly on their own row or overflowing, making the interface more reliable and easier to use in both portrait and landscape views.
Original PR description
This PR fixes the issue of the Cancel button floating on the last row when the buttons wrap and other overflowing issues. Before this PR, we were targetting the screen's orientation and max-height,…
This PR fixes the issue of the Cancel button floating on the last row when the buttons wrap and other overflowing issues. Before this PR, we were targetting the screen's orientation and max-height, which worked in general but still let a few layout issues through. On tablets the buttons are large and squarish for better touch usability (which has the double function of leaving plenty of space for translations), this makes fitting them within the modal container without overflowing a bit more complex. Instead, we target ranges of the aspect-ratio of the screen and adjust the buttons squarish aspect-ratio and the number of grid columns accordingly. By controlling the grid's columns we're able to tell the last button (the Cancel button) to stretch to full width when needed as well as having a more balanced layout in both landscape and portrait views. task-6235164 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265711
Search fields in Odoo Mail now look clearer and more consistent, with better spacing, aligned action buttons, and improved labels. This makes conversation search and related mail actions easier to recognize and use without changing core behavior.
Original PR description
- space out the search icon and placeholder; - reserve the clear icon room only when it shows; - align primary buttons with the search input height; - label the messaging menu search "Search Conversation"; - make the messaging menu action icons fixed-width. <img width="1408" height="322" alt="search-primary-button-before-after" src="https://github.com/user-attachments/assets/618d3f2c-7aa9-45c2-a6d4-bb46f43da2bf" /> Forward-Port-Of: odoo/odoo#290092
Mail message and composer action buttons no longer show an extra outline when active. This reduces visual clutter and prevents nearby action buttons from appearing to overlap, making the interface cleaner and easier to read.
Original PR description
Active message and composer actions no longer show a button outline. Their opacity already marks them as active, so the outline was only visual noise, and it made adjacent message actions overlap. <img width="1438" height="638" alt="Screenshot 2026-09-23 at 00 49 39" src="https://github.com/user-attachments/assets/58fd104b-44f4-414d-99c8-f215cc15046c" /> Forward-Port-Of: odoo/odoo#290101
Accounting journal codes are no longer limited to seven characters, preventing errors when translated labels become longer in some languages. This removes an old generic restriction so businesses can use localized accounting setups without unexpected validation failures.
Original PR description
Since 20.0, the ORM will raise if the size of a Char field is not respected [1]. Since Journal's field "code" is translated, it can overflow its size of 7 [2] depending on the language. We decide to remove the size constraint on code, since it seems more like a legacy, unjustified constraint. If a country really has a legal constraint on it, it should be handled in the l10n module, not as a generic random constraint. [1]: https://github.com/odoo/odoo/commit/022578d4d6f7406a01a5af7da063e9813bf2ff9b [2]: https://github.com/odoo/odoo/blob/ba824ab3a22a28212171f402e6a54b19e2f847e5/addons/account/models/account_journal.py#L88 Reported by https://github.com/odoo/odoo/pull/289435. Fixes https://github.com/odoo/odoo/issues/289179. Forward-Port-Of: odoo/odoo#289871
This fix prevents a failed permission check on one editor-related channel from stopping all client subscriptions. Users can continue receiving updates from allowed channels, while channels they cannot access are quietly skipped.
Original PR description
`_build_bus_channel_list` should never raise. Otherwise, the entire request is aborted, meaning the client fails to subscribe to *all* channels, including completely unrelated channels. Instead, if a client do not have permission to subscribe to a channel, the channel should just be skipped. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#287142
This fixes how journal item reconciliation behaves when an account is not set up for payment reconciliation. The system now uses the company currency and avoids creating unnecessary exchange difference entries, helping keep accounting records accurate.
Original PR description
When reconciling journal items, if one of them is using an account with no payment reconciliation, then the currency of the reconciliation should be the company currency regardless of which currency was used on the items. Also, in that case, no exchange difference entry should be created. task-6582723 Forward-Port-Of: odoo/enterprise#132199
The timesheet timer now prefills with the most recently visited task instead of being blocked by an untouched draft. This prevents employees from accidentally logging time on the wrong task and also supports non-billable tasks when timesheets are allowed.
Original PR description
1. Open a task and open the timer from the systray -> it is prefilled with that task 2. Close the systray, open another task and open the timer again -> it is still prefilled with the first task 3. Open a task, open the timer and click "Create" -> the empty form taking over is prefilled with the task that was just timesheeted Closing the systray saves the form as a draft even when nothing was typed in it, and a draft takes precedence over the task last visited. With this PR, a form is only kept as a draft once the user has edited it, and creating a timesheet consumes the prefill so that the form taking over starts empty. Reopening the systray still prefills the task last visited. Task-6580476 Forward-Port-Of: odoo/enterprise#132176
Opening the lot or serial number generation window no longer crashes when a product has no numbering sequence configured. This helps warehouse users continue barcode operations smoothly even when product setup is incomplete.
Original PR description
When opening the generate lot dialog, there's a traceback when there is no sequence associated with the product. This commit adds the necessairy checks Forward-Port-Of: odoo/enterprise#131917
This fix ensures Colombian electronic invoice XML notes contain only the invoice Terms and Conditions, not the journal technical control key. This keeps DIAN submissions aligned with expected business content and avoids exposing an internal configuration value in customer-facing invoice data.
Original PR description
**Steps to reproduce:** - Install the `l10n_co_dian` module and switch to the CO Company. - Disable `Test environment` and enable `DIAN Demo Mode` in the invoicing settings. - Set a `Technical…
**Steps to reproduce:** - Install the `l10n_co_dian` module and switch to the CO Company. - Disable `Test environment` and enable `DIAN Demo Mode` in the invoicing settings. - Set a `Technical control key` on the `Customer Invoices` journal. - Create and confirm an invoice with Terms and Conditions. - Send the invoice to `DIAN`. - Open the generated XML file and observe the `cbc:Note` tag. **Observation:** The `Note` tag contains the `technical control key`. **Expected behavior:** The `Note` tag should only contain the Terms and Conditions value from the invoice. (Confirm with PO [1]) **Root Cause:** At [2] and [3], the code includes the `technical key` in the `Note` tag. [1]: https://www.odoo.com/mail/message/1164671931 [2]: https://github.com/odoo/enterprise/blob/a5f4bde1aa33ea7b796d7ee3f9d713a6c8ab8348/l10n_co_dian/models/account_edi_xml_ubl_dian.py#L664 [3]: https://github.com/odoo/enterprise/blob/a5f4bde1aa33ea7b796d7ee3f9d713a6c8ab8348/l10n_co_dian/models/account_edi_xml_ubl_dian.py#L1600-L1603 opw-6513843 Forward-Port-Of: odoo/enterprise#132831 Forward-Port-Of: odoo/enterprise#131495
Employees in Belgium can now choose a company bike even when they use the mobility budget. This fixes an incorrect restriction and aligns the salary package options with legally allowed benefits.
Original PR description
When you take the mobility budget, it doesn't allow you to take a company bike. This should be possible as it is legally possible Forward-Port-Of: odoo/enterprise#132567 Forward-Port-Of: odoo/enterprise#132405
Appointment calendar views now display all appointment bookings, even when the current user is not directly part of them. This restores the previous behavior and prevents teams from seeing empty or incomplete calendars after the multi-calendar update.
Original PR description
With the new multi-calendar feature, calendar views in the appointment app also used the calendar filter to show events. This proved to be a regression compared to the old view where we could see other appointments, even if the user wasn't part of it. This commit brings back this behavior by displaying all appointments. Task-6591658 Forward-Port-Of: odoo/enterprise#132742
This update prevents Odoo Studio from crashing when users create a new app and select the map view from the Views tab. It ensures the view setup opens reliably, helping users continue configuring their app without interruption.
Original PR description
In a new app in studio tab "views" ; click on map view. Before this commit there was a crash because of some props not correctly defined After this commit there is no crash Forward-Port-Of: odoo/enterprise#132783 Forward-Port-Of: odoo/enterprise#132608
This fix improves searches that exclude certain records, so teams get more accurate results when filtering out items in Helpdesk, Planning, Sales-related planning, skills reporting, and Kenyan e-invoicing product data. It helps prevent misleading lists or reports caused by negative search conditions not being applied correctly.
Original PR description
https://github.com/odoo/odoo/pull/289955 Forward-Port-Of: odoo/enterprise#132619
This update fixes several Shop Floor interface inconsistencies and adds easier access to barcode reference sheets. It helps manufacturing teams work more smoothly by making the work order screen clearer and related barcode guidance easier to find.
Original PR description
Fix some Shopfloor UI and had link to barcodes demo and action sheet. Task-6574839 Forward-Port-Of: odoo/enterprise#132566
This update adds missing component settings in Planning Field Service, Social, Social Twitter, and Web Studio. It helps prevent runtime errors that could interrupt users while working with planning views, social posts, or report editing.
Original PR description
* planning_field_service,social,web_studio This commit adds missing props declarations which cause runtime errors. Forward-Port-Of: odoo/enterprise#132795
This update corrects configuration issues that could cause internal component errors in the Knowledge article index and O-Box remote debugging tools. It removes outdated inputs and ensures required settings are provided, helping these features run more reliably without changing user workflows.
Original PR description
See commit messages for details. - Runbot [947332](https://runbot.odoo.com/odoo/runbot.build.error/947332) - Runbot [947371](https://runbot.odoo.com/odoo/runbot.build.error/947371) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/enterprise#132734
This fix removes an outdated length limit on journal codes in several import and order-processing areas. It prevents errors when translated or localized journal codes are longer than expected, helping accounting imports and platform order handling work reliably across languages and countries.
Original PR description
*: l10n_fr_fec_import, pos_platform_order Since 20.0, the ORM will raise if the size of a Char field is not respected [1]. Since Journal's field "code" is translated, it can overflow its size of 7 [2] depending on the language. We decide to remove the size constraint on code, since it seems more like a legacy, unjustified constraint. If a country really has a legal constraint on it, it should be handled in the l10n module, not as a generic random constraint. [1]: https://github.com/odoo/odoo/commit/022578d4d6f7406a01a5af7da063e9813bf2ff9b [2]: https://github.com/odoo/odoo/blob/ba824ab3a22a28212171f402e6a54b19e2f847e5/addons/account/models/account_journal.py#L88 Reported by https://github.com/odoo/odoo/pull/289435. Fixes https://github.com/odoo/odoo/issues/289179 Forward-Port-Of: odoo/enterprise#132591
A WhatsApp-related automated test was updated to match a small change in the channel invitation button. This helps keep quality checks reliable without changing the user experience.
Original PR description
The "Invite" button of the channel invitation no longer has a title attribute, as it duplicated the button label. Target it by its text instead. https://github.com/odoo/odoo/pull/288961 Forward-Port-Of: odoo/enterprise#132692
The Luxembourg reports module now uses a working download link for the FAIA schema file. This prevents failed or empty downloads when users need the required file for Luxembourg reporting compliance.
Original PR description
The old link points to a file with zero bytes. opw-6344914 Forward-Port-Of: odoo/enterprise#132582
Removed an obsolete styling override for navigation dropdown spacing that no longer affects the interface. This keeps the enterprise code aligned with the main Odoo platform cleanup and reduces maintenance without changing how users interact with the navbar.
Original PR description
d364fc78a532 reset `--Dropdown_menu-margin-y` on `.o_main_navbar` to cancel the community navbar value. Dropdown menus are rendered in the overlay container, outside of the navbar, so neither declaration applied, and the variable is removed in community. task-6589485 Requires: - https://github.com/odoo/odoo/pull/289833 Forward-Port-Of: odoo/enterprise#132727