Monday, September 7, 2026
147 changes · master
New functionality added to Odoo
Adds support for salary sacrifice in Belgian payroll so eligible employee benefits can reduce taxable and social security salary calculations. The feature caps the sacrifice based on company rules and minimum wage protections, with any excess handled as a net employee contribution; end-of-year bonus sacrifice and salary configuration flow are not included yet.
Original PR description
Look at commit messages PR to try the salary sacrifice feature Did not implement: salary config flow & end of year bonus sacrifice task-6313710
Companies using Turkish Nilvera e-invoicing can now define multiple invoice series on a single journal and apply them based on customer, invoice scenario, invoice type, exports, or credit notes. This reduces unnecessary journal setup while keeping invoice numbering aligned with different business processes.
Original PR description
In Türkiye, companies commonly use a different invoice series for each business process: invoice type, branch, or customer. A journal carries a single sequence, so getting a second series means creating a second journal purely to renumber, which inflates the configuration for no accounting reason. This commit adds an "e-Document Sequences" list on the journal. Each line pairs a series code with the invoice characteristics it applies to: customer, GİB scenario, GİB invoice type, product export invoice and credit note. When an invoice matches every condition of a line, the series code is used instead of the journal's code. task-6316156 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
Email Marketing gains reusable mailing templates, a refreshed campaign interface, and a smoother start-from-scratch workflow. Marketers can reuse successful designs, create mailing contacts from existing contacts, and choose when individual links should not be tracked.
Original PR description
## Description This PR adds new features to the `mass_mailing` app. ## Added Features The features are: - [x] adding mailing Templates: - [x] upgrade the `Mailing List` view (UI/UX) - [x] disable link tracker on demand - [x] `Start From Scratch` template: the `Drag a block...` button should open the block library - [x] `View in Browser` should be a toggle - [x] support more fonts (implement a fallback mechanism) - [x] upgrade `mailing.lists`: create `mailing.contacts` from `res_partners` (`Contacts` app). - [ ] create `dynamic lists` --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This PR adds two new modules that together implement an end-to-end TDS FVU file validation pipeline for Indian Payroll. The official Income Tax FVU utility is a Java desktop GUI application that cannot run inside Odoo directly (requires a display, slow to start, single-threaded). This PR solves that by splitting the work across two Odoo instances: - `l10n_in_tds_fvu_utility` (client) — extends Form 138, sends files, receives results. - `l10n_in_tds_validation` (server) — receives f
Original PR description
This PR adds two new modules that together implement an end-to-end TDS FVU file validation pipeline for Indian Payroll. The official Income Tax FVU utility is a Java desktop GUI application that…
This PR adds two new modules that together implement an end-to-end TDS FVU file validation pipeline for Indian Payroll. The official Income Tax FVU utility is a Java desktop GUI application that cannot run inside Odoo directly (requires a display, slow to start, single-threaded). This PR solves that by splitting the work across two Odoo instances: - `l10n_in_tds_fvu_utility` (client) — extends Form 138, sends files, receives results. - `l10n_in_tds_validation` (server) — receives files, runs the JAR headlessly, delivers results back. ───────────────────────────────────────────────────── Functional changes ───────────────────────────────────────────────────── Client (`l10n_in_tds_fvu_utility`): - add a Challan File (.csi) upload field directly on the Form 138 record; the challan is mandatory before sending. - add a "Send to TDS Server" button on the Form 138 form, visible only after the text file has been generated; sends both the `.txt` and `.csi` files to the validation server in a single call. - attach every sent file (.txt and .csi) and every received output file to the Form 138 chatter for a complete audit trail. - display a human-readable error banner when the FVU JAR rejects the filing; technical error codes are stripped and only plain-language messages from the `.err` file are shown to the user. - add a "Reset TDS" button to clear all send state, error banner, challan, and output attachments, returning the record to draft for re-sending. - add a stat button linking to all TDS output attachments once validation is complete. Server (`l10n_in_tds_validation`): - expose POST /api/tds/generate: accepts a TDS .txt file and mandatory challan .csi file, verifies the SHA-256 checksum sent by the client, enqueues the record, and immediately returns a 'queued' acknowledgment — the caller never waits for JAR execution. - process queued records in FIFO order (oldest queued_date first) via a 1-minute cron in configurable batches (default 5), so no single slow JAR run blocks the HTTP worker or other users' requests. - reclaim records stuck in 'running' for more than 10 minutes: re-enqueue up to 3 times (max_retries), then mark failed and notify the client via webhook. - retry undelivered webhooks up to 3 times via a separate 5-minute cron; add a manual "Resend Webhook" button on the server record as a fallback. - add list and form views for l10n.in.tds.validation so the server operator can monitor the queue, inspect output files, and trigger manual resets or webhook resends. ───────────────────────────────────────────────────── Technical changes ───────────────────────────────────────────────────── Client (`l10n_in_tds_fvu_utility`): - extend `l10n.in.payroll.form.138` via `_inherit` with challan file, tds_send_state, server_validation_id, tds_error_banner, and checksum fields. - implement _do_send(): SHA-256 checksum, chatter attachments, commit state=processing before HTTP call, timeout=20. - implement _parse_err_file(): ^-delimited .err → deduplicated human-readable HTML list. - add webhook controller at POST /api/tds/form138/webhook: match by server_validation_id, attach outputs, set done/failed. Server (`l10n_in_tds_validation`): - introduce l10n.in.tds.validation: FIFO queue model with states draft → queued → running → done/failed, checksum verification at enqueue, and webhook delivery tracking. - _cron_process_queued(): stuck-record reclamation, FIFO dequeue, state=running + immediate commit (race guard), FVURunner invocation. - FVURunner: per-record sandbox temp dir, Xvfb virtual display, java -jar with memory caps, output polling, 3-layer kill ladder. - seed jar_dir, batch_size, stuck_running_minutes, max_retries config params; two ir.cron records. Note: /api/tds/generate uses auth='none'; in production this should sit behind a VPN or firewall — API key auth is a planned future step. References: https://tinpan.proteantech.in/downloads/e-tds/eTDS-download-regular.html
Enhancements to existing features
Employees and payroll users now see a warning on time off records that points them to the payslip needing correction. This helps payroll teams resolve time off adjustments more directly, while removing an unnecessary payslip status field from the time off view.
Original PR description
-Warning has been introduced on the timeoff form view, to redirect to the payslip to be corrected. -"payslip_state" has been removed from the timeoff view.
Resolved issues and error corrections
The messaging menu now explicitly opens on the intended Chats tab instead of relying on fallback behavior. This prevents future tab-order changes from accidentally opening the wrong section and makes the user experience more predictable.
Original PR description
Before this commit, the systray state is inserted with `activeTab: MENU_TABS.CHATS`, a name no module defines, so the value is undefined and the state links no tab at all. This happens because each module names its own tabs, and the discuss one declares `MENU_TABS.CHAT`. The eager compute of `activeTab` hides the mistake: with no tab to keep, it falls back to the first visible tab, which is Chats whenever it is shown, as its sequence is the lowest. This commit inserts `MENU_TABS.CHAT`, so the state says which tab it opens on rather than depending on the sequences around it.
Code cleanup and technical improvements
The Indonesia QR payment module for self-ordering was renamed so it is treated as an Indonesia-specific localization. This prevents default test installations from pulling in Indonesia-related dependencies unnecessarily, reducing setup noise without changing business functionality.
Original PR description
QRIS is Indonesia's national QR payment standard and was commited here https://github.com/odoo/odoo/commit/077ea34a6765f7203222cd8329eb026336a6ac06 . Right now runbot install it and therefore all indonesian dependencies by default. This commit prefix the module by l10n_id to avoid this behavior. task-6542675
Miscellaneous changes
In order to prepare the translations for Odoo 20, we fill in the translations from saas-19.4. Meanwhile we also updated `base.pot`, which is now exportable from Runbot as well, since the manifest terms moved out. We also update `.weblate.json` with the latest changes. Related: https://github.com/odoo/enterprise/pull/130300 Related: https://github.com/odoo/design-themes/pull/1340
Original PR description
In order to prepare the translations for Odoo 20, we fill in the translations from saas-19.4. Meanwhile we also updated `base.pot`, which is now exportable from Runbot as well, since the manifest terms moved out. We also update `.weblate.json` with the latest changes. Related: https://github.com/odoo/enterprise/pull/130300 Related: https://github.com/odoo/design-themes/pull/1340
Payroll users now see a clearer warning on time off records when a related payslip needs correction, with a direct path to the payslip to update. The payroll dashboard and correction process have also been streamlined so teams can resolve time off and payslip issues more easily.
Original PR description
-Warning has been introduced on the timeoff form view, to redirect to the payslip to be corrected. -"payslip_state" has been removed from the timeoff view. -UX changes in the payroll dashboard.
The activity popover now adapts its layout depending on whether activities are scheduled. This makes the empty state clearer with a stronger call to action, while keeping lists of activities easier to read and visually polished.
Original PR description
Give the popover two distinct states instead of one rigid layout. With no activity scheduled, it shrinks to its help text and offers a primary CTA. With activities listed, it keeps its 350px width and a secondary button. Also stops the section headers' background from overflowing the popover's rounded top corners, and tints the handle to match the header it points at. task-6528195 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Manufacturing orders are now easier to use because the Unbuild action has been moved away from the main buttons, reducing confusion with resetting an order to draft. Stock transfers are also easier to find because the quick search now includes vendor names.
Original PR description
This improvement enhances the manufacturing and stock user experience by: - Moving the Unbuild button to the cog menu of the MO form view to avoid confusion with the Reset to Draft action. - Updating the Transfer quick search filter in stock.picking to also consider the vendor name, making it easier to find transfers related to a specific vendor. Task iD- 6460372 Enterprise PR: https://github.com/odoo/enterprise/pull/128087
Manufacturing users get a clearer experience in ECO approvals, planning schedules, and work order lists. The approvals section now has more room, planning opens with fewer visual distractions, and work order action buttons are sized more consistently.
Original PR description
*: quality_mrp_workorder This improvement enhances the UX by: - Extending the Approvals view in ECO stages to full width for better form visibility. - Setting Show Dependencies to false by default in the Planning Gantt view for a cleaner and less cluttered view. - Fixing the Finish button size in the work order list view to ensure consistent sizing across the list view. Task Id - 6460372 Community PR: https://github.com/odoo/odoo/pull/282715
Manufacturing order overviews now include a To Replenish toggle that shows only components still needing to be ordered. This helps users quickly focus on missing supplies by hiding unrelated operations, byproducts, and already-covered components while the filter is active.
Original PR description
Users could not quickly identify components that still needed to be ordered because the MO overview displayed them alongside all other components. Add a To Replenish toggle to the top-right control panel so users can limit the overview to components whose status is To Order. This commit's changes: - Add the To Replenish toggle to ongoing manufacturing orders - Show only components whose status is To Order when enabled - Hide operations and byproducts while the filter is enabled task-5946139 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update introduces a light user access level that automatically keeps permissions limited to lightweight groups where available. It reduces manual permission setup and helps organizations manage lower-privilege users more consistently across multiple business apps.
Original PR description
**[IMP] base: light user access rights management** Introduce the "light user" concept to optimize group assignment and privilege management. ### Technical Details * **Light vs. Regular Groups**: Groups listed by `_get_light_group_xmlids` are classified as light groups; all other groups are treated as regular groups. * **Implied Groups Automation**: `base.group_user_regular` is automatically appended to the `implied_ids` of groups (specifically those without privileges, without existing `implied_ids`, or representing the lowest privilege level within a privilege set). This logic is internal and cannot be modified or accessed by users. * **Light Group Reduction**: Selecting the light user access level triggers `_reduce_to_light_groups`, which revokes all regular groups from the user and replaces them with their corresponding light versions (when available). https://github.com/odoo/odoo/pull/285702
Odoo introduces a light user access level that automatically keeps users limited to lower-privilege groups when selected. This helps businesses manage basic user permissions more consistently and reduces the risk of assigning unnecessary access across apps.
Original PR description
**[IMP] base: light user access rights management** Introduce the "light user" concept to optimize group assignment and privilege management. ### Technical Details * **Light vs. Regular Groups**: Groups listed by `_get_light_group_xmlids` are classified as light groups; all other groups are treated as regular groups. * **Implied Groups Automation**: `base.group_user_regular` is automatically appended to the `implied_ids` of groups (specifically those without privileges, without existing `implied_ids`, or representing the lowest privilege level within a privilege set). This logic is internal and cannot be modified or accessed by users. * **Light Group Reduction**: Selecting the light user access level triggers `_reduce_to_light_groups`, which revokes all regular groups from the user and replaces them with their corresponding light versions (when available). OPW-5323371
Belgian payroll wording has been standardized so salary classifications are now consistently called salary scales across employee records, salary offers, reports, warnings, and demo data. This reduces confusion for HR users and makes payroll configuration easier to understand.
Original PR description
Harmonize the terminology used for Belgian salary scale classifications across
UI labels, views, models, salary offers, reports, data records, and test suites.
Previously, different terms ("Job Categories", "Professional Categories", and
"Category") were used inconsistently throughout the payroll configuration,
contract options, and employee views.
- Rename model `l10n_be.job.category` to `l10n_be.salary.scale`
- Rename relational field to `l10n_be_salary_scale_id` across employees, versions, and contract offers
- Rename record names in CSV data (e.g., "Category A" -> "Salary Scale A")
- Update payroll warnings, PDF reports (individual account, social balance), JS patches, and salary configurator
- Rename data, view, model, and test files to match the new nomenclature
- Update demo data and tests in dependent module `test_l10n_be_hr_payroll_account`
Task: 6475636HR documentation now uses “salary scale” instead of “job category” to match Belgian payroll terminology. This helps keep internal wording consistent and clearer for teams working with Belgian payroll processes.
Original PR description
Update method docstring and parameter examples to reference 'salary scale' instead of 'job category' to align with the Belgian payroll terminology. Task: 6475636
Odoo Discuss can now use a custom call client bundle for testing alternative video call infrastructure or server updates. If no custom bundle is active, the standard built-in client continues to be used, reducing disruption while making experimentation easier.
Original PR description
Testing alternative SFU implementations (or updating the SFU with a breaking client-server API change) currently requires replacing the bundled client in the source tree. Add a config setting to provide a custom SFU JS client bundle. The bundle is stored as an attachment and replaces the default client through an `ir.asset`. When deactivated or empty, it is the built-in static bundle that is used.
The messaging menu can now combine filters from multiple features, so users see more accurate and relevant conversations without pagination issues. It also supports context-specific tabs that stay out of the global menu and counters while still loading and counting their own content correctly.
Original PR description
See individual commits for rationale. enterprise: https://github.com/odoo/enterprise/pull/130289
Project users can now open a Time by Stage report to see how long tasks spend in each stage. This helps teams spot workflow bottlenecks and better understand where project work is slowing down.
Original PR description
- added `Time by Stage` option to open the report page - create `project.task.stage.report` for the stage time calculation --- task-5139455
Serial numbers now show their delivery date in stock and field service planning screens, making it easier for teams to see when equipment was delivered. When all delivered items are returned, the delivery date is cleared so records stay accurate.
Original PR description
- show the `delivery_date` of the serial number in the `stock.lot` form, list, and kanban views - show the `delivery_date` in `planning.slot` equipment notebook - product returns make delivery date to false if the returned quantity = the delivered one --- task-5184420
Helpdesk search screens have been reorganized and simplified to make tickets and SLA reports easier to filter and analyze. This improves day-to-day navigation for support teams without changing the underlying ticket data or workflow.
Original PR description
In this commit, we refactor and clean the search view of Helpdesk. task-6512923
The Project options menu now places “Timesheets and Planning Analysis” in a revised order. This makes the menu organization more consistent and easier for users to navigate.
Original PR description
Change the order of `Timesheets and Planning Analysis` in the project option menu --- task-5139455
This update improves how character field size limits are handled in the user interface, helping users enter data that fits expected limits. It reduces the chance of input errors or rejected exports, with a small impact focused on German reporting tests.
Original PR description
https://github.com/odoo/odoo/pull/284290
The HR app menu order has been adjusted so Fleet and Payroll appear directly after Time Off. This creates a more logical onboarding flow and helps users find related HR tools more easily.
Original PR description
Reorder menu sequence values to position Fleet and Payroll directly after Time Off while maintaining increments of 5 between bounds 185-230. Sequence changes: - Appraisals: 200 -> 190 - Attendances: 205 -> 200 - Recruitment: 210 -> 205 - Referrals: 215 -> 210 - Time off: 225 -> 215 - Fleet: 220 (unchanged, now following Time Off) - Payroll: 190 -> 225 task-6482852 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The online shop now shows out-of-stock status more accurately, only marking products as unavailable when all variants are sold out. Customers are guided to available variants when possible, and unavailable products show clearer notification and wishlist actions instead of a misleading add-to-cart option.
Original PR description
**Purpose:** Out of stock was not completely managed in eCommerce. The out of stock ribbon was not reflecting correctly the status of the partially out of stock products. The notification and…
**Purpose:** Out of stock was not completely managed in eCommerce. The out of stock ribbon was not reflecting correctly the status of the partially out of stock products. The notification and wishlists buttons were inconsistents with the rest of the features. **Specification:** Shop page: - Make the out of stock ribbon appear only if all variants are out of stock. - If a product if completely out of stock, hide the add to cart button. - If a variant is still available, select the first available variant in the configurator or when clicking on the tile to open the product page. Product page: - Make the notification button replace the Add to cart button. - Rationalise the wishlist button of out of stock products. - When clicking notify me, show form to enter email if not logged in, subscribe directly if logged in Task-6026756 See also: - https://github.com/odoo/enterprise/pull/130684 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update makes several internal improvements across Odoo's core framework, including faster access checks, better handling of cached model data, and clearer debugging information for access errors. These changes should help developers diagnose issues more easily while improving performance and reliability for users behind the scenes.
Original PR description
(see commits) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update brings Odoo's spreadsheet engine up to its latest version, including improvements that help calculations run more efficiently by limiting evaluation to valid sheet areas. It also includes internal compatibility updates that support ongoing spreadsheet reliability and maintainability.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/54a0597b26 [REL] 19.5.0-alpha.18 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/54a0597b26 [REL] 19.5.0-alpha.18 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/4f0daee34e [IMP] index: export `owlPlugins` [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/532243ce63 [REL] 19.5.0-alpha.17 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/7907b8e368 [PERF] evaluation: clip range to sheet [Task: 6483083](https://www.odoo.com/odoo/2328/tasks/6483083) https://github.com/odoo/o-spreadsheet/commit/1fe87f3046 [IMP] owl3: remove `env.getPopoverContainerRect` [Task: 6510584](https://www.odoo.com/odoo/2328/tasks/6510584) Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> Co-authored-by: Anthony Hendrickx (anhe) <anhe@odoo.com> Co-authored-by: Alexis Lacroix (laa) <laa@odoo.com> Co-authored-by: Lucas Lefèvre (lul) <lul@odoo.com> Co-authored-by: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya (rmbh) <rmbh@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@odoo.com> Co-authored-by: Rémi Rahir (rar) <rar@odoo.com> Co-authored-by: Pierre Rousseau (pro) <pro@odoo.com> Co-authored-by: Vincent Schippefilt (vsc) <vsc@odoo.com> Co-authored-by: Marceline Thomas (matho) <matho@odoo.com>
Swiss QR invoices can now be generated even when a company or customer address is missing street or building number details, since those fields are not required in Switzerland. Users are informed with a banner in the Send & Print flow and batch processing continues for other invoices if one invoice has a QR issue.
Original PR description
In Switzerland, the street and building number is not required to generate a valid QR invoice. To minimize friction, errors are no longer raised if they are missing from the address of the company or the customer during the creation of the QR Code. Instead, an info banner is now displayed in the Send & Print popup indicating to the user that the addresses of some of the customers are missing and allow the user to browse through those customers. task-4349496 opw-4317153 Forward-Port-Of: odoo/odoo#271534
The HR app menu order has been adjusted so new companies see related onboarding areas in a more logical sequence, with Fleet and Payroll placed directly after Time Off. This makes navigation clearer during setup and supports a smoother onboarding experience for business users.
Original PR description
Reorder menu sequence values to position Fleet and Payroll directly after Time Off while maintaining increments of 5 between bounds 185-230. Sequence changes: - Appraisals: 200 -> 190 - Attendances: 205 -> 200 - Recruitment: 210 -> 205 - Referrals: 215 -> 210 - Time off: 225 -> 215 - Fleet: 220 (unchanged, now following Time Off) - Payroll: 190 -> 225 task-6482852
The AI feature now records a warning when a required markdown component is missing. This helps administrators identify configuration issues faster and reduces time spent diagnosing why AI-generated content may not render as expected.
Accounting reports now once again let users filter for unreconciled items while keeping the existing reconciliation date logic. This makes it easier for finance teams to review open partner balances accurately for a selected reporting date.
Original PR description
Restore the unreconciled filter while continuing to use the recon_date mechanism, applying the date to date_to. task-none
Belgian payroll now handles worker terminations with updated termination fee calculations and no employer holiday pay. It also generates the dedicated holiday attestation report for workers, helping payroll teams produce the correct departure documents and amounts.
Original PR description
1. No holiday pay from the employer. 2. Generate the delicated holiday attest report for wokers. 3. Update termination fees. Task-6006190
Odoo now stops silently shortening text that is longer than an allowed field size and instead relies on database validation to reject it clearly. This improves data accuracy and makes configuration or import issues easier to detect, with country codes now explicitly limited to the standard two-letter format.
Original PR description
Do not trim the value silently when storing the value in cache. postgres already enforces the size when writing values, let it enforce that constraint. This avoids silently truncating the value. The size attribute is not deprecated as it is used for UI. https://github.com/odoo/enterprise/pull/130315 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The gift card design has been refreshed to use space more effectively and stay readable in dark mode. The related PDF layout is also adjusted, and mail previews in the chatter get more room for a clearer customer-facing presentation.
Original PR description
This PR redesigns the gift card template by improving the space utilization and adding a white background to enhance readability on dark mode. It also - slightly modifies the layout of the related…
This PR redesigns the gift card template by improving the space utilization and adding a white background to enhance readability on dark mode. It also - slightly modifies the layout of the related PDF - increases the minimum width to provide more space for the mail preview in the chatter. task-6246180 | Before | After | |--------|--------| | <img width="616" height="779" alt="Screenshot 2026-06-25 at 10 53 22" src="https://github.com/user-attachments/assets/b7f05c43-aaaa-4f4f-ba5b-fa93f4aaaad2" /> | <img width="504" height="595" alt="Screenshot 2026-06-25 at 10 25 22" src="https://github.com/user-attachments/assets/19bca54b-923a-44d7-9c08-3901ff08a532" /> | |--------|--------| | <img width="448" height="720" alt="Screenshot 2026-06-02 at 10 43 53" src="https://github.com/user-attachments/assets/d5fed6d0-1d05-44a2-9bc8-090259a10291" /> | <img width="555" height="721" alt="Screenshot 2026-06-25 at 10 26 34" src="https://github.com/user-attachments/assets/8e26db94-d654-4d18-8e34-8bee277a9f44" /> | |--------|--------| | <img width="798" height="884" alt="Screenshot 2026-06-25 at 10 54 39" src="https://github.com/user-attachments/assets/54bf2940-988c-4754-8677-19bc980a6684" /> | <img width="790" height="856" alt="Screenshot 2026-06-25 at 10 26 52" src="https://github.com/user-attachments/assets/f2ca78d5-97f8-456d-9416-fbd2f680b013" /> | --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Visitors who sign in during an active live chat can now keep the same conversation instead of starting over. This improves the customer support experience by preserving ongoing and previous chat access after login, including cases where extra authentication is required.
Original PR description
*=base, mail, portal, website_livechat Before this commit, when a visitor logged in while an active livechat session was ongoing, the session was lost and the user had to start a new one. Once logged in, access is checked on `partner_id` and no longer on `guest_id`. Add a post-session-login hook that runs only after authentication is fully finalized, including MFA. im_livechat uses this hook to replace the guest members of pinned livechat sessions with the logged-in partner. This allows visitors to continue active sessions and access previous ones. When a guest is present in the user context, both the user and guest are sent to the client so that guest messages continue to be recognized as self-authored after login. task-[3957100](https://www.odoo.com/odoo/project/1519/tasks/3957100)
Belgian payroll calculations now reduce payslip amounts based on time credit, parental time off, and partial incapacity while keeping the employee's contractual wage unchanged. This improves accuracy for regular pay, holiday-related calculations, and reporting by reflecting actual working time across fixed and variable schedules.
Original PR description
**Time Credit Work Entries :-** . LEAVE300 (Credit Time) . LEAVE301 (Parental Time Off) . LEAVE281 (Partial Incapacity) ### Regular Pay :- **1. Wage proration for time credit** The `wage proration`…
**Time Credit Work Entries :-**
. LEAVE300 (Credit Time)
. LEAVE301 (Parental Time Off)
. LEAVE281 (Partial Incapacity)
### Regular Pay :-
**1. Wage proration for time credit**
The `wage proration` applies only to the payslip calculation, not to the employee's contractual wage, the employee's full-time contractual wage remains unchanged. The wage displayed on the employee's version remains the original amount agreed in the contract, where **The proration is applied only when calculating the worked days and corresponding amounts on the payslip**. This ensures that the payslip reflects the employee's actual working time while preserving the contractual wage as the reference amount.
The used range to calculate the proration ratio depends on the schedule type :-
_. Fixed Calendars:_ The proration ratio is computed using a standard 1-week period (Monday to Sunday) from the attendance schedule, as fixed schedules repeat weekly.
> Fixed Calendar Example (1-Week):
> Schedule: 4 working days (30.4h) + 1 time credit day (7.6h) = 38h total schedule
> Calculation range: 1 week
> Proration ratio: $\frac{30.4\text{ actual working hours}}{38.0\text{ total schedule hours}} = 0.80$.
> Contractual Wage: €5,000 (Unchanged).
> Prorated Payslip Amount: $€5,000 \times 0.80 = €4,000$.
_. Variable Calendars:_ The proration ratio is computed over the entire target evaluation period to accurately capture work entries, taking the full month for a monthly payslip or the full 3-quarter/3-month period for DMFA reporting.
> Schedule: Alternating shifts across a monthly payslip period totaling 152 total scheduled calendar hours, of which 38 hours are marked as time credit and 114 hours are actual working hours.
> Calculation range: Full calendar month (e.g., 1st to 30th/31st).
> Proration ratio: $\frac{114\text{ actual working hours}}{152\text{ total schedule hours}} = 0.75$.
> Contractual Wage: €5,000 (Unchanged).
> Prorated Payslip Amount: $€5,000 \times 0.75 = €3,750$.
Ex: If an employee has a contractual wage of €5,000 and their schedule includes time credit:
Employee/contract wage: €5,000 → remains unchanged
Basic wage used as the contractual reference: €5,000 → remains unchanged
Payslip worked-days amount: prorated according to the actual working time
This distinction is important because time credit changes the amount paid for the payroll period, but it does not change the employee's underlying contractual full-time wage.
**2. Version Work Time Rate**
The `work_time_rate` is computed at the employee version level, where the time-credit situation belongs to the employee's version.
The existing behavior for flexible/variable calendars is preserved, **where currently the work_time_rate not computed for variable calendars and the user is expected to enter the appropriate work_time_rate manually for the variable calendars, So the overidden work_rime_rate computation deals with the `credit_time_fixed_calendars`**
For fixed calendars with time credit, the computation is handled specifically for the employee version:
. Only versions flagged with l10n_be_time_credit and using a fixed calendar are handled by the custom computation.
. The employee's reference calendar is used to determine the full-time weekly hours.
. The calculation considers both, regular working attendances & attendances marked as time credit.
The time-credit hours are therefore included when determining the employee's work_time_rate, **But Importantly, the actual working hours of the resource calendar are not changed.**, where The time-credit attendances are included only for the purpose of calculating work_time_rate. They are not treated as actual working hours, and hours_per_week continues to represent the employee's effective working hours without the time-credit period.
Ex: For a full-time reference calendar of 38 hours:
Actual working hours: 30.4h/week
Time-credit hours: 7.6h/week
Hours considered for work_time_rate: 30.4 + 7.6 = 38h
work_time_rate: 100%
Actual working hours remain: 30.4h/week
-----
### Double Holiday :-
The Double Holiday Pay calculation requires special handling for time-credit periods because two different rates need to be considered:
. The **computed work_time_rate** that used to normalize the wage "include credit_entries"
. The **effective/real work_time_rate** used to determine the assimilated months "not include credit_entries""
The used wage is the version wage itself that's not prorated. The calculation first uses the full contractual wage **(so no need to change the wage on the tests)** and divides it by the version's current computed work_time_rate. This is important for time-credit versions because their computed work_time_rate can include the time-credit attendances.
However, when calculating the _double_holiday_assimilated_months, the time-credit periods are treated differently. The calculation uses the effective working-time rate, where regular time-credit entries are not considered as working time. The exception is `LEAVE281 (Partial Incapacity),` which is considered in the assimilated-month calculation and therefore contributes with its corresponding rate.
Ex: An Employee works with wage €2,500
. January → June with Normal Schedule
. July → September with 4/5 Partial Incapacity (LEAVE281)
. October → December with 4/5 Credit Time (LEAVE300)
The employee's version wage remains €2,500 throughout the calculation and the used work_time_rate for the wage will be the current computed work_time_rate which will be 1.0
The Double Holiday Pay calculation can therefore be represented as:
€2,500 / 1.00 × [(6 × 1.0 / 12) + (3 × 1.0 / 12) + (3 × 0.8 / 12)]
. For the wage normalization: the computed work_time_rate of the relevant version is used. This rate can include time-credit attendances.
. For _double_holiday_assimilated_months: the calculation uses the effective/real working-time rate for each period. Regular time-credit (LEAVE300) is therefore reflected as 80%, while LEAVE281 (Partial Incapacity) is treated as an assimilated period and remains at 100% in this example.
check:-
```
def _l10n_be_get_paid_double_holiday()
def _compute_double_holiday_assimilated_months()
```
-----
### Eco Voucher :-
The Eco-voucher calculation depends directly on the employee version's work_time_rate.
The voucher amount is therefore automatically updated when the work_time_rate changes. This is particularly important for time-credit versions, because the work_time_rate now correctly represents the employee's contractual occupation rate, including the relevant time-credit periods.
This means that a time-credit version does not necessarily result in a reduced Eco-voucher entitlement. In particular, when the employee is on a reduced working schedule but the reduction is entirely due to time credit, the computed work_time_rate can remain at 100%, because the time-credit periods are included when calculating the rate.
Ex: An employee is entitled to a maximum of €250 in Eco-vouchers and has the following situation during the reference period:
01/06/2020 → 31/10/2020: Full-time schedule → work_time_rate = 100%
01/11/2020 → 31/05/2021: 3/5 schedule with Tuesday and Wednesday represented as credit-time entries.
Although the employee only has 22.8 actual working hours per week, the two non-working days are explicitly represented as time credit. Therefore, for the purpose of the employee version's work_time_rate, the time-credit hours are included and the rate remains 100%.
The Eco-voucher calculation consequently uses: €250 × 100% = €250
110 valid working days during the full-time period, out of 261 scheduled days.
82 valid working days during the 3/5 time-credit period, out of 157 scheduled days, after excluding 9 unpaid-time-off days.
Therefore: €250 × 110 / 261 + €250 × 82 / 157 = €235.94
This confirms that time credit does not incorrectly reduce the Eco-voucher amount simply because the resource calendar contains fewer actual working hours. The employee's work_time_rate correctly remains 100% when the missing hours are accounted for as time credit.
check:-
`def _get_eco_vouchers_amount(self, get_explanation=False):
`
-----
### Representation Fees :-
The REP.FEES calculation depends directly on the employee version's work_time_rate. Therefore, for time-credit versions, the newly computed work_time_rate is automatically taken into account when determining the amount.
For time-credit versions, the computed rate includes the time-credit hours. Therefore, a 4/5 schedule with one full day of time credit has a work_time_rate of 100% (the 4/5 worked hours + the 1/5 time-credit hours represent the full reference schedule). As a result, the existing representation-fee proration logic is not triggered, and the full representation-fee amount is maintained.
check :-
`def _get_representation_fees(self, localdict):
`
-----
### DMFA :-
The DMFA declaration requires two separate considerations for time credit:
**. Working days,** where the employee's days_per_week is preserved and the time-credit attendances are not considered as actual working days.
This is important because the time-credit hours may be included when determining the employee's work_time_rate, but they must not be reported as worked days in the DMFA declaration, So the time credit can affect work_time_rate, but it does not create additional working days for DMFA.
**. Termination contribution type,** The contribution type is determined based on the employee's yearly salary, which is accumulated from the amounts reported on the payslip worked-days lines, The resulting yearly salary is compared against the configured salary thresholds to determine the appropriate contribution type.
Because the yearly salary is based on the actual amounts coming from the payslip worked-days lines, a time-credit period can reduce the yearly salary used for this calculation.
As a result, the employee's contribution type can legitimately move to a lower category.
check:-
```
DMFAWorkerContribution() __init__ class
yearly_salary = payslips[0]._l10n_be_get_termination_yearly_salary()
```
-----
task-5126195Field Service planning now supports an additional Urgent priority for shifts, giving teams a clearer way to flag work that needs immediate attention. The website request form also adds a Minor Impact option, helping businesses capture issue severity with more precision from the start.
Original PR description
This PR adds a new "Urgent" priority level in Field Service shifts, and a new "Minor Impact" level in the website form, to allow more granularity. Task-6486321
Subscription users can now add recurring lines using only a description, without first creating a dedicated product. These lines are included in invoicing, renewals, upsells, plan counts, and recurring revenue metrics, while existing product-based subscription lines keep their current behavior.
Original PR description
Before this commit: Subscription lines needed a product. Lines with no product were not treated as recurring, so invoicing, renew, upsell, plan counts, and MRR ignored them. After this commit: A line…
Before this commit: Subscription lines needed a product. Lines with no product were not treated as recurring, so invoicing, renew, upsell, plan counts, and MRR ignored them. After this commit: A line with only a description on a subscription with a plan is recurring. It can be invoiced, renewed, upsold (with prorata when prepaid), counted on the plan, and included in MRR. Impact: Users can build subscriptions without creating a product for every line. Product lines keep the same behavior as before. Performance: Profiler on Subscription Report (list), product only dataset on master vs this branch (2000 subscriptions) Main report query (sale_subscription_report ... LIMIT 80): - master: 58.97 ms - this branch: 59.52 ms No meaningful difference on that path. Flame graphs: Current master- <img width="1920" height="1002" alt="image" src="https://github.com/user-attachments/assets/c81fd63a-c9b7-4506-a4a8-8f04b1427549" /> PR Branch- <img width="1920" height="1002" alt="image" src="https://github.com/user-attachments/assets/9b750b14-739f-4b1c-b661-e915dac60c5c" /> Task id: 6410240
Belgian payroll reporting now includes employer-owned pool vehicles in quarterly ONSS/DMFA CO2 contribution declarations when they were used during the period. This helps companies report company car contributions more accurately and avoid double-counting vehicles already handled through employee payslips.
Original PR description
**Description :-** This PR adds support for declaring ONSS/DMFA quarterly CO₂ contributions for pool vehicles (vehicles owned by the employer that are not assigned to am employee on a contract, but…
**Description :-** This PR adds support for declaring ONSS/DMFA quarterly CO₂ contributions for pool vehicles (vehicles owned by the employer that are not assigned to am employee on a contract, but are used during the period). According to Belgian social security (ONSS) regulations, CO₂ fees must be paid for all company vehicles used during the quarter: . Assigned Company Cars: CO₂ fees are calculated and declared directly via employee monthly payslips. . Pool Cars: Must be declared at the employer level for any month in which they had active assignment/driver logs (fleet.vehicle.assignation.log) and were not already declared on an employee payslip. **Implementation :-** . Vehicles declaration on the DMFA (_compute_vehicle_ids) Retains all active vehicles with valid license plates that have driver assignment logs during the DMFA quarter. Ensures eco-friendly and pool vehicles appear under the XML <CompanyVehicle> declaration block. . Month-by-Month Vehicles Contribution (_get_vehicles_contribution) Evaluates the DMFA quarter on a per-month basis rather than applying a static quarterly multiplier. Prevents double-counting by excluding vehicles already charged via an employee payslip for a specific month (covered_vehicle_ids). Dynamically checks driver log date overlaps (date_start and date_end) per month to properly handle mid-quarter acquisitions or transitions. Evaluates CO₂ indexation parameters historically per month by passing co2_fee_date in the context (vehicle.with_context(co2_fee_date=current_month)._get_co2_fee(...)). **Example :-** > CAR-001 (Diesel, CO₂=120): ((120 * 9 - 600) / 12) * (181.93 / 114.08) * 2.75 = 175.42 > CAR-002 (Gasoline, CO₂=100): ((100 * 9 - 768) / 12) * (181.93 / 114.08) * 2.75 = 48.24 > CAR-003 (Diesel, CO₂=110): ((110 * 9 - 600) / 12) * (181.93 / 114.08) * 2.75 = 142.53 > TEST (Class Default Car): = 33.22 > Payslips CO₂ Fees: > CAR-002 on Employee Payslips (Jan & Feb): 48.24 * 2 = 96.48 > Pool Cars Monthly CO₂ Fees (Iterating Jan, Feb, Mar): > > January: > CAR-001: 175.42 > TEST: 33.22 > Subtotal Jan: 208.64 > > February: > CAR-003: 142.53 > CAR-001: 175.42 > TEST: 33.22 > Subtotal Feb: 351.17 (Cumulative pool fees: 559.82) > > March: > CAR-003: 142.53 > CAR-001: 175.42 > CAR-002: 48.24 > TEST: 33.22 > Subtotal Mar: 399.41 (Cumulative pool fees: 959.23) > > Therefore, Total Vehicles Contribution: 96.48 (payslips) + 959.23 (pool) = 1055.71 task-6147532
Belgian payroll declarations now calculate withholding-tax exemptions for eligible overtime hours and include them in the 274.XX report. This helps companies apply annual hour caps correctly across the year and gives payroll teams clearer XLS and PDF reporting, including sector-specific rules and white-cash-register settings.
Original PR description
Compute the withholding-tax exemption for overtime hours (natures 44–59) within the Belgian 274.XX declaration. Overtime worked-day lines are collected from validated payslips, bucketed by rate and sector (CP124/CP302/immovable work), and allocated to the appropriate nature codes while respecting each employee's annual hour cap. Hours already declared in earlier months of the same year are carried forward so the cap is enforced cumulatively. The exemption rate is stored as an updatable rule parameter. A white-cash-register flag on the company controls the higher cap for CP302 employees. New work-entry types, an XLS extra-hours sheet, a PDF section, and extended tests are included. Task Id: 5430988
Belgian payroll now includes the foundation for DRS declarations and supports exports for the WECH009 and WECH010 declaration types. This helps businesses prepare required social risk declarations more directly from Odoo, reducing manual reporting work and improving payroll compliance workflows.
Original PR description
Implements the base for all DRS declarations And already implements the exports for WECH009 and WECH010 task-5915160
Spanish accounting users can now choose the abbreviated accounting plan template in Odoo. This makes the appropriate reports available for companies that use this lighter version of the standard Spanish chart of accounts.
Original PR description
Description of the issue/feature this PR addresses: Add abbreviated accounting plan There is an accounting plan called abbreviated that was not there. This is very similar to full that is why it has this template as parent. Now this template can be selected and access to its reports. task-6065347
Financial reports now use the new retained earnings account category when calculating cumulative translation adjustments. This improves the accuracy and consistency of balance sheets, general ledger, trial balance, and SAF-T reporting across affected localizations.
Original PR description
This commit uses the new Equity Retained account type with average CTA. It also adds the account type in the balance sheet and in SAFT. task-6374563
This update adds an equity retained earnings account and adjusts currency translation handling in accounting reports. It helps businesses produce more accurate financial reporting, especially when consolidating or translating balances across currencies.
Original PR description
Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update prevents server connection errors when many background requests happen at the same time. It helps Odoo stay responsive during busy periods, especially for live messaging and websocket-related activity.
Original PR description
make gevent connection pool non-blocking to avoid 'The Connection Pool Is Full' error when too many coroutines are borrowing connections in gevent server. https://github.com/odoo/iap-apps/pull/1827 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#285423
Odoo now supports Turkish workflows where an e-Archive invoice is legally used as the dispatch document, avoiding a separate e-Dispatch submission. This reduces duplicate paperwork for e-commerce, marketplace fulfillment, and third-party logistics while keeping the standard e-Dispatch process available when needed.
Original PR description
Purpose: Turkish regulations allow an e-Archive invoice to serve directly as the dispatch document, eliminating the need to send a separate e-Dispatch XML. This is commonly used in e-commerce…
Purpose:
Turkish regulations allow an e-Archive invoice to serve directly as the
dispatch document, eliminating the need to send a separate e-Dispatch XML.
This is commonly used in e-commerce marketplace fulfillment or third-party
logistics scenarios.
This commit adds support for the "Invoice Serves as e-Dispatch" workflow:
- Extend `l10n_tr_nilvera_dispatch_type` on `stock.picking` with the new
option `IS_DESPATCH` ("Invoice Serves as e-Dispatch") and update its label
to "Dispatch Handling".
- When `IS_DESPATCH` is selected on linked pickings for e-Archive invoice, skip
sending separate e-Dispatch and instead inject '<cac:AdditionalDocumentReference>'
node with `<cbc:DocumentTypeCode>IS_DESPATCH</cbc:DocumentTypeCode>`
into e-Invoice XML.
- Hide the "Send GİB e-Dispatch (XML)" and "Update From GİB e-Dispatch (XML)"
buttons when Dispatch Handling is set to `IS_DESPATCH`.
- Vehicle and carrier information is not required when Dispatch Handling is
set to `IS_DESPATCH`.
- Replace the blocking warning for invoices with linked pickings but no
e-Dispatch orders with an info message, allowing the XML to be sent without
e-Dispatch information.
- Keep the existing flow when both linked delivery and e-Dispatch orders are
provided.
task-6369988Polls in Odoo Discuss now use the updated visual style, including refreshed panel colors and rounder corners. This creates a more consistent and polished experience for users when viewing or interacting with polls in conversations.
Original PR description
Since [1], discuss styling was adapted to frost. Action panel have a different color and more radius. This commit adapts the poll components to match this new styling. [1]: https://github.com/odoo/odoo/pull/285383 |Before|After| |-|-| |<img width="500" alt="image" src="https://github.com/user-attachments/assets/88b7dcce-ca30-4fb1-bc1c-7252a70b524f" />|<img width="500" alt="image" src="https://github.com/user-attachments/assets/34cae1e1-8bb7-4920-980b-45d236433e3e" />|
Belgian payroll now recalculates company car benefit-in-kind at year-end or when a contract ends, so employees are not overtaxed when their car changes during the year. If too much benefit was already taxed because of monthly minimums, the system automatically applies a regularization to correct it.
Original PR description
**Description :-** The payroll system currently applies a minimum legal yearly BIK/ATN for company cars. So even if the employee’s theoretical calculated car benefit is lower than the legal minimum,…
**Description :-**
The payroll system currently applies a minimum legal yearly BIK/ATN for company cars.
So even if the employee’s theoretical calculated car benefit is lower than the legal minimum, payroll still taxes the employee on the legal minimum.
That is correct as long as the employee keeps that same car all year,
But if later in the same year the employee changes to a another car, with a lower or a bigger BIK, In that case, the employee may already have paid too much earlier in the year because the minimum was applied month-by-month indirectly.
So, in December, or in the Month that the contract ends, must:
1. recompute the true yearly ATN
2. compare it with what was already paid
3. refund/deduct the excess if too much ATN was charged.
. Add a salary rule to calculate the regularization amount in case of employee have paid too much for the car bik, which applied in December, or in the Month that the contract ends,
**Implementation :-**
. Min legal car ATN: this's minimum yearly ATN that need to be paid.
. Yearly Theoretical ATN: This's the sum of the real BIK calculated from the car formula without applying the min legal car atn per month
. Yearly ATN paid: this's the sum of ATN paid on the payslips during the year
∴ Yearly ATN to pay = MAX( Min legal car ATN, Yearly Theoretical ATN)
∴ Regularization amount = Yearly ATN to pay - Yearly ATN paid
If +ve ,then employee paid less and owes more ATN **(not our case)**
If -ve ,then employee paid too much and need to refund
**Example :-**
min_car_atn = 1,690€ / year _(in 2026)_
car1 (Volkswagen/Golf 8) from January to June:
car_value = 38,000 €
yearly_theoretical_atn = 1,938 €/year
yearly_paid_atn = 1,938 €/year
car2 (Nissan) July to December::
car_value = 20,000 €
yearly_theoretical_atn = 1,371.43 €/year
yearly_paid_atn = 1,690 €/year
Calculations:
∵ monthly_car_atn is calculated based on the month calendar days so need to get the car covered assignment on days
∵ car1 covered_days = 181 days
∵ car2 covered_days = 184 days
∴ Yearly Theoretical ATN = 1,938 * (181 / 365) + 1,371.43 * (184 / 365)
= 1,652.39 €
∴ Yearly ATN to pay = Max(min_legal_car_atn, yearly_theoretical_atn)
, where it's the final ATN that should have been paid after applying the legal minimum.
= Max(1,690, 1,652.37) = 1,690 €
∵ Yearly ATN paid _(payslips)_ =
car1 -> (1,938/365) * (31 + 28 + 31 + 30 + 31 + 30) = 961.035616438 €
car2 -> (1,690/365) * (31 + 31 + 30 + 31 + 30 + 31) = 851.945205479 €
= 1,812.98 €
∴ Regularization amount = yearly_atn_to_pay - yearly_atn_paid
= 1,690 - 1,812.97
= -122.97 €
**∴ Need to refund 122.97 € to the employee**
**Example :-**
min_car_atn = 1,690€ / year _(in 2026)_
Car 1 (Corolla) Jan-Jun:
Yearly Theoretical ATN = 1,748.57€
Yearly Paid ATN = 1,748.57€
Car 2 (Clio) Jul-Nov:
Yearly Theoretical ATN = 1,371.43€
Yearly Paid ATN = 1,690€
>>The contract end at 30th November
Calculations:
∵ monthly_car_atn is calculated based on the month calendar days so need to get the car covered assignment on days
∵ car1 covered_days = 181 days
∵ car2 covered_days = 152 days
∴ Yearly Theoretical ATN = 1,748.57 * (181 / 365) + 1,371.43 * (152 / 365)
= 1,438.215 €
∵ The regularization will be applied till the contract end not the full year, so the min_legal_car_atn will be prorated
∴ min_atn_prorated = 1,690 * ((181 + 152) / 365)
= 1,541.8356 €
∴ Yearly ATN to pay = Max(1,541.8356, 1,438.215) = 1,541.8356 €
∵ Yearly ATN paid (payslips) =
car1 -> (1,748.57/365) * (31 + 28 + 31 + 30 + 31 + 30) = 867.11 €
car2 -> (1,690/365) * (31 + 31 + 30 + 31 + 30 + 29) = 571.12 €
= 1,570.87 €
∴ Regularization amount = 1,541.8356 - 1,570.87
= -29.03 €
∴ Need to refund 29.03 € back to the employee
**Tests :-**
. Payslip Simulation for December & Termination Tests:
Updated all test cases covering December payslip computations and mid-year contract terminations
(e.g., test_274_declaration_december, test_end_of_contract, test_simple_n_holiday_pay_recovery_higher_salary)
to ensure that fully validated payslips exist for all preceding months of the active fiscal year, where The `ATNCARREGUL` salary rule computes regularization by inspecting historical payslips (_get_line_values / cumulative paid BIK from January up to the current month), so December or exit payslips in isolation without prior validated payslips skews the total paid BIK (atn_paid_before_current_payslip), which does not accurately reflect a real-world payroll state.
check:-
`def _get_holiday_pay_recovery()
`
. Updated Assertions (M.ONSS):
Adjusted expectations for year-to-date-dependent lines, for special ONSS contributions (M.ONSS) across these specific tests. **Because previous months' payslips are now added, processed and validated sequentially, which reflect exact real-life behavior.**
check:-
`def _l10n_be_get_special_social_contribution()
`
. Updated 274_xx december declarations
Make sure that the payslips are computed and validated **sequentially**, where all payslips from January through November is computed first then December payslips,
Before M.ONSS computed for December first which leads to Zero values, that makes taxable_amount_10 & pp_amount_10 not correct, **But now payslips are now processed and validated sequentially, which reflect exact real-life behavior.**
check:-
`def _compute_line_ids(self): "l10n_be_274.xx"
`
`def _l10n_be_get_special_social_contribution()
`
-----
task-6197625The salary configurator now prevents employees or candidates from selecting both a company car rental option and reimbursement for using a private car. When one option is selected, the other is reset and disabled, helping avoid incompatible benefit combinations and payroll mistakes.
Original PR description
In order to safe gaurd from employees (or candidates) from selecting both options for renting a company car and getting reimbursed for their private cars, the salary configurator now resets and disables one of the benefits if the other is selected. Task: 6515172
Payroll screens and reports now use the clearer term "Payslip Adjustment" consistently instead of "Salary Adjustment". The related forms and list views have also been simplified, making payroll adjustments easier for users to understand and manage.
Original PR description
- Updated all instances of "Salary Adjustment" to "Payslip Adjustment" across models, views, and reports for consistency. - simplify UI/UX across all form, list views Task: 6416223
Odoo no longer uses database-level text length limits for character fields, avoiding cases where values could be silently shortened and later produce confusing search or filter results. Length limits can still guide the user interface, while important business rules such as two-letter country codes are enforced explicitly with clearer validation messages.
Original PR description
Having a size of varchar is leading to subtle inconsistencies: silently truncating the value. For example, if size=2, you could insert "ABC" and a search with "ABF" would match that record, but filtering would match nothing. The property was already marked as deprecated. This change removes it. In terms of storage, this has no impact. https://github.com/odoo/enterprise/pull/129766 https://github.com/odoo/upgrade/pull/11134 https://github.com/odoo/upgrade-util/pull/505 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update brings Odoo's spreadsheet component up to the latest version. It improves spreadsheet calculation performance by limiting evaluations to relevant sheet ranges and includes internal compatibility updates that help keep the feature reliable.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/532243ce63 [REL] 19.5.0-alpha.17 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/532243ce63 [REL] 19.5.0-alpha.17 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/7907b8e368 [PERF] evaluation: clip range to sheet [Task: 6483083](https://www.odoo.com/odoo/2328/tasks/6483083) https://github.com/odoo/o-spreadsheet/commit/1fe87f3046 [IMP] owl3: remove `env.getPopoverContainerRect` [Task: 6510584](https://www.odoo.com/odoo/2328/tasks/6510584) Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> Co-authored-by: Anthony Hendrickx (anhe) <anhe@odoo.com> Co-authored-by: Alexis Lacroix (laa) <laa@odoo.com> Co-authored-by: Lucas Lefèvre (lul) <lul@odoo.com> Co-authored-by: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya (rmbh) <rmbh@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@odoo.com> Co-authored-by: Rémi Rahir (rar) <rar@odoo.com> Co-authored-by: Pierre Rousseau (pro) <pro@odoo.com> Co-authored-by: Vincent Schippefilt (vsc) <vsc@odoo.com> Co-authored-by: Marceline Thomas (matho) <matho@odoo.com>
Copying existing attachments is now faster because the system reuses known file information instead of recalculating it. This reduces waiting time when duplicating large files and improves performance for workflows that copy attachments often.
Original PR description
Do not recompute the checksum and lookup indexed content if we copy an already known file.
Creation of an attachment of 100Mo takes approximately 3s. This reduces the copy less than 1s is the indexed content is huge and to a few milliseconds if it's small.
```py
att = env['ir.attachment'].create({'name': 'a.csv', 'raw': BinaryBytes(b'a,b,c,d,e,f,g\n' * 2000000)}) # 1.25s
att.copy() # before: 1.25s; after: 0.25s
```
task-2630381
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prSaudi companies will now keep global tax rounding enabled automatically, reducing the risk of accidental configuration changes. This helps maintain compliant and consistent tax calculations for Saudi localization users.
Original PR description
- Force "Round Globally" on Saudi companies to prevent accidental changes. task-6377776 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
Pricelists now include a Daily Rates calendar that lets users select days and create the matching daily pricing rules in one action. This makes seasonal or date-specific pricing easier to manage, while related pricing forms are simplified and reused across connected sales channels.
Original PR description
Seasonal prices are set through pricelist rules with validity dates. This commit adds a "Daily Rates" button on the pricelist that opens a calendar where selecting days creates the matching rules at once, each covering a full day. The pricelist button box is moved to the base form so it can be shared, and partnership is updated to reuse it. task-4968689 See : - https://github.com/odoo/enterprise/pull/126319 - https://github.com/odoo/upgrade/pull/10797 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Customers now see more accurate pickup and shipping information during checkout, including first available pickup dates, store closure notices, and expected shipping dates when available. The checkout also remembers the customer's selected delivery method and pickup store, making the buying experience smoother and reducing confusion.
Original PR description
Improve the pickup and shipping widgets to provide more accurate delivery information and keep track of the customer's choices. - Compute and display the first available pickup date based on opening hours, closures and estimated delivery time. - Display upcoming exceptional store closures in the pickup map. - Select the most relevant shipping method based on the customer's country and estimated delivery time. - Display the expected shipping date when available. - Remember the selected delivery method and pickup store during checkout. task-6485106 , design-task-6514854
Pricing rules that previously used percentage-based discounts now use the newer formula-based approach while keeping the same discount values. This keeps product, rental, subscription, point of sale, and website pricing behavior consistent after the old method was removed.
Original PR description
Follows the removal of the percentage price method. Rules defined with 'percentage' and a `percent_price` are redefined as 'formula' with the same value in `price_discount`, and the checks deciding whether a price can be shown as a discount now call `_is_plain_discount_rule`. See: - https://github.com/odoo/odoo/pull/273685
Belgian payroll worker code names have been simplified so users can find and select the right option more easily. The full official wording is still kept separately for reference, reducing clutter in daily payroll workflows without losing important details.
Original PR description
DMFA worker code names were overly long and detailed, making selection cumbersome for users in payroll workflows. Move the long official descriptions to a new `description` field on `l10n.be.worker.code` and update `name` with concise short names. Task: 6514465
The rental stock module now reuses an existing shared rule for checking rented product quantities. This makes it easier for future customizations or add-on modules to adjust rental availability logic consistently without changing the core process.
Original PR description
There is already an existing hook on product.product ([sale_renting.models.product_product.ProductProduct._get_qty_in_rent_domain](https://github.com/acsone/enterprise/blob/2cd105c93bb7199a5ecea67a919a7ab5d9251cbf/sale_renting/models/product_product.py#L24)), use it to get the domain, so it can be inherited by other modules.
While the upstream method uses `('product_id', 'in', self.ids)` instead of this one's `('product_id', '=', self.id)`, this isn't an issue since there's a `self.ensure_one()` just above.
Forward-Port-Of: odoo/enterprise#130090
Forward-Port-Of: odoo/enterprise#129191The website import form now directs users to official documentation instead of older links. This helps users find clearer guidance on creating API keys, reducing setup confusion when using the website import tool.
Original PR description
Update the import form links to use the documentation instead. This is important as it gives better info about creating API keys to use the tool correctly. Forward-Port-Of: odoo/enterprise#130457
Users can now connect WhatsApp Business accounts through Meta Embedded Signup directly in Odoo. This automates authorization, account setup, phone registration, and webhook configuration, reducing manual setup work and lowering onboarding friction.
Original PR description
Allow users to onboard WhatsApp Business accounts through Meta Embedded Signup using the application as their Tech provider. The onboarding flow guides users through the Meta authorization process, retrieves the required account information, configures the WhatsApp account automatically, registers the required webhook, and completes the setup without requiring manual Meta application configuration. Documentation: https://developers.facebook.com/documentation/business-messaging/whatsapp/embedded-signup/overview Related IAP PR: https://github.com/odoo/iap-apps/pull/1606 Task-5237447
Large Italian electronic invoices now import much faster by processing invoice lines more efficiently and reducing repeated checks. This can significantly shorten waiting times for businesses handling invoices with many lines, especially in accounting workflows.
Original PR description
### Description: When importing a large invoice, the process can take a lot of time. This is caused by how `l10n_it_edi` handles the creation and writing of each line of the bill. To improve performance, most of the process is now performed in memory and record creation is deferred to a single batch at the end. Additionally, the check related to `account_accountant` is cached to avoid superfluous calls. ### Benchmark: **For `history.limit`[^1] of 50 (= 21002 `account.move.line`):** | Invoice lines | Before | After | Speedup | |---------------|----------|---------|---------| | 33 | 4.75s | 2.23s | 2.1× | | 172 | 2.3min | 45.1s | 3.1× | | 1,934 | 44.4min | 6.8min | 6.6× | [^1]: System parameter `account.bill.predict.history.limit` ### Reference: opw-5937519 Forward-Port-Of: odoo/odoo#286357 Forward-Port-Of: odoo/odoo#282880
Belgian payroll officers now change an employee’s working schedule through one guided flow directly from the employee form. The process helps ensure leave balances, wages, and employee records are updated consistently, reducing confusion and avoiding missed payroll adjustments.
Original PR description
Before: Belgian employees had two different ways to change their working schedule: Directly updating the Working Schedule field on the employee. Using the "Working Schedule Change" action. Only the…
Before: Belgian employees had two different ways to change their working schedule: Directly updating the Working Schedule field on the employee. Using the "Working Schedule Change" action. Only the dedicated action correctly handled related payroll operations such as leave allocation adjustments and employee version creation. The action was not easily discoverable and created confusion about which workflow should be used. After: The "Working Schedule Change" action has been removed. Changing the Working Schedule directly from the employee form now opens a dedicated wizard. The wizard allows payroll officers to review and adapt the related leave allocation and wage before applying the change. Employee versions are automatically created when required. Existing allocation recomputation, wage update and version creation logic is preserved. To support this workflow: Added a custom widget on the employee Working Schedule field to trigger the wizard when the schedule changes. Reworked the wizard to focus on the Belgian paid time off use case. Added user notifications to clearly communicate the actions performed after validation. Impact: Provides a single and more intuitive workflow for working schedule changes. Prevents users from bypassing payroll-specific recomputations. Improves usability while preserving existing business behavior. Task: 6247606
Bill field suggestions now run more efficiently on databases with many accounting entries. This improves responsiveness when processing supplier bills, especially in Peppol workflows where product, account, and tax matching is used frequently.
Original PR description
### Description: Predicting fields can be slow when the database has a large amount of move lines (AML). This is caused by the fact that `_predicted_field` will search on all these AMLs to find the…
### Description: Predicting fields can be slow when the database has a large amount of move lines (AML). This is caused by the fact that `_predicted_field` will search on all these AMLs to find the ones related to the searched fields. It can be an issue when using Peppol since it is used a lot in most localizations to match each line to its product/account/tax. To speed up the queries, the move IDs have been inlined in `_build_predictive_query` to avoid suboptimal execution plans caused by LIMIT and ORDER BY clauses. Additionally, materialization of the `account_move_line` CTE has been removed so the planner can inline filters and stream rows directly, which improves performance in most use cases. ### Benchmark: **For a `history.limit`[^1] of 100:** | Nb of invoice line | Before | After | AMLs scanned | |--------------------|-----------|---------|--------------| | 33 | 7s | 4s | 232 | | 172 | 11.39min | 5min | 99859 | | 1934 | 3h+ [^2] | 1h40min | 102503 | **For a `history.limit`[^1] of 50:** | Nb of invoice line | Before | After | AMLs scanned | |--------------------|---------|---------|--------------| | 33 | 6s | 4s | 187 | | 172 | 2.52min | 1.27min | 21002 | | 1934 | 40min | 20min | 21002 | [^1]: System parameter `account.bill.predict.history.limit` [^2]: Stopped manually after 3h; full runtime not measured ### Reference: opw-5937519 Forward-Port-Of: odoo/enterprise#130242 Forward-Port-Of: odoo/enterprise#128172
Marketing Automation now includes a Templates area for saving, finding, and reusing favorite marketing emails. Users can create email activities from scratch or start from an existing template, making campaign setup faster and more consistent.
Original PR description
This commit includes the `mass_mailing`'s mailing **templates** in the `marketing_automation` app.
The Time Off Gantt view no longer displays an unnecessary “Undefined Employee” row when grouped by employee. This removes visual clutter and makes employee time off planning clearer for HR users.
Original PR description
Since web_gantt creates a placeholder group for optional fields, an "Undefined Employee" row was displayed when grouping by employee in the Time Off Gantt view. Add `required=True` to `employee_id` on `hr.leave.report.calendar` to prevent rendering this empty row. Task: 6537247
Certificate records can now be created or updated from the user interface without errors when uploading certificate files. This prevents a traceback caused by the newer upload format and keeps certificate management working smoothly for users.
Original PR description
Description of the issue this commit addresses: Since https://github.com/odoo/odoo/commit/23a7d8cc5b1d, binary values uploaded from the UI are dictionaries containing the filename and base64 content. Certificate creation parses the value before ORM normalization and calls bytes() on the dictionary, causing a traceback. --- Desired behavior after this commit is merged: This commit normalizes certificate content through the binary field converter before parsing it, allowing certificates to be created or updated from the UI. --- task-6538863 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Intrastat report lines now appear in a consistent order across different database environments. This prevents environment-specific test failures and reduces the risk of confusing report differences caused only by internal currency IDs.
Original PR description
`_intrastat_groupby_label_builder` calls `sorted(grouping_keys)` on JSON strings to determine the order of intrastat report lines. Those strings contain `"invoice_currency_id": <int>`, an…
`_intrastat_groupby_label_builder` calls `sorted(grouping_keys)` on JSON
strings to determine the order of intrastat report lines. Those strings
contain `"invoice_currency_id": <int>`, an environment-dependent integer.
When two groups share all other dimensions but differ only in currency,
the sort compares the serialised integers lexicographically, so the group
order depends on the specific integer values of each currency in the DB.
The values differ between environments because `odoo/modules/db.py` reads
the `ODOO_RUNBOT` / `ODOO_TEST` environment variables at import time
(`RANDOM_SERIAL`). When set, it runs `base/data/base_data_test.sql` after
the normal bootstrap, which executes
`select setval('res_currency_id_seq', 97)`, advancing the sequence by 96
before any currency is loaded from `res_currency_data.xml`. This shifts
every currency ID up by 96: SEK becomes 114, EUR becomes 222. As strings,
"114" < "222" (first character), so SEK sorts before EUR, breaking the
test. On a standard local install the sequence is not advanced: SEK=18,
EUR=126. As strings "18" > "126" (second character, '8' > '2'), so EUR
sorts first, matching what the test expected.
Steps to reproduce the failure (before this fix):
Local (EUR sorts first, test passes):
./odoo-bin -d test_local -i account_intrastat --stop-after-init
> SEK=18, EUR=126 → "18" > "126" as strings → EUR first
Runbot-like (SEK sorts first, test fails):
ODOO_RUNBOT=1 ./odoo-bin -d test_runbot -i account_intrastat --stop-after-init
> base_data_test.sql pre-advances res_currency_id_seq to 97
> SEK=114, EUR=222 → "114" < "222" as strings → SEK first
> Alternative: restore any master-all runbot DB dumpThe help message shown when no records exist is now tailored separately for tax returns and working files. This avoids confusing users by referring to tax returns when they are viewing working files.
Original PR description
Before this commit: - There is a common empty list help for tax returns & working files. This is confusing in the case of working files, as the help states Tax Return in it. After this commit: - There are now separate empty list helps for both actions. Task-6475771
The website shop header now uses the already saved cart quantity when available instead of reloading the full cart each time. This avoids unintended cart resets or recovery actions while customers are browsing or completing payment, improving checkout reliability.
Original PR description
`header_cart_link` computed the badge quantity with `request.session.get('website_sale_cart_quantity', request.cart.cart_quantity)`. Python evaluates the default argument unconditionally, so every render resolved `request.cart` even when the quantity was already cached in the session. Resolving the cart runs `_get_and_cache_current_cart`, which can mutate the session (cart reset, abandoned-cart recovery) as a side effect of merely rendering the header.
Read the cached quantity directly when the session key is present, falling back to `request.cart` only when it is absent.
This is needed for https://github.com/odoo/odoo/pull/268897 to prevent the cart from being reset while waiting for the user to do the payment.This fix validates key French Flow 10 e-invoicing report fields before sending them to the public platform. It helps prevent full report rejections by flagging affected journal entries when text, tax, company, or address values do not meet required limits.
Original PR description
Some Flow 10 values are generated without applying the length and format constraints expected by the PPF. Long free-text values, oversized VAT numbers, and invalid address data can therefore cause an entire report to be rejected. Limit product names and invoice notes to their allowed lengths and normalize country codes. Validate the declarant SIREN, VAT number lengths, and address values before sending so affected journal entries are marked as errors and excluded from the report. No Task id Forward-Port-Of: odoo/odoo#286887 Forward-Port-Of: odoo/odoo#286536
Internal users assigned to tasks in invitation-only projects can now open their assigned task links without being blocked by project-level access errors. The fix preserves project privacy, so users can access only the task they are assigned to without exposing other project tasks.
Original PR description
Issue: Internal users assigned to a task in an "Invited internal users" project can read the task but may receive an access error when opening it. Adding them as project followers avoids the error…
Issue: Internal users assigned to a task in an "Invited internal users" project can read the task but may receive an access error when opening it. Adding them as project followers avoids the error but also exposes the project's other tasks. Steps to reproduce: - Set a project's visibility to "Invited internal users". - Assign an internal Project user to one of its tasks. - Keep the user out of the project's followers. - Open the assigned task through its access link. Cause: The task form loads feature flags whose computations read their values from the parent project. These computations run as the assignee, who can read the assigned task but not the invited-only project, causing a project access error. Additionally, the project many2one widget declares `is_template` as a related field. This makes web_read request `project_id.is_template` even though the widget uses the task's own `is_template` value. https://github.com/odoo/odoo/blob/8c1e139a8ffca9e9a82e90eb4a8a03a56b4aa660/addons/project/models/project_task.py#L277 https://github.com/odoo/odoo/blob/8c1e139a8ffca9e9a82e90eb4a8a03a56b4aa660/addons/project/models/project_task.py#L295 https://github.com/odoo/odoo/blob/8c1e139a8ffca9e9a82e90eb4a8a03a56b4aa660/addons/project/static/src/components/project_many2one_field/project_many2one_field.js#L36-L39 Solution: We need to compute the inherited task feature flags with elevated access so their values do not depend on the assignee's access to the parent project. declare `is_template` as a dependency of the current task instead of a related field of `project_id`. The task form therefore no longer reads the inaccessible project while its access restrictions remain intact. opw-6475880 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#284196
The AI chat agent filter now loads and paginates results using the selected agent from the start, instead of filtering only what was already loaded. This prevents the chat list from getting stuck with too few conversations and keeps agent-specific chat views consistent when navigating back.
Original PR description
The AI chat tab has a dropdown allowing to filter it on a specific agent. The filter is applied client-side only, which is incompatible with lazy loading. A `load_more` batch fetched from the unscoped tab domain can come back mostly unrelated to the selected agent. Once filtered down it may render too little content to overflow the scrollable area. The bottom scroll trigger that requests the next batch then never fires again, leaving the tab stuck showing fewer matching channels than actually exist. The dropdown now sets its own filter through `mail`'s new `MessagingMenuUIState.pluginFilters`, which goes through the real fetch and pagination: the agent scope is resolved server-side and ANDed into the tab's domain community: https://github.com/odoo/odoo/pull/286451
This update fixes small visual inconsistencies in Odoo forms on mobile screens, including extra spacing, oversized tag delete buttons, and a misaligned CRM probability icon. The result is a cleaner and more consistent experience when viewing or editing records on smaller devices.
Original PR description
Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The Add Font dialog now uses the standard switch control, so the “Serve font from Odoo server” option shows its checked state correctly and can be toggled with the keyboard. This improves usability and accessibility while removing obsolete duplicate styling.
Original PR description
[FIX] html_editor, website: generalize Switch component --- __Problem__ In the "Add font" dialog, the "Serve font from Odoo server" switch never shows its check mark, and cannot be toggled with…
[FIX] html_editor, website: generalize Switch component --- __Problem__ In the "Add font" dialog, the "Serve font from Odoo server" switch never shows its check mark, and cannot be toggled with Enter. __Reason__ The dialog reimplements the switch markup by hand instead of using the `Switch` component. Two things the component does were lost in the copy: - the knob glyph is a `::before` ligature, so it only renders if the span carries the `oi oi-filled` classes. The copy has a bare `<span/>` and stays blank once checked. - `Switch` supports toggling with `Enter`, which the copy does not handle at all. `Switch` itself was not directly usable here: it had no way to set an `id` (needed by the external `<label for=...>`). __Fix__ Make `extraClasses` optional, add an `id` prop, and use the component in the dialog. Toggling with `Enter` also failed to call `onChange` in `Switch`, leaving the owner state out of sync with the displayed value; this is fixed too. `labelIcon`/`labelIconClass` props are added for the `ai_website` counterpart of this fix. Finally, `website.editor.ui.scss` still carried a copy of the `.o_switch` rules, dead since the styles moved next to the component in `html_editor`. It is removed. + Enterprise PR: odoo/enterprise#130453 task-6377407
This fixes an issue that prevented users from adding extra images to products from the eCommerce tab. Product teams can now upload additional product media without encountering an error during the add process.
Original PR description
Steps to reproduce: 1. Open a product form view. 2. Go to the eCommerce tab. 3. Click on 'Add Media'. 4. Upload an image. 5. Click on 'Add'. Issue: - Adding an image fails with `ERR_INVALID_URL` because the generated data URL contains `[object Object]`. Cause: - The `raw` value returned by `searchRead` is a binary object containing `filename`, `content`, and `size`, but `convertToWebpFormat` passes the whole object as the image data to `generateImageVariants`. Fix: - Pass the `content` of the binary value to `generateImageVariants` instead of the whole `raw` object. opw-6542393
The member panel now positions the owner or admin crown icon next to the member's name instead of centering it across the full member entry. This makes the member list look cleaner and easier to read when extra status text appears below a name.
Original PR description
Before this commit, crown icon of a member in member panel was dead center to the member item as a whole. This means that if the member had name + another row of text (e.g. Back on X), then the crown would not be aligned with the member name. Before / After <img width="257" height="277" alt="Screenshot 2026-09-07 at 14 58 09" src="https://github.com/user-attachments/assets/289a5aa5-519e-4f0c-b226-5ed8b5b70ded" /> <img width="257" height="279" alt="Screenshot 2026-09-07 at 15 10 44" src="https://github.com/user-attachments/assets/4c29cf64-f759-476a-8663-efa8ab689d26" />
Fixed an issue where uninstalling certain modules could fail if they were linked to AI composer rules. Related model-specific AI rules are now removed automatically during uninstall, preventing conflicts and keeping module removal reliable.
Original PR description
## Issue When uninstalling a module that defines a model referenced by an `ai.composer` configuration, the corresponding `ir.model` is deleted. Deleting the `ir.model` sets the `focused_model_id` of…
## Issue
When uninstalling a module that defines a model referenced by an `ai.composer` configuration, the corresponding `ir.model` is deleted.
Deleting the `ir.model` sets the `focused_model_id` of the related `ai.composer` record to `NULL`.
The unique index on `ai.composer` uses `NULLS NOT DISTINCT`:
```python
_unique_agent_interface_model = models.UniqueIndex(
"(ai_agent_id, interface_key, focused_model_id) NULLS NOT DISTINCT",
)
```
As a result, `NULL` values are considered equal by the unique index.
If both a generic rule and a model-specific rule exist:
* `(agent, media_dialog, NULL)`
* `(agent, media_dialog, product.image)`
uninstalling the module that provides `product.image` deletes its `ir.model`, which sets `focused_model_id` to `NULL` on the model-specific rule.
This results in two identical `(agent, media_dialog, NULL)` entries and raises a `UniqueViolation`, preventing the module from being uninstalled.
## Fix
Set `focused_model_id` to `ondelete='cascade'`.
When the `ir.model` is deleted during module uninstallation, the corresponding model-specific `ai.composer` record is deleted instead of setting `focused_model_id` to `NULL`.
runbot-945683This fixes Spanish TicketBAI reporting for point-of-sale orders that use gift cards. Gift card refund amounts are now shown with the correct sign, preventing mismatches between line totals and the overall invoice total.
Original PR description
The issue fixed in commit[1] is again reproducible after commit [2] the pos order line for gift card is now not considered as a refund Step to reproduce: - Install pos_loyalty and…
The issue fixed in commit[1] is again reproducible after commit [2] the pos order line for gift card is now not considered as a refund Step to reproduce: - Install pos_loyalty and l10n_es_edi_tbai_pos with demo data - Create a gift card (add a tax to the discount product, any 0%) - start pos, add a product and use the gift card - fulfill the order - go to backend and open that order - In the TicketBAI XML, the values for the giftcard product will be positive, causing an inconsistency between the product line total and the invoice total [1] https://github.com/odoo/odoo/commit/0bbc5ebdcc7e014d87130b2ff9cee98e3aa7479a [2] https://github.com/odoo/odoo/commit/b17c9713e7a3305c240298fa54fcf1bc87a9bb8c FIX - we used to determine `sign` based on each order line's `is_refund` property - this property is quite sensitive as it depends on factors like line's qty, price, is reward or not. - so its better to depend on order's refund property for sign reversal https://github.com/odoo/odoo/blob/4fef2c5b69fac10594fac81b149d542ee4621b13/addons/point_of_sale/models/pos_order.py#L1768 opw-6226003 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#286448 Forward-Port-Of: odoo/odoo#278042
Dark mode color palettes now load correctly and include the full set of colors used by the interface. This prevents missing or incorrect colors in items such as kanban cards, tags, badges, and color lists, improving visual consistency for users working in dark mode.
Original PR description
1) The "$o-colors" css variable was rebuilt in "secondary_variables.dark.scss", which loads after community's "primary_variables.scss" already assigned it via !default. The dark "$o-colors: ()!default;" reset was silently skipped, so dark colors were appended onto the light ones instead of replacing them, doubling "$o-colors" to 24 entries. => Moving this logic to "primary_variables.dark.scss", which correctly loads first. 2) "$o-colors-secondary-original" only listed 18 colors instead of the 44 used in the original "$o-colors-secondary" of light mode, meaning the dark mode's total palette had far fewer entries than the light mode leading to missing coloring in kanban, tags, badges and colorlist. => Extending the list so that the dark mode "$o-colors-secondary-original" matches the original "$o-colors-secondary" light mode's 44 colors. related: https://github.com/odoo/odoo/commit/1dd67666ce06a9ee44a193e8006cf61aa71479c3
Rental products now show zero availability when no matching rental window exists, instead of triggering an error. This helps customers and staff complete searches or bookings without unexpected interruptions.
Original PR description
`_get_free_qty` computes the free quantity for a rental period by taking the minimum `quantity_available` across the availabilities returned by `_get_availabilities`. When that method returns an empty list (e.g. no availability windows overlap the requested period), `min()` raises a `ValueError` instead of returning a quantity. This commit passes `default=0` to `min()` so `_get_free_qty` returns 0 when there are no availabilities, instead of crashing. task-6026756 See also: - https://github.com/odoo/odoo/pull/254869
The AI website Add Page dialog now shows the Generate text switch correctly and lets users toggle it with the keyboard. This improves accessibility and makes the dialog behave consistently with the rest of the interface.
Original PR description
[FIX] ai_website: broken switch in the "Add page" dialog --- __Problem__ In the AI "Add page" dialog, the "Generate text" switch never shows its check mark, and cannot be toggled with Enter. <img width="439" height="326" alt="image" src="https://github.com/user-attachments/assets/0dc38547-679f-4fe1-9fda-a93213adc3d4" /> __Reason__ The dialog reimplements the switch markup by hand instead of using the `Switch` component: its `switch-slider` span misses the `oi oi-filled` classes the knob ligature needs to render, and nothing handles `Enter`. The hand-written markup is also why the icon is the hardcoded `/ai/static/description/icon.png` with inline sizing rather than the `o_ai_icon` font icon used everywhere else. __Fix__ Use `Switch`, now that it takes a label icon. <img width="400" height="322" alt="image" src="https://github.com/user-attachments/assets/d71580e2-68c2-473e-8819-ed532ff2f1d8" /> + Community PR: odoo/odoo#286700 task-286528
The Belgian payroll interface now correctly shows the Working Time Reorganisation field on fixed calendars when credit time attendance requires it. This helps payroll users see and manage the relevant information without affecting the intended behavior for variable calendars.
Original PR description
A recent change incorrectly hid the Working Time Reorganisation (MRT) field on fixed calendars, even when a credit time attendance triggered its computation. This commit restores the dynamic visibility of the MRT field for fixed calendars, while preserving the intended behavior for variable calendars. Task: 6538351
This fix ensures Belgian payroll correctly includes canteen cost codes when calculating payslips. It closes a gap from a previous correction, helping payroll results and related validation tests reflect the right employee cost treatment.
Original PR description
Previous fix 9c4acee2d324a454d12dd21388ae083f99c40416 was missing a change in the list of code to read. Forward-Port-Of: odoo/enterprise#130522 Forward-Port-Of: odoo/enterprise#130481
The Sign app now correctly opens the file picker when users tap "Add Document" from a mobile template view. This prevents an error screen and lets users upload PDFs from mobile devices as expected.
Original PR description
Version: - saas-19.5 Steps to reproduce: - Open a Sign template on a mobile. - Go to the Documents tab in the sidebar. - Click "Add Document" to upload a new PDF. Issue: - clicking on "Add Document" button raise a traceback. Cause: - The button called `this.requestFile(...)`, but that method lives on `this.signButtons`, not on the component itself. Solution: - Fix the button to call `this.signButtons.requestFile(...)` so it opens the file picker correctly. task-6535275
When a contact linked to multiple active users is mentioned, all of those users now receive the notification immediately instead of only one seeing it right away. This ensures teams sharing a contact record do not miss timely mention alerts and avoids relying on a page reload to see them.
Original PR description
Before this commit, mentioning a partner that has two users notified only one of them. The other user saw the mention on reload only. This happens because the notification is sent on the single user that _notify_get_recipients picks for a partner, and since "[REF] bus, mail: use user rather than partner as bus target" a user is its own bus channel, so the other users of that partner are no longer reached. The notification record is stored per partner, which is why a reload shows it. This commit fixes the issue by sending to every active user of the notified partner. https://github.com/odoo/enterprise/pull/129969 Forward-Port-Of: odoo/odoo#286290 Forward-Port-Of: odoo/odoo#283836
This fixes small icon display issues in the Stock Barcode and Planning Field Service areas. Package and planning-related icons now show as intended, reducing visual confusion for users.
Original PR description
[FIX] stock_barcode: fix `oi_dropbox` typo --- `stock_barcode` uses the `oi_dropbox` icon to represent packages. odoo/enterprise@86659741 made a typo, this commit fixes it. task-6377407 [FIX] planning_field_service: fix some remainings fa icons --- task-6377407
The update adjusts an internal test expectation for France-specific employee leave management so it aligns with newly added DRS automation. This helps keep automated checks reliable without changing day-to-day user functionality.
Original PR description
Related to odoo/enterprise#129851 This commit adapts a query counter in order to fit with the newly integrated DRS automation task-5915160
This update corrects several records and tests that used values longer than allowed by their configured field limits. It helps avoid validation errors and keeps accounting, payroll, localization, and point-of-sale data consistent with system rules.
Original PR description
https://github.com/odoo/odoo/pull/286488
When a partner is mentioned, all active users connected to that partner now receive the notification immediately instead of only one user seeing it before reload. This improves reliability of real-time communication, with related test updates to reflect the extra processing needed.
Original PR description
Before this commit, mentioning a partner that has two users notified only one of them. The other user saw the mention on reload only. This commit raises the query counts of the activity tests: the fix in odoo resolves each notified partner to its active users, which costs one query per post with an inbox recipient. https://github.com/odoo/odoo/pull/283836 Forward-Port-Of: odoo/enterprise#130206 Forward-Port-Of: odoo/enterprise#129969
Users can now access the correct reconciliation models from bank statement lines when the bank journal uses a foreign currency. This fixes a search issue where currency labels in journal names prevented matching models from appearing, helping accounting teams manage bank reconciliation setup reliably.
Original PR description
### Issue before this commit: When clicking "Manage Models" from a bank statement line, the associated reconciliation models are not displayed when belonging to a foreign currency journal. ### Steps…
### Issue before this commit: When clicking "Manage Models" from a bank statement line, the associated reconciliation models are not displayed when belonging to a foreign currency journal. ### Steps to reproduce the issue: 1. Download Accounting 2. Go to Currencies and activate another currency like EUR 3. Go to Journals and create a new one with bank type and curency EUR 4. Go to dashboard > new test bank journal created > 3 dots in the upper-right corner > Models > create a new one (ex Tester) setting the new test bank created as journal 5. Go to test bank journal and create a new bank matching 6. After the line is created click the 3 dots and go to Manage Models 7. See that the new model Tester created does not appear ### Cause of the issue: Foreign currency journals append their currency to the display_name (e.g., "Bank (EUR)"). The JS search framework passes this full decorated string into the search domain. The backend then attempts to match "Bank (EUR)" exactly in the database name and code fields, which fails because the database name is "Bank" without the currency added. https://github.com/odoo/odoo/blob/9c67949be529eb86886b3d5bde08e81e048ecfe7/addons/account/models/account_journal.py#L1095-L1100 ### Reason to introduce the fix: The filter is not working correctly. In this case it's better to change it to a domain instead of a default filter. opw-6481970 Forward-Port-Of: odoo/enterprise#129992
The AI agent panel has been adjusted to follow the same visual style as the Discuss panel. This creates a more consistent experience for users and reduces confusion when moving between collaboration tools.
Original PR description
<img width="2058" height="521" alt="Screenshot 2026-09-07 at 12 26 42" src="https://github.com/user-attachments/assets/c12ba5ec-5dc8-43b0-af10-97b95a24212c" />
A bug in the web interface prevented repeated card reloads from taking effect after the first refresh. This fix ensures cards are recreated properly on every reload, improving reliability for users working with card-based views.
Original PR description
`this.key` is the signal function, so `this.key + 1` concatenates its source and `set` stores that same string on every reload: the first reload changes the key and re-creates the Record, the next ones are no-ops.
This fixes an issue where helpdesk tickets could crash when starting a repair after the product on a return operation was changed. The repair flow now handles unmatched products safely, helping support teams continue processing tickets without interruption.
Original PR description
## Steps to Reproduce: - Install the `helpdesk_repair` module. (with demo data) - Open the ticket titled **"Cabinet Colour and Lock aren't proper"**. - Go to Returns and change the product in Operations. - Click the "**Repair**" button on the ticket. ## Error: `IndexError - tuple index out of range` ## Cause: When the product on the picking does not match the ticket's product, the filtered picking recordset is empty. Accessing `[-1]` on an empty recordset raises an _IndexError_. ## Fix: Use `[-1:]` instead of `[-1]` when retrieving the matching picking, so an empty recordset is handled. sentry-7692929099 Forward-Port-Of: odoo/enterprise#130165 Forward-Port-Of: odoo/enterprise#129526
The payment provider list now shows already installed providers before other available options. This makes the payment setup screen easier to scan and helps users find active providers more quickly.
Original PR description
# How to reproduce - Go to the payment provider Kanban view # The issue The installed providers are listed last, instead of first # Cause This PR changed the way the ordering on Selection fields is processed : https://github.com/odoo/odoo/commit/f0e68e342fb0b1722279cbce4f84161d3f312ac3 It is now based on the index of the current selection in the selection array opw-6537788
Payroll users can now access contract templates and employee type settings as soon as the Payroll app is installed. This fixes a menu visibility issue that previously required an additional salary contract app, making payroll setup clearer and more consistent.
Original PR description
Previously, the contracts configuration menus (Templates and Employee Types) appeared in the payroll configuration menu only if hr_contract_salary was installed. Now, they appear when installing payroll. task-6530076
Fixed an issue where embedded journal-entry actions in Documents could be removed by the cleanup process when users were working in a different company. This helps multi-company users keep their configured document shortcuts intact while preserving company-specific access behavior.
Original PR description
Step to reproduce: - You must have at least 2 companies with an account Journal - Create a New Journal Entry actions (child or parent) - Embed it to a folder - Set your company on a different one than the journal's one - Run the Garbage collector cron (Base: Auto-vacuum internal data) - The embed action has been removed The cause of this is that in the `_get_base_server_actions_domain` method in `documents_account` module there is a check on company to avoid using/running the actions when not in the right company. But the garbage collector don't need to have this check. Task-6147618 Forward-Port-Of: odoo/enterprise#122821
FedEx deliveries can now use a phone number from either the main customer contact or the selected delivery address. This prevents shipments from failing when one related contact record is missing a phone number but the other has it.
Original PR description
Issue ----- Users cannot deliver to a contact's delivery address if the contact address itself doesn't have a phone number. Steps to reproduce ----- - Setup Fedex - Create a contact with no phone number - Create a delivery address for the contact (with phone number) - Create a SO with the contact using Fedex & confirm - Change the partner on the picking to use the delivery address - Validate the picking > Error: missing phone number Cause ----- To populate the `soldTo` part of thepayload, we call `_get_contact_from_partner` with the contact specified on the SO https://github.com/odoo/enterprise/blob/8e60f910a52e3b836e997e54a0b704e5786a28f2/delivery_fedex_rest/models/delivery_fedex.py#L171 https://github.com/odoo/enterprise/blob/8e60f910a52e3b836e997e54a0b704e5786a28f2/delivery_fedex_rest/models/fedex_request.py#L447-L452 The phone number is then taken directly from the contact. ----- Ticket: opw-6427962 Forward-Port-Of: odoo/enterprise#127434
Fixed an issue where completed field service shifts linked to sales orders could incorrectly reset planned hours to zero. This prevents completed work from being shown as still needing planning, improving visibility of scheduling progress.
Original PR description
## before: When marking a shift linked to SO as complete. The `allocated_hours` of this shift is reset to 0. So when the `Planned` button tries to compute the `planning_hours_planned` it adds zero to the planned hours, making all the hours go to the `To Plan`, which is incorrect ## after: prevents the `allocated_hours` from being recomputed when making the shift as complete to avoid this issue. This will leave the hours to be calculated in the `Planned` stat button instead --- task-6425357 Forward-Port-Of: odoo/enterprise#129833 Forward-Port-Of: odoo/enterprise#126396
The messaging menu dropdown no longer shows extra rounded borders that were not intended in this view. This keeps the interface visually consistent and avoids a distracting layout issue for users.
Original PR description
In [1], discuss styling was adapted to frost, adding border radius to the messaging menu. However, borders/radius shouldn't be applied to messaging menu in dropdown. [1]: https://github.com/odoo/odoo/pull/285383 |Before|After| |-|-| |<img width="500" alt="image" src="https://github.com/user-attachments/assets/2fbff5eb-4282-4a5b-88d6-4c3c491dd2ea" />|<img width="500" height="691" alt="image" src="https://github.com/user-attachments/assets/7349b06f-2ddf-4d47-868b-7a2a8ccfc6b7" />|
Payslip worked-day lines are now translated using the employee's payslip language instead of the HR officer's language. This prevents mixed-language payslips and helps employees receive clearer, more consistent payroll documents, except where translations are not yet available.
Original PR description
l10n_be_hr_payroll Translation for payslip was not uniform. It is supposed to be based on employee language. But some fields we based on the user language (the HR officer who issues the payslips) What is not covered : fields that have missing translations. Those ones will still appear with the default (english) value.
Fixed an issue where exporting time entries could fail for employees whose contract had multiple versions. This helps payroll users complete exports reliably after contract changes without encountering an error.
Original PR description
## Steps to Reproduce: - Install the hr_work_entry module. - Create an employee. - Payroll tab > create a contract by setting only the start date (leave the end date empty). - From the contract…
## Steps to Reproduce:
- Install the hr_work_entry module.
- Create an employee.
- Payroll tab > create a contract by setting only the start date (leave the end date empty).
- From the contract version timeline (navigation bar), click the "+" button and create a new version.
- Open the cog menu (gear icon) and click 'Export Time Entries'.
## Error:
`ValueError - Expected singleton: hr.version(257, 258)`
## Cause:
Method `_get_contract_versions()` returns multiple versions for the given period.
for example:
`contract_dict = {datetime.date(2026, 8, 1): hr.version(1, 2)}`
The code assumes each value is a singleton and builds the recordset using `c.id`,
`[c.id for c in contract_dict.values()]`
Since `c` contains multiple records, accessing the ID will raise an error.
## Fix:
Instead of accessing `id`, it will access `ids`, and it returns the list of all records (`[1, 2]`).
`chain.from_iterable()` flattens this list into one iterable sequence `(1, 2, ...)`, and
then it will convert into a list and be passed to `browse()` to fetch the corresponding recordset.
sentry-7623869169
Forward-Port-Of: odoo/odoo#278858Custom font files uploaded through the website editor no longer appear in the media dialog's Documents tab. This keeps the document list cleaner by hiding technical font-related files that business users do not need to manage there.
Original PR description
Steps to reproduce: - From the website editor, open the Theme tab. - Upload a custom font. - Open the media dialog and go to the "Documents" tab. Issue: The uploaded font files appeared in the…
Steps to reproduce:
- From the website editor, open the Theme tab.
- Upload a custom font.
- Open the media dialog and go to the "Documents" tab.
Issue:
The uploaded font files appeared in the Documents tab. When a zip file
was uploaded, every font it contained appeared individually, along with
the generated "CSS font face" attachment and the Google fonts metadata
cached by the server.
Cause:
Fonts uploaded through `/website/theme_upload_font` are created as
public attachments. The Documents tab of the media dialog lists every
public attachment that is not an image or an asset, so the font files
(mimetype `font/...`), their font face declaration (mimetype `text/css`)
and googleFontMetadata (server caches it as public attachment) were
listed.
Fix:
Create those attachments with a technical `/web/font/{id}/{name}` url
and exclude it from the Documents tab domain.
Existing databases are adapted by an upgrade script(https://github.com/odoo/upgrade/pull/10999)
Upgrade PR: https://github.com/odoo/upgrade/pull/10999
task-[4771523](https://www.odoo.com/odoo/project/974/tasks/4771523)This fixes an issue where special styling from user mentions could accidentally be carried into email content. Emails generated from Odoo will now keep cleaner, more consistent formatting and avoid a test failure caused by differing style values.
Original PR description
Before this commit, inlining the styles of a mail body copies the border radius, the padding and the margin of a mention into its style attribute, although `o_mail_redirect` is blacklisted so that none of its class styles are inlined. This happens because the blacklisted declarations are matched by property name, while the styles collected for the node have `padding-top` and its siblings merged into `padding`, `margin` and `border-radius`, three names no blacklisted declaration carries. This commit compares each blacklisted declaration with the value the node ends up with, so that a merged shorthand is removed as well. Note that the three tests asserted the values that leaked, the radius among them being `$btn-border-radius-lg`: 6px in enterprise but 4px in community, which is what turned the JS suite red on master. https://runbot.odoo.com/odoo/error/946970
Corrects how the website shop reads the delivery country when searching for pickup locations. This prevents pickup point lookup from failing or showing an incorrect prompt when a customer address already has a country selected.
Original PR description
`country_id` is a number so the fix in #281720 - which avoids a traceback when no country is present - now leads to nothing being loaded when the delivery address has a country. Because `country_id?.id` now gives `undefined`. The fix makes sense only if the field is marked as a many2One as done in 319bb52 (which was only merged in 19.4+). This is consistent with fix edf65dc done in 19.4+ as well. Forward-Port-Of: odoo/odoo#286195 Forward-Port-Of: odoo/odoo#285006
This update fixes missing accent marks in Spanish fiscal position labels. It improves the professionalism and accuracy of Spanish localization text without changing business logic or workflows.
Original PR description
@Tecnativa Forward-Port-Of: odoo/odoo#284053
Links added to manufacturing shop floor notes now open in a new browser tab instead of disrupting the current shop floor view. This keeps operators in their workflow while still allowing them to access attached documents or referenced pages.
Original PR description
Steps to reproduce 1. On a Manufacturing Order, open the Miscellaneous tab, click in Additional Notes, type "/file", pick "File" (Insert a file from Documents), select a document and save. 2. Open…
Steps to reproduce 1. On a Manufacturing Order, open the Miscellaneous tab, click in Additional Notes, type "/file", pick "File" (Insert a file from Documents), select a document and save. 2. Open the Shop Floor of that Manufacturing Order. 3. On the order card, click the link shown in the note. Expected: the link opens in a new tab. Actual: the Notes edition dialog opens and the link is not opened. Issue --- On the Shop Floor the Additional Notes HTML field is rendered inside a container whose click handler opens the note edition dialog, its links carry no target and the handler stops the event propagation, so clicking a link opens the edition dialog instead of the linked document. Additional Notes became an HTML field in ebc30649c0f5, which allowed such links while this rendering was never adapted to open them. https://github.com/odoo/enterprise/blob/bfda5100ddd423f9e5fb91a9f83b4719c1f58397/mrp_workorder/static/src/mrp_display/mrp_display_record.xml#L58-L63 The note links now receive target="_blank" after mount and on every patch so they open in a new tab like the readonly HTML field viewer, and the container handler ignores clicks landing on a link so it no longer opens the edition dialog for them. https://github.com/odoo/enterprise/blob/bfda5100ddd423f9e5fb91a9f83b4719c1f58397/mrp_workorder/static/src/mrp_display/mrp_display_record.js#L106-L111 opw-6487702 Forward-Port-Of: odoo/enterprise#128979
This update prevents conflicting context settings when users create items quickly during bank reconciliation. It ensures the user's current settings take priority, reducing inconsistent behavior in accounting workflows.
Original PR description
Since this commit: https://github.com/odoo/enterprise/commit/938978c622700f9de097d9ff163f5b3c043231ed We pass the auto_statement_processing context key to false when destroying the component. The problem is that for the quick creation we use the model context. It might happen that those two contexts are different and can create inconsistancy. This commit will make sure the user context has priority on the global state context. no task id Forward-Port-Of: odoo/enterprise#130456 Forward-Port-Of: odoo/enterprise#129957
This fix ensures that when an employee has multiple contracts and payslips in the same month, canteen costs are applied to the first payslip with a paid amount. This helps Belgian payroll calculations stay accurate and avoids misplaced employee cost deductions.
Original PR description
In case of multiple contracts for a single month (and then multiple payslips), the canteen cost must appear in the first payslip that have a paid amount. Forward-Port-Of: odoo/enterprise#130364 Forward-Port-Of: odoo/enterprise#130109
Belgian CodaBox SODA imports now use the actual last import date when checking for new statements, instead of relying on accounting entry dates. This prevents valid payroll statements generated within the same accounting period from being skipped.
Original PR description
Before v19.1, we used to set the date on the journal entry based on the generation date of the SODA statement during the import. So it was possible to use the last date found in the salary journal as a `date_from` filter when fetching new SODA statements. Starting from v19.1, we now set the date on the journal entry as the last day of the accounting period referenced in the SODA file. However, we didn't change the fetching logic accordingly. If a SODA statement is generated on July 7 for the accounting period of July, the date on the journal entry would be July 31 and, consequently, any other SODA statement generated in-between those dates would be filtered out during the fetch. Ticket: opw-6214589 Forward-Port-Of: odoo/enterprise#130183
This fix prevents an unexpected error from appearing when Odoo handles certain report actions. It improves reliability by using the correct record context, reducing the chance of users seeing a traceback during normal operations.
Original PR description
opw-6360013 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#274977
The stock allocation report has been refined to work better on mobile, avoid over-allocating already reserved quantities, and prevent errors from repeated quick actions. Users can now allocate or unallocate directly from the forecast report, while validation flows no longer open the allocation report automatically.
Original PR description
This PR fixes issues with [the recently merged](https://github.com/odoo/odoo/pull/264299) allocation report. Main changes are: - Add specific design for mobile device; - Don't allocate already reserved quantity; - Allocation report won't open itself automatically when validating an operation from the Barcode app, no matter the configuration (a setting is planned to be added in `master` to let the possibility if the user wants); - Add the possibility to allocate from the forecast report. For more details on these changes or other fixes, check the corresponding commit's message. _________ **Enterprise PR:** odoo/enterprise#122258 task-4894566 Forward-Port-Of: odoo/odoo#272722
The barcode app’s print button now prints labels for the allocated products instead of the allocation operation report. This helps warehouse users get the right labels directly from barcode lines, reducing confusion and manual reprints.
Original PR description
Before this commit, the print button on barcode line printed the allocated operation's report instead of the allocated products' labels. This commit fixes that. _________________ **Community PR**: odoo/odoo#272722 [task-4894566](https://www.odoo.com/odoo/966/tasks/4894566) Forward-Port-Of: odoo/enterprise#122258
Fixes an error that could occur when paying a vendor bill with withholding tax after the currency field was cleared. The system now safely falls back to the company currency, helping users continue the payment flow without an unexpected crash.
Original PR description
Currently, an error occurs when user tries to pay on a vendor bill and removes the currency. Steps to replicate: - Install `l10n_account_withholding_tax`and activate multiple currencies. - Open…
Currently, an error occurs when user tries to pay on a vendor bill and removes the currency.
Steps to replicate:
- Install `l10n_account_withholding_tax`and activate multiple currencies.
- Open Invoicing > Vendors > Bills and create a new bill and add a vendor and bill date.
- Add a product and tax `2% WTH`.
- From the Cog menu > Click Pay > Remove the Currency.
Error:
```
File '/home/odoo/src/odoo/saas-19.4/addons/l10n_account_withholding_tax/models/account_withholding_line.py', line 208, in _compute_original_amounts
line.original_base_amount = line_curr.round(base_amount * rate)
File '/home/odoo/src/odoo/saas-19.4/odoo/addons/base/models/res_currency.py', line 264, in round
self.ensure_one()
File '/home/odoo/src/odoo/saas-19.4/odoo/orm/models.py', line 5342, in ensure_one
raise ValueError('Expected singleton: %s' % self)
ValueError: Expected singleton: res.currency()
```
Cause:
- As the user removed currency, the `comodel_currency_id`is received as false.
- Later when we call `round()` on the empty res.currency recordset causes this error to occur.
Solution:
- Added the company currency as a fallback value when `currency_id` is removed by user, since `currency_id` is a required field user will need to select a currency when saving.
sentry-7616890592
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#283737
Forward-Port-Of: odoo/odoo#277507This fixes an internal test setup for LDAP authentication so it matches expected cookie behavior after recent timezone handling changes. It helps keep automated checks reliable without changing how users sign in.
Original PR description
In #279318 `ResUsers._login` was modified to *parse* the `tz` cookie instead of just storing it in order to normalize the timezone (as browsers can send CLDR timezones which are legacy tzdata timezones). This is a problem in auth_ldap's tests because `mock_check_identity` sets the entire request as a straight mock, so `request` is truthy, `request.cookies` is a mock, `request.cookies.get(...)` is a mock, and `ZoneInfo` blows up trying to resolve it because it's nonsensical. If we make the mock cookies into a straight dict, `request.cookies.get(...)` returns `None` and we skip ahead without error (previously we'd skip ahead because `tz in all_timezones` would be `False`). https://runbot.odoo.com/odoo/error/945680
Adds checks before sending Turkish Nilvera e-invoices so users are warned when invoice lines are missing required taxes or product/CTSP details. This helps prevent invoices from being rejected by Nilvera, while avoiding unnecessary warnings for note or section lines.
Original PR description
Nilvera does not accept invoices with lines that do not have taxes, so we added a valiation check for sending the invoice to warn the user. Additionally, we raise a warning when a line does not have a product and has an empty CTSP. However, if the line is a note or section, this warning should not be triggered. task-6404409 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#284969 Forward-Port-Of: odoo/odoo#284377
Restarting a live chat chatbot session now correctly shows the available answer choices again. This prevents visitors from getting stuck or confused when they restart a conversation before it has been fully saved.
Original PR description
Before this commit, after restating a chabot session, the chabot question answers were not shown. This happens since the change in [1], introducing the field `selectedAnswerEver` in order to solve problems of stale server writes. However when a session is restarted, the first chatbot steps without a "real" message record (before the session is persisted) resolve to the same records of the earlier session. In turn this leads to said step having a selected answer already and thus not showing the choice. This commit solves the issue by clearing the selected answer fields when going to the next step, which is acceptable against stale writes since it's a purely client side decision. task-6535116 [1] https://github.com/odoo/odoo/pull/278597
Turkish credit notes created from existing invoices now use the dedicated sales return account from the sales journal instead of incorrectly keeping the original sales account. This improves accounting accuracy for Turkish companies while preserving exact matching for cancellation reversals.
Original PR description
The Turkish chart of accounts keeps sales and sales returns on separate accounts, and the sales journal carries the account to use for returns. A credit note typed in by hand already lands on it, but one created from an existing customer invoice did not. Reversing an invoice copies `account_id` over from the invoice line, and since that field is a stored compute without depends, nothing ever recomputes it, so the return kept the sales account. Set the journal account on the copied product lines instead. Reversals made to cancel an entry are left alone, as those have to mirror the original move exactly for the two to net out, and a plain duplicate is untouched. Task-6438412 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#284808 Forward-Port-Of: odoo/odoo#282858
E-invoice imports and exports no longer include internal deferred revenue dates that are only relevant to the vendor's accounting process. This prevents customers from receiving irrelevant date information and avoids creating deferred entries when importing vendor bills.
Original PR description
The current implementation of the Peppol XML export incorrectly populates the <cac:InvoicePeriod> nodes with internal deferred entry dates. These dates are intended for the vendor's revenue recognition process, and the customer has nothing to do with these dates. This commit ensures that: - deferred entries are never created when importing vendor bills. - <cac:InvoicePeriod> is no longer exported in invoices (for now). task-6014315 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#281348 Forward-Port-Of: odoo/odoo#265796
Pasted tables from Google Docs now keep only the first row as the header, matching what the editor supports. This prevents extra header rows from appearing incorrectly and makes pasted table content more consistent for users.
Original PR description
Steps to Reproduce - Copy a table with multiple header rows from Google Docs. - Paste the table into the editor. Description of the issue: - The pasted table contains multiple header rows, but the editor supports only the first row as the table header row. Cause: - During paste, `cleanForPaste` does not handle tables with multiple header rows - As a result, header cells (`<th>`) in rows other than the first row remain as header cells instead of being converted to normal table cells (`<td>`). Solution: - Update `cleanForPaste` to handle tables with multiple header rows. - If a table contains `<th>` elements in any row other than the first row, replace those `<th>` elements with `<td>` elements. - This ensures that only the first row is treated as the table header row. task-6455248 Forward-Port-Of: odoo/odoo#286303 Forward-Port-Of: odoo/odoo#281234
Fixes a Razorpay FPX payment issue that could cause checkout to fail when customers returned from the payment page. The payment flow now handles missing return details correctly, improving reliability for merchants using Razorpay FPX.
Original PR description
Issue: --- Paying with Razorpay using FPX raises `KeyError: 'amount'` when the customer returns from checkout. Steps to reproduce: 1- Enable Razorpay with FPX as a payment method. 2- Pay an order using FPX. Cause: --- In FPX, Razorpay returns without `amount`/`currency`. `_apply_updates` fetches the full payment from the API to determine the state, but that fetched entity is local to the method and never reused for amount validation, so `_process` still calls `_validate_amount` / `_extract_amount_data` with the original, amount-less redirect data. This issue is introduced after c34992ffd94ba4594731400839332b677fdc2b32, which removed the check in `_extract_amount_data` that returned `None` (skip validation) when `amount`/`currency` were absent. opw-6467815 Forward-Port-Of: odoo/odoo#286476
Stripe SEPA payments no longer use the order reference as the bank statement descriptor, avoiding failures when an order number contains only digits. The descriptor now uses the company name again, making SEPA payments more reliable for affected customers while preserving expected statement information.
Original PR description
**Steps to reproduce:** 1. Install Sales, l10n_be, payment_stripe and switch to belgian company 2. Switch the admin user's company to the belgian one, and update their contact address to be in…
**Steps to reproduce:** 1. Install Sales, l10n_be, payment_stripe and switch to belgian company 2. Switch the admin user's company to the belgian one, and update their contact address to be in Belgium 3. Enable stripe payment provider 4. Add SEPA payment method in stripe configuration 5. Create a sale order with a name that doesn't include any characters (numbers only), confirm, click preview and attempt to make a payment using SEPA **Issue:** `The statement descriptor must contain at least one Latin character.` **Cause:** The previous fix (4fde0232b821c9a1d46d589ff14495f4e19029f4) passed the order reference directly, assuming it will contain characters. The intended behavior is to actually have the company name used in the statement descriptor field: https://support.stripe.com/questions/what-is-a-statement-descriptor-and-how-do-i-update-it This was the existing behavior before the fix, so will revert back to it. opw-6497127 Forward-Port-Of: odoo/odoo#286620 Forward-Port-Of: odoo/odoo#286287
Colombian retention reports now calculate the taxable payment amount correctly when vendor bills include partial credit notes. This prevents credit notes from incorrectly increasing the reported tax base, improving accuracy for retention certificates and related tax reports.
Original PR description
**STEP TO REPRODUCE** 1. install l10n_co_reports and account_accountant 2. Create a bill, with a line with a retention tax (3.50% RteFte). 3. Create a partial credit note (unit price less than what's on the bill). 4. Goes to the report 'Certificado de Renteciòn en Fuente', and notice the Monto del Pago Sujeto Retenciòn is not correct. **CAUSE** The sql query multiply tax_base_amount by -1 if debit > 0, which means (because we are dealing with vendor bills) the line is from a credit note, but tax_base_amount is already a signed value so credit notes ends up contributing to the tax base amount while they should reduce it. opw-6235830 Forward-Port-Of: odoo/enterprise#130340 Forward-Port-Of: odoo/enterprise#119716
Invoice import and export now avoids using internal deferred revenue dates that are only relevant to the vendor. This prevents customers from receiving irrelevant accounting dates in Peppol invoice data while preserving the needed Colombian support document behavior.
Original PR description
The current implementation of the Peppol XML export incorrectly populates the <cac:InvoicePeriod> nodes with internal deferred entry dates. These dates are intended for the vendor's revenue recognition process, and the customer has nothing to do with these dates. This commit ensures that: - deferred entries are never created when importing vendor bills. - <cac:InvoicePeriod> is no longer exported in invoices (for now). But it is kept for the colombian localization in case of support documents though. task-6014315
This fix makes employee records with the same name appear in a consistent order, preventing intermittent test and data-ordering failures. It helps ensure HR-related absence information is read reliably when a partner is linked to multiple users.
Original PR description
Before this commit, TestPartner.test_res_partner_to_store fails on the all-modules and per-country builds: AssertionError: '2024-06-06' != '2024-06-07' : Return date is the return date of the main…
Before this commit, TestPartner.test_res_partner_to_store fails on the all-modules and per-country builds: AssertionError: '2024-06-06' != '2024-06-07' : Return date is the return date of the main user of the partner This happens because the test reads the first entry of the hr.employee list, which holds one employee per user of the partner: back on the 7th for the main user, on the 6th for the other. This comes from "[FIX] hr*: load out-of-office dates from all user employees", which added the employees of the partner to the payload, where it held those of the main user only. The problem is that the list keeps the order of employee_ids, which is 'name' with no tiebreaker, and both employees are named test1, as an employee takes the name of its user and creating the second user renames the partner. Postgres is then free to return either one first, and the failing builds get the second one. This commit fixes the issue by ordering the employees on 'name, id', so that employees sharing a name keep a stable order instead of the one the database picks. The test asserts the whole hr.employee list, one entry per user of the partner, rather than its first entry alone, and that assertion pins the order. https://runbot.odoo.com/odoo/error/945994 Forward-Port-Of: odoo/odoo#286796 Forward-Port-Of: odoo/odoo#286236
Changing Peppol Reception Mode to receive invoices as documents no longer triggers an error. This helps Belgian companies using Peppol complete setup smoothly without interruption.
Original PR description
Steps to reproduce: - Install `documents_account_peppol` and `l10n_be` module - Switch to BE Company > `Activate Peppol` - Change `Peppol Reception Mode` -> `Receive as Documents` Traceback: `AttributeError: 'res.company' object has no attribute '_peppol_allows_document_reception'` Problem: Changing the `Peppol Reception Mode` to `Receive as Documents` causes an `AttributeError` because `_compute_peppol_purchase_journal_required()` calls `_peppol_allows_document_reception()` on `config.company_id`, but the method is defined on `res.config.settings`. Cause: The method is available on the `res.config.settings`, not on the `res.company`. Solution: Add `_peppol_allows_document_reception()` method in `res.company` and call company's method from the `res.config.settings` method. opw-6470552 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#286517
This update fixes an internal test issue in the Mail app where mention styling could be measured differently depending on the installed edition. It helps keep automated checks stable across Odoo setups without changing the user experience.
Original PR description
Before this commit, some tests in convert_inline were failing due to mismatch of border-radius of mentions: - expected 0.375rem - received: 0.25rem This happens because the border radius of mention relies on `$btn-border-radius-lg`, which has different value in community and enterprise, respectively `o-to-rem(6px)` and `o-to-rem(8px)`. This commit fixes the issue by dynamically reading the border radius of mention, so that running it with or without enterprise modules make the test pass. Fixes runbot-error-946970
Fixed an issue in Documents where choosing “Search More...” from fields like Owner or Customer could immediately close the selection window. Users can now interact with that window normally, making it possible to search, sort, and select the right related record without interruption.
Original PR description
Steps to reproduce: 1. Install Documents 2. In the Documents list view, select a document to display the inspector. 3. Edit a field such as Owner or Customer which uses a Many2one widget. 4. In the…
Steps to reproduce: 1. Install Documents 2. In the Documents list view, select a document to display the inspector. 3. Edit a field such as Owner or Customer which uses a Many2one widget. 4. In the field dropdown, click "Search More..." to open a modal dialog. 5. Click inside the "Search More..." modal (e.g., to sort columns or resize headers). Issue: - The modal dialog immediately closes, and the contact cannot be selected. Root cause: - When an inspector field is edited, the record row is put into edit mode. While in edit mode, the documents list renderer listens for global clicks. Clicking inside the "Search More..." modal dialog targets elements that have `.o_list_renderer` (since the modal dialog renders a list view). Because the click target is within a list renderer but is not a document row, `DocumentsListRenderer.onGlobalClick` executes and clears the selection of the main list view. Clearing the selection unmounts the edited field in the inspector, thereby destroying the modal dialog stack. Solution: - Modify DocumentsListRenderer.onGlobalClick to scope click handling to the current Documents list renderer. Ignore clicks outside this.root.el, so interactions in nested UI such as Search More... do not clear the main selection and destroy the inspector field. opw-6253360 Forward-Port-Of: odoo/enterprise#128812 Forward-Port-Of: odoo/enterprise#119262
Manual quality checks created from a picking can now record a partial failed quantity without blocking the transfer. This prevents validation errors and lets warehouse teams continue processing orders when only some units fail inspection.
Original PR description
Version: -------- - 19.0+ Steps to reproduce: ------------------- - Install `quality_control` module - Create a picking order with a product - From the gear menu, create an on-demand Quality Check -…
Version:
--------
- 19.0+
Steps to reproduce:
-------------------
- Install `quality_control` module
- Create a picking order with a product
- From the gear menu, create an on-demand Quality Check
- Set the check to *Control per Quantity* and back to the picking
- Set the done quantity to 10
- Open the Quality Check wizard
- Try to fail 3 units
Issue:
------
Validating the partial failure raises a `ValidationError`:
- Missing required value for the field 'Team' (team_id)
The quality check split is not performed and the picking cannot be processed.
Cause:
--------
Quality checks created on-demand from the picking (via the gear menu) have
no associated `quality.point` or `stock.move.line` — only
`picking_id` is set at creation time.
https://github.com/odoo/enterprise/blob/7d40d6b787511bf2fcbf581859ed2cd38ba3f658/quality_control/models/quality.py#L457
In `_move_to_failure_location()`, the `move_line` branch assumes
`check.move_line_id` is populated. Since it is empty for on-demand
checks, the split logic operates on an empty recordset.
The new quality check for the split is then created via:
https://github.com/odoo/enterprise/blob/7d40d6b787511bf2fcbf581859ed2cd38ba3f658/quality_control/models/quality.py#L493
At this point both `failed_move_line` (a copy of the empty move line) and
`check.point_id` are empty. `_get_check_values(False)` cannot derive
fields normally sourced from the quality point (`team_id`, `company_id`,
`measure_on`, `test_type_id`, etc.), causing the `ValidationError` on record creation.
Fix:
----
- If the quality check is not linked to a move line, find the matching move line
from the picking before splitting the failed quantity.
https://github.com/odoo/enterprise/blob/7d40d6b787511bf2fcbf581859ed2cd38ba3f658/quality_control/models/stock_move_line.py#L94-L97
- `_get_check_values()` normally takes values from a Quality Point.
Since on-demand quality checks do not have one, fill the missing
values (`team_id`, `measure_on`) from the original quality check instead.
This allows manually created quantity-based quality checks to be
split correctly after a partial failure.
---
opw-6428749
Forward-Port-Of: odoo/enterprise#130275
Forward-Port-Of: odoo/enterprise#126505This update removes an older Point of Sale data cleanup step that is no longer needed. A newer, more targeted fix now handles stale loyalty reward lines, reducing the risk of unintended changes while keeping checkout data clean.
Original PR description
This fix is no longer required(https://github.com/odoo/odoo/pull/202752) as this one (https://github.com/odoo/odoo/pull/257043) is cleaner and less aggressive (it will only delete stale reward lines). This is the relevant part of the new fix to delete the previous one: https://github.com/odoo/odoo/pull/257043/changes#diff-18cef42f8c39513a82387e9cb81bc732b252304cd15b5b2f7b0b4623ac20cb41R100-R104 opw-6447092 Forward-Port-Of: odoo/odoo#286499 Forward-Port-Of: odoo/odoo#285376
Fixed an issue where importing multiple Belgian SODA files at once could copy accounting lines from the first file into the second. This helps ensure imported payroll accounting data stays accurate and avoids duplicate or incorrect entries.
Original PR description
Due to this commit: https://github.com/odoo/enterprise/commit/93c05b380e3c939e3c0b44eafcd7a41e86042d2d When importing 2 sodas from drag and drop. Due to the placement of the line_ids variable, the second move would have the line of first. By placing the variable in the loop we don't have that problem anymore task-6528101 Forward-Port-Of: odoo/enterprise#130190
This fix makes internal automated tests use a consistent language when checking activity history and tracking messages. It helps prevent false test failures caused by translation differences, improving release reliability without changing day-to-day product behavior.
Problem: When a parent element applies a `font-weight: 300` to its content, a child `<strong>` tag defaults to `font-weight: bolder`, which resolves to a computed font weight of `400`. For certain font families, weight `400` is visually identical to `300`, leaving no visual distinction for bold text. Cause: `<strong>` tags relied on relative weight boosting (`bolder`), which only increases the parent weight from `300` to `400` instead of applying explicit bold weight. Solution: Expl
Original PR description
Problem: When a parent element applies a `font-weight: 300` to its content, a child `<strong>` tag defaults to `font-weight: bolder`, which resolves to a computed font weight of `400`. For certain font families, weight `400` is visually identical to `300`, leaving no visual distinction for bold text. Cause: `<strong>` tags relied on relative weight boosting (`bolder`), which only increases the parent weight from `300` to `400` instead of applying explicit bold weight. Solution: Explicitly set `font-weight: bold` on `strong` for `.o_wblog_read_text` Steps to reproduce: - Go to /blog - Open any blog - Open editor. - Select some text from the content of the blog. - Apply Bold. - Observe that there is no visual difference. opw-6460699 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#282667
The Shopee sales integration now continues processing shipment label batches even if one batch has incomplete or unexpected data from Shopee. This reduces failed background jobs and helps remaining shipments keep moving without manual intervention.
Original PR description
Currently, an error occurs when the `sync_shopee_pickings` cron tries to fetch shipment labels for multiple batches of shipments. If some shipments do not contain the required data in the Shopee API…
Currently, an error occurs when the `sync_shopee_pickings` cron tries to fetch
shipment labels for multiple batches of shipments. If some shipments do not
contain the required data in the Shopee API response, the error causes the
cron to stop, preventing the remaining batches from being processed.
Error:
`ValueError: KeyError('status') while evaluating 'model._sync_shopee_pickings()'`
This issue was introduced by a recent refactoring commit [1] focused on linting
and formatting the Python file. The commit replaced the generic `Exception`
with `UserError` when handling errors during batch label printing.
As a result, errors other than `UserError` are no longer handled at the batch
level. When such an error occurs, the entire cron process stops instead of
failing only the affected batch and continuing with the remaining batches.
This commit fixes the above issue by handling generic `Exception` during
shipment label generation, ensuring that the error is handled for the
affected batch while the remaining batches continue to be processed.
[1]: https://github.com/odoo/enterprise/commit/cfe5d947579739ad770ac3f1525ce157af530846#diff-e072c3ecf980add685bb4a4f25cf2b0ab5d4625988e4afc2c4d4faeae687ca88R199
sentry-7685943988
Forward-Port-Of: odoo/enterprise#130295
Forward-Port-Of: odoo/enterprise#130181The spreadsheet edition test setup was updated to match an internal change in how popover positioning is provided. This helps keep automated tests reliable without changing the spreadsheet features users interact with.
Original PR description
The env value `getPopoverContainerRect` has been changed into an owl plugin. We need to adapt the test components accordingly. Task: 6510584
This change updates many automated tests to use a consistent way of freezing the current date and time. It reduces flaky or inconsistent test results across business areas such as accounting, CRM, point of sale, mail, and localization, without changing day-to-day product behavior.
Original PR description
Instead of patching (often partially) the time, use `mock_datetime_and_now`. https://github.com/odoo/enterprise/pull/130586 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update removes unnecessary internal code left over from the migration to the newer interface framework. It does not change product behavior, but helps keep the codebase simpler and easier to maintain.
Original PR description
- https://github.com/odoo/enterprise/pull/130345 See commit messages for details. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update standardizes how tests control dates and times across several Odoo Enterprise apps. It helps reduce inconsistent test results and improves confidence that business workflows behave predictably over time.
Original PR description
Instead of patching (often partially) the time, use `mock_datetime_and_now`. https://github.com/odoo/odoo/pull/286853
The restaurant preparation display was updated to use the newer underlying interface expected by the platform. This keeps the screen compatible with upcoming framework changes and adds automated test coverage to reduce the risk of regressions.
Original PR description
Changes useLayoutEffect to useEffect to match the OWL3 API. We also write a new unit test because it turns out this particular effect was untested (see commented out effect runbot green: https://runbot.odoo.com/runbot/batch/2596701/build/114854663) Note: - This useLayoutEffect use to be a useEffect before this commit: https://github.com/odoo/enterprise/commit/eab9f777ae8303d7e3a8a94f7e356c6183dc1c2f - Removed a one step python tour that is redundant with new hoot.
This change cleans up leftover technical code from the Owl 3 migration that was no longer needed. It does not change business features, but helps keep the Studio codebase simpler and easier to maintain.
Original PR description
- https://github.com/odoo/odoo/pull/286533 See commit messages for details. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The spreadsheet edition test setup was updated to match an internal framework change for how popover positioning is provided. This keeps spreadsheet-related automated tests aligned with the current architecture without changing business features or user workflows.
Original PR description
The env value `getPopoverContainerRect` has been changed into an owl plugin. We need to adapt the test components accordingly. Task: 6510584
The room booking screen was updated to use newer underlying technology so it remains reliable in future Odoo versions. A new test was added to confirm the selected booking slot still scrolls into view when users change days.
Original PR description
Replaced `useLayoutEffect` with `onMounted` + `onPatched` because `useLayoutEffect` is deprecated in OWL3. `useLayoutEffect(() => { ... }, () => [this.state.selectedDay])` scrolled to the selected…
Replaced `useLayoutEffect` with `onMounted` + `onPatched` because
`useLayoutEffect` is deprecated in OWL3.
`useLayoutEffect(() => { ... }, () => [this.state.selectedDay])`
scrolled to the selected slot after each day change. OWL3 has no
direct equivalent with a dep array. The natural port to `useEffect`
ran eagerly before mount and crashed all 10 room_booking_form tests
(`this.root.el` was null). `onMounted` + `onPatched` guarantee the
DOM is present; a closure variable `scrolledDay` skips re-scrolls
when the day hasn't changed, preserving the original dep-array
semantics. An `onWillRender` subscription on `this.state.selectedDay`
ensures OWL schedules a re-render — and thus triggers `onPatched` —
whenever the day changes.
When commenting out the useLayoutEffect there was no error,
the code we refactored had NO TEST coverage. A test was written
to ensure our fix was correct, and it was tested against the
previous useLayoutEffect:
- Passed with previous useLayoutEffect.
- Failed with previous useLayoutEffect commented.
- Passed with our OWL3 replacement.The web tour feature was updated to use the current component property handling approach. This keeps the guided tour and recording tools aligned with the latest framework standards and improves long-term maintainability without changing user-facing behavior.
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
This update modernizes internal web interface components by replacing an older property definition pattern with a newer validation approach. It helps keep the web client easier to maintain and reduces the risk of component configuration issues, without introducing expected changes for end users.
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
The spreadsheet edition test setup was adjusted to match an internal change in how popover positioning is provided. This helps keep spreadsheet filter and pivot panel testing reliable without changing the experience for end users.
Original PR description
The env value `getPopoverContainerRect` has been changed into an owl plugin. We need to adapt the test components accordingly. Task: [6510584](https://www.odoo.com/web#id=6510584&cids=1&menu_id=4720&action=333&active_id=2328&model=project.task&view_type=form)
In order to prepare the translations for Odoo 20, we fill in the translations from saas-19.4. We also update `.weblate.json` with the latest changes. Related: https://github.com/odoo/odoo/pull/286466 Related: https://github.com/odoo/design-themes/pull/1340
Original PR description
In order to prepare the translations for Odoo 20, we fill in the translations from saas-19.4. We also update `.weblate.json` with the latest changes. Related: https://github.com/odoo/odoo/pull/286466 Related: https://github.com/odoo/design-themes/pull/1340