Daily updates from Odoo
Thursday, July 30, 2026
48 changes · master
Enhancements to existing features
Partner pages are simplified by removing an extra subscription statistic, freeing space for more relevant information. Appointment teams also gain a feedback email and ratings flow to collect and review customer satisfaction after visits.
Original PR description
Remove the sale_subscription statistic hook from res.partner to reduce the space taken by application statistics in partner views. task-6385576
Spreadsheet formulas now do more preparation once upfront instead of repeating it every time a function runs. This should make spreadsheet evaluation faster, especially in documents and survey-related spreadsheets with many formulas.
Original PR description
…tion at compile time A number of checks and pre/post processing is done for each executed function. Some of it can be known at compile time since it only depends on the function and the number of arguments. With this commit, we pre-compute a number of things only once at compile time to minimize what is done when executing the function. This also opens the door to moving vectorization at compile time as well, which could again improve perf. Task: 6254300
Payroll will no longer automatically set the current driver of a company car based on employee benefits. Instead, employees who choose or receive a car through their contract are marked as the future driver, preventing the car from being offered to others and avoiding unnecessary task creation for payroll officers.
Original PR description
. Remove the auto-assignment of the Driver based on the payroll benefits . If an employee signs a contract and selects the car or the car gets added to the employee's benefits, he should become the car's future driver . Don't offer in the salary configurator cars for which the future driver is filled . Don't generate a task every time the payroll officer assigns a new driver to the car task-6425360
Spreadsheet users now have a dedicated side panel to review unused pivots and lists instead of triggering checks from the Data menu. This keeps large spreadsheets more responsive and improves detection of unused items across formulas in cells, charts, and other spreadsheet features.
Original PR description
This commit replace the `Unused pivot/list` warning in the `Data` topbar menu by a dedicated side panel. Checking which pivot is unused is an expansive operation, and is not frankly important, removing the pivots only cleans up the JSON. Doing it every time we open the menu can make the menu very slow on big spreadsheets. There was also a problem on how we were checking which pivot was unused. Only the formulas in the cells were checked, not the formulas of cfs/charts/... This commit introduce a new `FormulaProvider` to the core plugins, so they can register their formulas. Task: [6185119](https://www.odoo.com/web#id=6185119&cids=1&menu_id=4720&action=333&active_id=2328&model=project.task&view_type=form)
Shopfloor handling for continuous production has been tightened to avoid creating backorders for now. Users must specify the quantity being produced before closing a manufacturing order, helping prevent inaccurate production records.
Original PR description
In this commit we continue refining continuous production: - No backorder via shopfloor for cont production (for now). - Finishing a WO will not update the qty_producing. Note: Continuous flag on boms were commented out from some tests until the solution to unblock WO's mark as done for continuous production boms is thoroughly discussed. For now, an error is thrown if the user isn't specifying a quantity producing before closing off (producing) the MO through shopfloor. Task: 6384174
The partner follow-up list now hides the Last Reminder column by default because it is not useful for most users. This reduces visual clutter and helps users focus on the information they typically need.
Original PR description
The `Last Reminder` column is not relevant for most users and its position in the partner list makes it unnecessary noise. Hide the column by default. Task-6420573
The TikTok Shop configuration is now located under the new Marketplaces menu. This makes marketplace setup easier to find and keeps related sales channel settings grouped together.
Original PR description
- Move tiktok shop configuration to the new 'Marketplaces' menu PR Ref: https://github.com/odoo/enterprise/pull/113307 Forward-Port-Of: odoo/enterprise#125953
Payroll users can now move several payslips from a pay run to off-cycle processing in one action. This reduces repetitive manual work and makes handling payroll exceptions faster and more efficient.
Original PR description
- Currently, payslips can only be sent to off-cycle one at a time from the Payrun list view using button. - There's no way to send multiple payslips to off-cycle at once. - Add a "Send to Off-Cycle" action to allow sending multiple payslips to off-cycle in a single operation in payrun. task-6320059
Belgian payroll now uses the Belgian reference calendar consistently when calculating work time rates and related payroll values. This improves accuracy for salary offers, payslips, attendance, time off allocation, and payroll reporting while aligning tests with the updated approach.
Original PR description
Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: . Remove standard_calendar_id field and use l10n_be_reference_calendar_id instead for BE. . Use l10n_be_reference_calendar_id instead of company.resource_calendar_id on all computations. . Use version work_time_rate directly instead of version.resource_calendar.work_time_rate to use the reference_calendar_id instead of company_calendar_id . `Resource_Calendar` Model uses the company_hours as reference to compute the work_time_rate . `Version` Model Calendar uses the ref_calendar_hours as reference to compute the work_time_rate . Both `Resource_Calendar` & `Version` Models ignore computations of the work_time_rate for the `Variable Calendars` . Approximate version.work_time_rate to a precision of two decimal places. . Update the corresponding tests task-6292597
Large accounting reports now load and scroll more reliably by only displaying the rows currently visible on screen and reducing unnecessary page elements. This helps prevent browser slowdowns or crashes when users work with thousands of report lines, while keeping the same report experience.
Original PR description
Introduced in https://github.com/odoo/enterprise/pull/96974, this is a new load more mechanism that loads all the new lines. When trying to display 3000+ lines in the browser it would crash as too…
Introduced in https://github.com/odoo/enterprise/pull/96974, this is a new load more mechanism that loads all the new lines. When trying to display 3000+ lines in the browser it would crash as too many components were getting created and the DOM was overloaded. To solve this issue, a virtual grid is used to only render the lines inside the user view (plus a margin of 0.5 view on top + bottom). However, the report lines were not made to be created, updated and deleted this often. The creation and suppression were improved by always keeping the same number of lines rendered. This is done by using a list of lines to display and hiding lines that don't need to be displayed anymore. Since the lines all have a similar height, this number should always stabilize at (user view height) * 2 / 31px. A lot of expensive computations were done when displaying or rendering the lines, such as lines searched or the account status badge. Instead, we opt to calculate them when they are displayed and then store them to not be computed again. A big part of the remaining time is taken by the reactivity system, which greatly increases the time taken and the memory used. This was partially solved by: removing useless reactivity on the controller in different components caching the custom components and templates on the controller. marking the lines as a raw Object to remove the proxy objects of the reactivity which takes a lot of memory and time. This also introduces a lot of breaking changes: - cachedFilterOptions and options are now a signal of a proxy so they need () after accessing them. - virtual lines are a proxy with signal for the primitives so accessing a primitive such as level needs (). - some functions were moved as computed to help reduce the number of renders of components. - using "key" in virtual_line/virtual_cell is advised against since keys are always added and never removed (instead test for the value of the primitive, for example instead of "level" in line use line.level?.()) However, if the key points to an array and not an object, the length is reactive since we want to easily support t-for for arrays. task-5478504
This update standardizes how extra electronic invoicing options are handled when sending account moves for Mexican localization. It helps prevent inconsistent behavior caused by the same information being treated in different formats, improving reliability for affected invoicing workflows.
Original PR description
make extra_edis a list, as it was a list, a set or a dict depending on how we get datas task-4916311
Planning entries now provide a clearer link to related field service sales information, including services and materials. This helps users move from a planned service visit to its associated commercial details more quickly, reducing navigation effort.
Original PR description
task-6140146
Spreadsheet users get a smoother experience after updates to the underlying spreadsheet engine. Large spreadsheets should open key menus faster, and unused pivot/list cleanup is moved into a dedicated side panel so it no longer slows down regular menu use.
Original PR description
See https://github.com/odoo/odoo/pull/279306
Accountants can now create a vehicle directly from a bill using a simplified dialog with only the essential details. When the bill is confirmed, the vehicle purchase value is automatically aligned with the related fixed asset value, reducing manual work and data-entry errors.
Original PR description
- When buying a car, creating a fixed asset in a bill, you are required to select a car. If the car is not there yet, you have to create one to link it to the fixed asset. The creation form is too long and complicated for an account. In this commit: - When selecting the create and edit option, we open a simple dialogue to create The car with the most basic information. - When the bill is confirmed, we set the purchase value equal to the fixed asset value of that vehicle. task-5380674
Belgian payroll now narrows the employee sub-type choices using both the employer category and the employee type. This reduces irrelevant options and automatically selects the sub-type when there is only one valid match, helping avoid payroll setup mistakes.
Original PR description
The Sub-type (formerly "Worker code") selector was only filtered by employer category, so DIMONA category "OTH" shared by both Workers and Employees left irrelevant codes selectable. l10n.be.worker.code now carries employee_type_ids (m2m), mirrored as hr.employee.type.l10n_be_worker_code_ids (replacing the old single default worker_code_id), so the Sub-type domain filters by employer category and employee type together. When exactly one sub-type (code) matches, the field is auto-filled and made readonly. Task-6365032
This update limits Chilean company activities on electronic documents to the maximum supported by Chile's XML requirements. It helps prevent document submission rejections caused by selecting more than four activities.
Original PR description
The Chilean XML schema supports maximum of 4 activities (l10n_cl_company_activity_ids), but we allow to add more than that. If this happens, it causes rejections since electronic documents are being sent with more than 4 options selected, and returning rejection errors. Adding constraint to limit l10n_cl_company_activity_ids task-id: 6329320 Forward-Port-Of: odoo/enterprise#126026 Forward-Port-Of: odoo/enterprise#123856
Brazilian fiscal reform settings were updated to match Avalara API changes by removing an obsolete CBS/IBS taxpayer option. Presumed credit rates now appear automatically for Simplified tax regime users, default to zero, and warn users when configured under other regimes.
Original PR description
The cbsIbsTaxPayer attribute driven by this field no longer exists in the Avalara API. The presumed credit rates (pCredCBSSN/pCredIBSSN) are now shown whenever the tax regime is Simplified, default to zero, and a warning is shown when rates remain configured under another regime. task-6396740
Pakistan payroll tax calculations are updated to use the 2026 income tax brackets. The previous extra tax surcharge mechanism has been removed, helping payroll results align with the latest tax rules.
Original PR description
[IMP] l10n_pk_hr_payroll: update 2026 tax brackets . tax brackets are updated . extra tax surcharge mechanism is deleted task-6401729 Forward-Port-Of: odoo/enterprise#125711 Forward-Port-Of: odoo/enterprise#124988
Resolved issues and error corrections
Fixes an issue where deleting a middle quality check in a manufacturing work order could cause later checks to disappear from the shop floor view. The remaining checks now stay properly connected, helping operators continue the full quality control process without missing required steps.
Original PR description
Steps to reproduce the bug: - Create a BOM for product P1 with one work order WO1 - Create 3 quality points linked to WO1 via the `operation_id` field - Confirm a manufacturing order for P1: - 3…
Steps to reproduce the bug:
- Create a BOM for product P1 with one work order WO1
- Create 3 quality points linked to WO1 via the `operation_id` field
- Confirm a manufacturing order for P1:
- 3 quality checks A → B → C are generated
- Open the shop floor for the work order:
- Observe that all 3 quality checks are displayed
- Delete quality check B (the middle one)
- come back to the shop floor for the work order:
- Observe that quality check C is no longer displayed in the shop floor
Problem:
After deleting check B, check C disappeared from the shop floor. Quality checks are stored as a doubly-linked list via the `next_check_id` and `previous_check_id` fields on `quality.check`. The shop floor JS (`mrp_display_record.js`) traverses this list starting from the check with no `previous_check_id`, then follows `next_check_id` until the chain ends. When check B was deleted, it nullified the FK references pointing to it, leaving check A with `next_check_id = False` and check C with `previous_check_id = False`. The traversal from A therefore stopped immediately, and C was never reached.
No `unlink` override existed on `quality.check` to repair the chain before deletion.
Solution:
Added an `unlink` override that, before deleting each check, reconnects its predecessor and successor: if the deleted check has both a previous and a next, `prev.next_check_id` is set to `next` and `next.previous_check_id` is set to `prev`, preserving a valid chain for the remaining checks.
opw-6369298
Forward-Port-Of: odoo/enterprise#124118The French FEC export tests were updated to align with recent changes in how entry labels are chosen when fallback values are needed. This helps ensure the reporting checks remain accurate and avoids false test failures after the related accounting logic update.
Original PR description
Adjust the FEC export test expectations to match the updated `EcritureLib` fallback logic introduced in the related community change. Related: https://github.com/odoo/odoo/pull/257242 task-5346068 Forward-Port-Of: odoo/enterprise#125684 Forward-Port-Of: odoo/enterprise#112822
This fix ensures that removing the AI Documents app also cleans up its automatic sorting rules. Users can continue uploading documents to previously auto-sorted folders without triggering background errors.
Original PR description
Currently, an error occurs when a user uploads a document. **Steps to Reproduce:** - Install the `ai_documents` module. - Go to `Documents` and create a `folder`, or use an `existing one`. - Open the…
Currently, an error occurs when a user uploads a document.
**Steps to Reproduce:**
- Install the `ai_documents` module.
- Go to `Documents` and create a `folder`, or use an `existing one`.
- Open the `folder` > click `Actions` > `Auto-sort`, and `save`.
- Uninstall the `ai_documents` module.
- Go back to `Documents`, open the `same folder`, and `upload any document`.
- Error is logged in the `terminal`.
`ValueError: Invalid field documents.document.ai_sortable in condition ('ai_sortable', '=', True)`
When the ai_documents module is installed and the user enables Auto-sort for a folder [1], an
automation rule and its linked server action are created [2] (if they do not already exist).
Whenever a document is uploaded to that folder, the automation rule triggers the server action,
which runs the AI prompt to classify and sort the document.
However, when the ai_documents module is uninstalled, the related automation rule and server
action are not removed. As a result, uploading a document to the same folder still triggers the
automation rule. While evaluating its domain, it attempts to access the ai_sortable field, which
no longer exists because it is defined by the ai_documents module, raise the error [3].
This commit ensures that uninstalling the ai_documents module removes the related automation
rules. The linked server actions are then deleted automatically through the field's ondelete='cascade' [4].
[1]: https://github.com/odoo/enterprise/blob/c6d3efb164a23d555e30d0f0f7de3de2ef1d08d3/ai_documents/wizard/ai_documents_sort.py#L100
[2]- https://github.com/odoo/enterprise/blob/c6d3efb164a23d555e30d0f0f7de3de2ef1d08d3/ai_documents/models/documents_document.py#L313-L330
[3]- https://github.com/odoo/enterprise/blob/c6d3efb164a23d555e30d0f0f7de3de2ef1d08d3/ai_documents/models/documents_document.py#L321
[4]: https://github.com/odoo/odoo/blob/2cb2f33c871bf83c74098ada568e167aad24f2a5/addons/base_automation/models/ir_actions_server.py#L17
sentry-7607903354
Forward-Port-Of: odoo/enterprise#124488This fixes errors in the Belgian payroll salary configurator caused by a recent change. It helps ensure the salary setup flow and related automated checks work reliably again.
Original PR description
-New changes that was introduced in odoo/enterprise#121196 cause errors in salary configurator tour.
After saving or resetting a timesheet timer entry, the description field now regains focus automatically. This removes an extra click for users entering multiple timesheets and makes repeated time entry smoother.
Original PR description
Steps to reproduce: - Install the timesheets application. - Open the timesheet timer menu from the systray. - Fill out the new timesheet entry. - Click the 'Save' or 'Reset' button (or use the keyboard hotkey). - Notice that the cursor focus is lost and the user must manually click back into the description field to start a new entry. Cause: - When a user clicks save or reset, the existing form is cleared via a DOM patch. Because the component is not remounted, the initial onMounted focus logic does not execute again. Fix: - Use onPatched to check if the save or discard button is the active element, and automatically re-focus the description input. task-6357438 Forward-Port-Of: odoo/enterprise#125578 Forward-Port-Of: odoo/enterprise#123697
This fixes how US payroll localization is automatically installed when Payroll is used for a US company. It prevents upgrade timing issues by relying on the standard auto-install process instead of a later installation hook, while keeping validation rules from blocking valid module setups.
Original PR description
In a [previous PR], a test was introduced to reject any `l10n_xx_hr_*` module that has a `countries` key in its manifest and depends on a module that also has that country key. This test was too…
In a [previous PR], a test was introduced to reject any `l10n_xx_hr_*` module that has a `countries` key in its manifest and depends on a module that also has that country key. This test was too broad and rejected some valid cases: 1. A non-auto-install module can have a country key defined to add flags in the apps kanban view. ([src]) 2. A module that has a country-specific regular dependency, but not as an auto-install condition. The second case is illustrated by [l10n_us_hr_payroll], which should auto-install when `hr_payroll` is installed and a US company exists. With the old test, achieving this required adding `l10n_us` to its auto-install dependencies. But, since `l10n_us` is not auto-installable, `l10n_us_hr_payroll` would not be installed if you create a DB with a US company and only install `hr_payroll`. In practice, that module was still being installed via a [post-init hook] in `hr_payroll`. This hook was installing all `l10n_XX_hr_payroll` modules for each country where a company is located, which is the behavior of the `countries` parameter in the manifest. This caused issues during upgrades as this runs late in the process: after the auto-discovery phase. Modules installed by this hook would be considered as `uninstalled` until `hr_payroll` is loaded. This commit narrows the check to only fail if: - A module has a `country` key in its manifest, and - It has a country-specific module in its **auto-install** dependencies. Moreover, it modifies `l10n_us_hr_payroll` to correctly rely on the auto_install mechanism instead of the post-init hook. [previous PR]: https://github.com/odoo/enterprise/pull/101843 [src]: https://github.com/odoo/odoo/blob/6df9f92a537aa4bb4ee5dc946fe31c4e56e6dfea/odoo/addons/base/models/ir_module.py#L271-L273 [l10n_us_hr_payroll]: https://github.com/odoo/enterprise/blob/24a33ffb769557be498d61328522bb77f68d3a5a/l10n_us_hr_payroll/__manifest__.py [post-init hook]: https://github.com/odoo/enterprise/blob/85185595cfd1ee5310ceb9dc80c0589accad2f19/hr_payroll/__init__.py#L21 Forward-Port-Of: odoo/enterprise#125853 Forward-Port-Of: odoo/enterprise#120279
Sendcloud shipping declarations now correctly handle products delivered in fractional quantities, such as 0.5 kg of an item sold by the kilogram. This prevents international shipments from being rejected due to mismatched declared item weights and shipment weights.
Original PR description
Issue ----- International deliveries for fractions of items (eg 500g of a product sold by kg) are rejected by Sendcloud. Steps to reproduce ----- - Setup Sendcloud - Fedex international - Create a…
Issue ----- International deliveries for fractions of items (eg 500g of a product sold by kg) are rejected by Sendcloud. Steps to reproduce ----- - Setup Sendcloud - Fedex international - Create a product - weight: 1kg - valid hs code - Create a contact (outside EU if the company is in EU) - Deliver 0.5 of the product to the contact > Error "... parcel not returned from Sendcloud" Cause ----- Sendcloud returns he folloing error: > "The total weight for declared items exceeds the total weight set for the shipment." This is because the `weight` set on the shipment https://github.com/odoo/enterprise/blob/99a13453cac8a7a4677cef3df8896329c90c9e99/delivery_sendcloud/models/sendcloud_service.py#L449-L464 corresponds to the weight of the package, whereas the weight set on the description of the product in `parcel_items` corresponds to the weight of one "full" unit of the product. https://github.com/odoo/enterprise/blob/99a13453cac8a7a4677cef3df8896329c90c9e99/delivery_sendcloud/models/sendcloud_service.py#L327-L335 We cannot change the quantity in `parcel_items` to match the actual delivered one because the field should be an integer. https://sendcloud.dev/api/v2/parcels/create-a-parcel-or-parcels#body-one-of-0-parcel-parcel-items-items-quantity The price is also off, because it gets taken from the `move_line`, so it reflects the price of the actual quantity and not a "full" item. https://github.com/odoo/odoo/blob/208a8a6a5adb8ec1f2710453c2ee3b54c55a9f1e/addons/stock_delivery/models/delivery_carrier.py#L235 Note that this issue is common to **all UoM types**. Solution ----- Since we cannot change the quantity, we can instead adapt the description and weight sent in `parcel_items`. For example, sending 300g of sugar, we would send - description: "Sugar (0.3 kg)" - weight: "0.300" ----- Ticket: opw-6346330 Forward-Port-Of: odoo/enterprise#125893 Forward-Port-Of: odoo/enterprise#124686
UPS commercial invoices now use the customer’s main commercial address as the Sold To address when appropriate, instead of incorrectly reusing the delivery address. If UPS requires the Sold To country to match the delivery country, the system falls back to the delivery address and warns the user, helping prevent failed international shipments.
Original PR description
Issue ----- When making an international delivery to a partner with different invoice and delivery addresses, we send the delivery address as the `Sold To` address as well. Problematic case 1 ----- -…
Issue ----- When making an international delivery to a partner with different invoice and delivery addresses, we send the delivery address as the `Sold To` address as well. Problematic case 1 ----- - Create a belgian company - Setup UPS - Create a French customer - Add a different french delivery address - Create a product (with some weight) - Create a SO (with UPS delivery) to the customer & confirm - Validate the transfer > Commercial invoice `Sold To` uses the delivery address Solution for case 1 ----- Use the delivery address' `commercial_partner_id`. This leads to another issue in some edge cases... Problematic case 2 (caused by case 1 fix) ----- - Create a belgian company - Setup UPS - Create a French customer - Add a delivery address in Switzerland - Create a product (with some weight) - Create a SO (with UPS delivery) to the customer & confirm - Validate the transfer > UPS error `The Sold To party's country code must be the same as the Ship To party's country code with the exception of Canada and satellite countries.` Solution for case 2 ----- Default back to delivery address for the `Sold To` field when countries don't match, as this is a limitation of the UPS API. Warn the user, either on the SO or the transfer itself (if no SO). Warning looks like this (on SO): <img width="1914" height="716" alt="image" src="https://github.com/user-attachments/assets/f7aa73c4-f24c-42da-8f3e-6a58765ef020" /> ----- Ticket: opw-6200263 Forward-Port-Of: odoo/enterprise#123163 Forward-Port-Of: odoo/enterprise#118031
Mexican electronic invoicing now recalculates the Tax Object field when a product's unit price is added or changed. This prevents invoices from keeping a blank tax classification after pricing is updated, reducing manual corrections and compliance risk.
Original PR description
**Steps to reproduce the issue:** - Install the l10n_mx_edi module. - Open the Accounting app and go to Customers → Invoices. - From the invoice line, make the Tax Object field visible. - Create a…
**Steps to reproduce the issue:** - Install the l10n_mx_edi module. - Open the Accounting app and go to Customers → Invoices. - From the invoice line, make the Tax Object field visible. - Create a new invoice and add a product that has no Unit Price. - Save the invoice. - Edit the same invoice, set a Unit Price for the product, and save it again. - Issue: The Tax Object field is not automatically set after the Unit Price is added. **Description:** - In our standard code, there is a condition that skips computing the Tax Object when the Unit Price is [0](https://github.com/odoo/enterprise/blob/615a5f756d708db95e22cdbdd6e7aca72ac769ec/l10n_mx_edi/models/account_move.py#L988). This is the expected behavior. - However, after setting a Unit Price on the product, the Tax Object is not recomputed, so it remains unset. - To resolve this issue, I added price_unit to the @api.depends decorator so that the Tax Object is recomputed whenever the Unit Price changes. **Reference videos:** Before the fix: [screen-capture (2).webm](https://github.com/user-attachments/assets/c1162fd9-52b8-4a8c-9ac2-39cf2ca3ad69) After the fix: [screen-capture (1).webm](https://github.com/user-attachments/assets/1c05dc34-6778-487a-9bfc-635cf652e670) OPW -6305080 UPG - 4268848 Forward-Port-Of: odoo/enterprise#125738 Forward-Port-Of: odoo/enterprise#123009
Odoo Studio no longer crashes when opening forms that include action buttons written as links. This keeps affected views, such as CRM lead forms, editable in Studio and avoids an interruption for users customizing screens.
Original PR description
Opening a view in studio crashed with an "Invalid component props (ViewButtonStudio)" error on records having a button written as an anchor tag, e.g. on the crm lead form:
<a class="..." name="action_set_automated_probability"
role="button" type="object" invisible="..."/>
Since the props migration, useStudioRef declares its own props schema to read studioXpath, and each props() call validates the whole props object against its own schema. Declaring studioXpath as a required string therefore made it mandatory for every component using the hook, even though ViewButtonStudio declares it as optional.
Such anchor buttons are compiled as ViewButtons, but the form editor compiler only puts an xpath on the nodes of its "interesting" selector, which lists "button" and not "a[type]": those buttons have no xpath, and the hook's validation blew up. Before the migration the hook read comp.props.studioXpath, without any validation.Creating a rental order directly from the schedule no longer fails with a server error. This restores a key rental workflow so users can start orders from product time slots without interruption.
Original PR description
Steps ----- - Go to "Rental" > "Schedule" - Click a time slot on a product's row to create an order Issue ----- Creating a rental order from the schedule raises a server error (TypeError: cannot use 'dict' as a set element), so no order can be created from the schedule view. Cause ----- When creating from the schedule, `SaleOrder.default_get` runs with the `convert_default_order_line_values` context and builds the default `order_line` as a list holding a bare values dict, then normalizes it through `convert_to_cache`. The x2many `convert_to_cache` no longer accepts a bare dict: it treats it as an id, so the resulting recordset has a dict in its `_ids` and `convert_to_write` raises when it does `set(self._ids)`. Solution -------- Wrap the built values in `Command.create(...)` so the default `order_line` is a proper ORM create command, which `convert_to_cache` and `convert_to_write` handle correctly.
Several automated checks for Point of Sale accounting and Peru electronic invoicing were corrected after recent accounting changes. This helps keep validation reliable and reduces the risk of future Point of Sale issues reaching customers.
Original PR description
*= pos_settle_due, l10n_pe_edi_pos In this commit: =============== - We have fixed several test cases that are impacted by pos accounting refactor. error-944320,944376,944377,944396,944397,944398,944399,944400,944322,944323, 944315,944319,944314 task-6401593 Related Community PR: https://github.com/odoo/odoo/pull/277655
When correcting a paid payslip from its Correct button, the wizard no longer asks users to choose between correcting one or multiple payslips. This prevents accidental bulk corrections and keeps the process focused on the payslip the user opened.
Original PR description
Steps to reproduce: - Validate and pay two payslips for the same employee - Change a payroll field (e.g. wage) on the employee form, flagging both payslips as having wrong data - Open one of the paid payslips and click "Correct" - The wizard shows the single/multi radio selection Hide the radio selection in the button flow, like the other button-flow-specific elements of the wizard view. The wizard then falls back to its default correction_choice 'single', correcting only the opened payslip. task-6391197 Forward-Port-Of: odoo/enterprise#124468
The bank reconciliation report now includes all unreconciled transactions up to the selected date, not just those from the latest bank statement. This helps accounting teams get a complete view of pending reconciliation work and avoid overlooking older transactions.
Original PR description
The reconciliation report lists only the unreconciled transactions from the last statement instead of all of them Steps: - Create 4 statements with one statement line each with different dates - Go to the reconciliation report (via the three dot menu on bank journal kanban card) - select date as Today -> only the line from the last statement is displayed opw-6250370 Forward-Port-Of: odoo/enterprise#124837 Forward-Port-Of: odoo/enterprise#119386
This fix keeps Australian payroll accounting tests consistent by setting them to run against a fixed date. It prevents date-sensitive payroll reporting rules from causing false test failures, supporting more reliable releases without changing user-facing payroll behavior.
Original PR description
The new qualifying earning rule introduced was breaking the tests that were not frozen in the past as it changed over to the new reporting code. runbot-940160 related too [11736](https://github.com/odoo/enterprise/pull/117367#event-26694075694) Forward-Port-Of: odoo/enterprise#122576
Expense card authorization updates now better preserve the merchant currency instead of falling back to the company currency when currency matching is imperfect. This helps keep expense amounts accurate for international card transactions and reduces accounting confusion.
Original PR description
During updates of the authorization amounts the currency may revert to the company one Specifically, if the merchant currency cannot be found, it defaults to the company currency. We now broaden the search search on currency with the `ilike` operator Task [link](https://www.odoo.com/odoo/project.task/6345203) opw-6345203 Forward-Port-Of: odoo/enterprise#125971 Forward-Port-Of: odoo/enterprise#123772
The timesheet assistant test setup was corrected so test data is prepared before the screen is loaded. This helps prevent false test failures and supports more reliable quality checks for timesheet features.
Original PR description
Before this commit, the component was mounted in the `beforeEach` block before its `onRpc` mocks were registered. This caused the initial data fetch to fail because the mocks were not yet available during initialization. This commit fixes the test by moving the component mount (`doAction`) inside the test block, strictly after the mocks are defined. Forward-Port-Of: odoo/enterprise#123790 Forward-Port-Of: odoo/enterprise#123683
Fixes an issue where extending a work order from the right edge in the Gantt view could crash when dependencies were present. Scheduling changes now complete normally, so dependent work orders can be updated without interrupting production planning.
Original PR description
Resizing a work order from the right edge in the Gantt view updated only the stop date (`date_finished`). Since the work order Gantt view defines dependencies, this triggered dependency propagation…
Resizing a work order from the right edge in the Gantt view updated only the stop date (`date_finished`). Since the work order Gantt view defines dependencies, this triggered dependency propagation through `web_gantt_reschedule`. During that flow, `_web_gantt_move_candidates` needed both the old start and stop dates to update dependent work orders, but the old-value snapshot only contained fields present in `vals`. As a result, `date_start` was missing and the resize crashed with a `KeyError: 'date_start'`. Handle the missing old start date in the generic Gantt dependency propagation flow. When only the stop date is changed, the old start date is added to the old-value snapshot without adding it to the actual write values. This keeps the right-edge resize payload unchanged while giving dependency propagation the values it needs. Steps to reproduce: 1. Create a manufacturing order with work orders. 2. Plan the manufacturing order. 3. Open the Work Order Gantt view. 4. Resize a work order from the right edge to change its planned end date. Before this commit: Right-edge resizing a work order with dependencies crashed during dependency propagation with `KeyError: 'date_start'`. After this commit: Right-edge resizing keeps the changed `date_finished`, dependency propagation has access to the old `date_start`, and dependent work orders are rescheduled without crashing. task-6345347 Forward-Port-Of: odoo/enterprise#122288
This fixes how payroll warnings decide which records they apply to, especially for Belgian DMFA reporting. It reduces confusion in warning setup and helps ensure the right alerts appear in the right payroll and reporting screens.
Original PR description
A previous PR (https://github.com/odoo/enterprise/pull/120063) introduced the new display_on_dmfa field for warnings to be displayed on the DMFA form view. This was initially done because we were…
A previous PR (https://github.com/odoo/enterprise/pull/120063) introduced the new display_on_dmfa field for warnings to be displayed on the DMFA form view. This was initially done because we were anticipating the possibility of having warnings that should be displayed on both DMFA and single models. However, the new direction is that we should only expect warnings to be displayed on DMFA and dashboard or model and dashboard so we can instead use the display_on_model field and set model_id to l10n_be.dmfa. Going forward, the idea is that warnings that have display_on_model set, should work on a recordset of model_id records. This was already what the DMFA warnings were doing by supposing self to be a dmfa record, but this is not the case for many other warnings. To avoid breaking everything, we leave self in the localdict as a reference to the warning record and we add a new value 'record' which will be a recordset of the model defined in model_id. To keep the DMFA warnings working, we substitute self with record in the computation. Also, we remove the default from model_id because, since now the field is always visible, it creates confusion to have it set at hr.employee. Furthermore we take away the possibility of creating new models from the dropdown of the model_id field and we eliminate a constraint on the model of the warning_records, which is only constraining our ability to write warnings without any real upside. Task: 6429645
Swedish SIE4 general ledger exports now use the actual fiscal year dates selected in Odoo, including non-standard fiscal years. This prevents mismatches between the declared fiscal period and the accounting data included in the export, improving accuracy for compliance reporting.
Original PR description
## Issue: Exporting the general ledger as SIE4 set the duration of fiscal years to one year from the starting date of the fiscal year. ## Steps to reproduce: - Create a fiscal year A of one month for…
## Issue: Exporting the general ledger as SIE4 set the duration of fiscal years to one year from the starting date of the fiscal year. ## Steps to reproduce: - Create a fiscal year A of one month for year X-1 (December 1st to December31th year X-1) - Create a fiscal year B of 1 year and 1 month (January 1st Year X to January 31th year X+1) - Create Invoices in November year X-1, December year X-1, year X and in January year X+1 and confirm them - Go to General Leder - Set date to the fiscal year B - Export as SIE4 ### Current behavior: - **for previous fiscal year** - declared fiscal year (#RAR field) goes : - from fiscal year X date_from -1 year - to fiscal year X date_to -1 year - However data are computed: - from fiscal year X date_from -1 year - to fiscal year X date_from -1 day - **for current fiscal year** - declared fiscal year (#RAR field) goes : - from fiscal year X date_from - to fiscal year X date_to - However data are computed: - from fiscal year X date_from - to fiscal year X date_from +1 year ### Expected behavior: Declared fiscal year match the one that is use for computation. - for previous fiscal year - from fiscal year X-1 date_from - to fiscal year X date_from -1 day - for current year - from fiscal year X date_from - to fiscal year X date_to Cause: Current year length was wrong because it [relied on](https://github.com/odoo/enterprise/blob/22b4100006ec24bf6e4b64042cbfdba360fcf470/l10n_se_sie4_export/models/account_general_ledger.py#L139-L140) the next_date_from which was wrong. opw-6264766 Forward-Port-Of: odoo/enterprise#125859 Forward-Port-Of: odoo/enterprise#125354
This fix prevents an error when users propose adding a step from the Shop Floor for manufacturing orders whose bill of materials contains very similar operations. It makes the improvement suggestion flow more reliable for teams using Product Lifecycle Management with manufacturing work orders.
Original PR description
[FIX] mrp_workorder_plm: avoid singleton traceback when matching BOM operations **Issue** Adding a step in a manufacturing order with two operations that are too similar could lead to a traceback…
[FIX] mrp_workorder_plm: avoid singleton traceback when matching BOM operations **Issue** Adding a step in a manufacturing order with two operations that are too similar could lead to a traceback when proposing an improvement from the Shop Floor. **Steps to reproduce** - Install the Product Lifecycle Management app. - Create a BOM for any product with two operations that: - Have the same name and work center - Have no variant - Create and confirm a Manufacturing Order for that product. - Open the Shop Floor view. - Click the gear icon -> Update Instructions -> Improvement Suggestion -> Add a Step -> Propose a Change. -> A traceback occurs **Cause** When adding a step: https://github.com/odoo/enterprise/blob/1c02615b73a2b4fb9f1ab91167a3c8d7c9ac824c/mrp_workorder_plm/models/mrp_workorder.py#L10 It tries to find the corresponding operation in the ECO's new BoM. This relies on `_get_sync_values()`: https://github.com/odoo/enterprise/blob/1c02615b73a2b4fb9f1ab91167a3c8d7c9ac824c/mrp_plm/models/mrp_routing.py#L9-L13 Because two operations share the same name, work center, and no variant, both match the filter: https://github.com/odoo/enterprise/blob/1c02615b73a2b4fb9f1ab91167a3c8d7c9ac824c/mrp_workorder_plm/models/mrp_workorder.py#L39 This results in a singleton error when accessing `operation.id`: https://github.com/odoo/enterprise/blob/1c02615b73a2b4fb9f1ab91167a3c8d7c9ac824c/mrp_workorder_plm/models/mrp_workorder.py#L42 opw-6241880 Forward-Port-Of: odoo/enterprise#123673 Forward-Port-Of: odoo/enterprise#119404
Fixes an issue in Australian payroll where clearing an employee's Tax Treatment Category could cause an error. The system now handles the empty value safely and recalculates correctly once the category is set again.
Original PR description
Currently, an error occurs when a user removes the Tax Treatment Category of an Australian employee. Steps to Reproduce: - Install the `l10n_au_hr_payroll` module with demo data. - Switch to an…
Currently, an error occurs when a user removes the Tax Treatment Category of an Australian employee. Steps to Reproduce: - Install the `l10n_au_hr_payroll` module with demo data. - Switch to an `Australian company`. - Open any `Employee` > `Payroll` > remove the `Tax Treatment Category` value. `UnboundLocalError: cannot access local variable 'code' where it is not associated with a value` After the [change] in selection field behavior, users can clear the value of the field. When the user removes the Tax Treatment Category value, the system computes the tax treatment code [1]. During this process, if no condition matches, the code variable is not initialized. Converting this uninitialized variable to a string [2] raises an error. This commit ensures that when the tax treatment category is not set, the tax treatment code is set to False with an early return. Since the tax treatment category is required field and compute the correct tax treatment code, once the category is set. [change]: https://github.com/odoo/odoo/pull/214422/changes/8d2a42ac419fdf7943a0c11beb8c5de6c6f85bef [1]- https://github.com/odoo/enterprise/blob/017743cbe97b629e9d9f1895b655014d4c3abbcb/l10n_au_hr_payroll/models/hr_version.py#L450-L451 [2]- https://github.com/odoo/enterprise/blob/017743cbe97b629e9d9f1895b655014d4c3abbcb/l10n_au_hr_payroll/models/hr_version.py#L515 No task ID Forward-Port-Of: odoo/enterprise#124067
Resetting a tax return no longer removes unrelated accounting entries that were only reconciled with the return. This protects invoice records and keeps resets limited to the intended tax return carryover entries.
Original PR description
Issue: Moves having a line reconciled to a tax return are unlinked if the tax return is reset. Steps to reproduce: - Set the tax account as reconcilable - Create an invoice for previous month and confirm it - Create a tax return for the previous month - Reconcile one of the invoice tax line to the tax return closing move. - Remove the lock date - Reset the tax return Current behavior: - all moves reconciled with the tax return are unlinked Expected behavior: - only moves comming from recoverable amount of previous tax returns should be unlinked opw-6370289 Forward-Port-Of: odoo/enterprise#125669 Forward-Port-Of: odoo/enterprise#123947
Code cleanup and technical improvements
The spreadsheet chart type selection code was simplified to align with the latest spreadsheet engine update. This is an internal cleanup that helps keep chart editing reliable and easier to maintain, with no expected change to day-to-day user workflows.
Original PR description
With the latest o-spreadsheet version, the patch of `ChartTypePicker` needs to be modified, and it ends up being simpler than before. Task: [6116503](https://www.odoo.com/web#id=6116503&cids=1&menu_id=4720&action=333&active_id=2328&model=project.task&view_type=form)
This update reorganizes how pivot table insertion is handled in Odoo spreadsheets. It should preserve the same user experience while making the underlying spreadsheet code easier to maintain and test.
The Documents PDF viewer now manages its behind-the-scenes page interactions more reliably and with less custom code. This is an internal cleanup that helps reduce maintenance risk while preserving existing PDF viewing, navigation, and drag-and-drop behavior.
Original PR description
Migrated the document-level event listeners (click, mousedown, mouseup, mousemove, keydown) to `useListener` (from `@odoo/owl`), which registers them and cleans them up automatically on component teardown. This replaces the manual `addEventListener` / `removeEventListener` pair that was split across `onMounted` and `onWillUnmount`, and drops the local `_onOutsideClick` holder that only existed to keep a stable bound reference for both calls. The PDF file loading in `onMounted` is now awaited. This code already had test coverage — below are some of the tests that failed when it was commented out, and are now passing again: - @documents/pdf_manager/Pdf Manager basic rendering - @documents/pdf_manager/Pdf Manager: arrow navigation - @documents/pdf_manager/Pdf Manager: drag & drop see commented-out runbot build: https://runbot.odoo.com/runbot/batch/2593682/build/114682467
This update modernizes internal appointment calendar code by replacing an outdated technical pattern with the newer recommended approach. It should not change day-to-day behavior for users, but it helps keep the system easier to maintain and safer to evolve.
Original PR description
- community: https://github.com/odoo/odoo/pull/277775 See commit messages for details. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The way Odoo Enterprise manages color scheme behavior has been reorganized to make it easier to maintain and extend. Existing behavior is preserved for compatibility, so users should not see functional changes.
Original PR description
In this commit, we rewrite the color_scheme service as a plugin. For legacy purposes, we keep the color_scheme service (as a service). We also adapt the codebase to reflect the changes on the service.
This update standardizes the popover cards shown in Map, Gantt, and Calendar-style scheduling views. It reduces duplicated implementations across apps, making future maintenance easier and helping deliver a more consistent user experience.
Original PR description
This commit factorizes the code of the card popovers used in Map, Gantt and Calendar views. Those popovers have been recently introduced [1][2][3], but each with their own implementation. Now that we have a clear picture of the functional needs, we introduce a standard CardPopover component that can be used in the various usecases. [1] task-6310630 [2] task-6358615 [3] task-6310362 Task-6385983
Miscellaneous changes
The transition to Material Symbols broke many translations. These commits apply safe repair to translation where only icon-related classes and data attributes changed.
Original PR description
The transition to Material Symbols broke many translations. These commits apply safe repair to translation where only icon-related classes and data attributes changed.