Monday, August 17, 2026
41 changes
6 changes
Resolved issues and error corrections
Invoices in Peru with missing tax information now produce a clear validation error during batch sending instead of causing a background processing failure. This prevents one problematic invoice from blocking other invoices from being submitted to SUNAT.
Original PR description
In l10n_pe_edi, invoices containing lines without tax can't be submitted to SUNAT.
When sending a single invoice, an error message is displayed. However, sending multiple invoices processes them in the background by a cron job. In this case, EDI document creation fails without error handling, raising a generic parsing error and blocking the cron from processing other invoices.
Steps to reproduce:
1. Create and post two invoices with no tax on some lines.
2. From the list view, select both invoices and click "Send" and mark "SUNAT".
3. An exception is raised: `ValueError: XMLSyntaxError("Start tag expected, '<' not found, line 1, column 1")`.
opw-6390480
Forward-Port-Of: odoo/enterprise#127947
Forward-Port-Of: odoo/enterprise#125143The planning field service onboarding tour now matches recent interface changes, helping users complete guided setup without getting stuck. The complete action is also shown in the right place depending on whether users are working in Kanban or Gantt views, reducing confusion during field service scheduling.
Original PR description
## [FIX] planning_field_service: display complete button in popover footer Before this commit, the complete button is displayed in the card even in the gantt popover instead of displaying it in the…
## [FIX] planning_field_service: display complete button in popover footer Before this commit, the complete button is displayed in the card even in the gantt popover instead of displaying it in the footer of the gantt popover. This commit makes sure the complete button in the card is only displayed in the kanban view and that button is displayed in the footer of the gantt view. ## [FIX] planning_field_service: adapt onboarding tour based on recent changes Before this commit, the quick create on resource_ids field in planning.slot has been replaced by a form view inside a modal. The Sign in button in gantt/calendar popover no longer automatically redirects the user to the form view of the intervention and so the user cannot directly complete the shift. This commit adapts the onboarding tour based on the recent changes. It also forces a reload in the gantt view when the user signs in a intervention via the Sign in button in the gantt popover. runbot-error-941063 task-[6353582](https://www.odoo.com/odoo/project/4105/tasks/6353582)
The Documents app now handles the Info & Tags panel more reliably on mobile, especially after reloading, switching views, previewing files, or clearing a selection. This prevents users from seeing an enabled button that opens a hidden or inaccessible panel, reducing confusion when managing documents on phones.
Original PR description
**Steps to reproduce:** - Go to Documents app in mobile - Go to the kanban view - Add some files and select one - Click on `Info & Tags` button in the control panel - Reload the page - Chatter is not…
**Steps to reproduce:** - Go to Documents app in mobile - Go to the kanban view - Add some files and select one - Click on `Info & Tags` button in the control panel - Reload the page - Chatter is not displayed but the button is still enabled - Switching to the list view properly shows it **Issue:** Original fix (see [1]) was not enough for every case. Additional issues: - Chatter hidden on init even when its panel has `visible = true` - State desynchronized with the view when switching menu type (kanban/list) or by previewing a document and coming back - When using the button with an open preview, chatter shows up in the background but is not accessible (and going back discards it) - Removing selection with an open chatter disable the related action **Fix:** - Disable the chatter on mobile init by default to avoid having to manually move it back - Reset chatter on selection removal to avoid getting stuck in the menu - Reset chatter on view switch to avoid being in the wrong state afterwards (and revert the previous css changes) Not a great fix (quite mobile-specific) and there might still be some edge cases. [1] original fix: https://github.com/odoo/enterprise/commit/cf3c2fce8a6b7b2d7547d44a0e4423f887986d52 opw-6061993 Forward-Port-Of: odoo/enterprise#121521
Historical Luxembourg payslips now calculate indexed wages using the wage index that was active at the payslip period end date, rather than today's index. This helps ensure past payroll calculations remain accurate when wage indexes change over time.
Original PR description
Historical payslips incorrectly used today's wage index instead of the index active during the payslip period. Now, salary rules evaluate the indexed wage using `payslip.date_to` via the new `_get_l10n_lu_indexed_wage(date)` contract method. Task: 6395557 Forward-Port-Of: odoo/enterprise#125861
The Dutch reporting module now skips over status records that are missing the accounting entry needed for a chatter message. This prevents one incomplete tax return record from blocking status updates for all Digipoort tax returns.
Original PR description
The `l10n_nl_reports_sbr_status_info` contains the `l10n_nl_reports_sbr.status.service` class. The class is responsible for fetching the status of sent Digipoort tax returns. The status is then posted as a chatter message to the tax return's closing entry. Issues can arise when one of the status service records is, for whatever reason, missing a closing entry. In such case, the message cannot be posted, resulting in an exception being raised. Since the records are processed in a loop without a try-catch, this causes the whole action to fail. This can lead to one broken record effectively shutting down the whole module's functionality. This PR adds some if-else checks to gracefully handle the case where the closing entry is missing. Related tickets: opw-5901446 and opw-6410082 Forward-Port-Of: odoo/enterprise#127844 Forward-Port-Of: odoo/enterprise#125996
When receiving lot-tracked products with putaway rules, the Barcode app now keeps the intended storage shelf for additional scanned lots. This prevents items from being shown in the wrong stock location and helps warehouse teams process receipts accurately.
Original PR description
Steps to reproduce --- 1. Enable Storage Locations and Lots & Serial Numbers. 2. Add a putaway rule sending a lot-tracked product from WH/Stock to WH/Stock/Shelf 1. 3. Confirm a receipt reserving 2…
Steps to reproduce --- 1. Enable Storage Locations and Lots & Serial Numbers. 2. Add a putaway rule sending a lot-tracked product from WH/Stock to WH/Stock/Shelf 1. 3. Confirm a receipt reserving 2 units of that product; putaway sets the reserved move line destination to WH/Stock/Shelf 1. 4. In the Barcode app, scan a first lot, then a second lot. The second lot lands on a separate line at WH/Stock instead of WH/Stock/Shelf 1. Issue --- The first lot reuses the reserved line and keeps its Shelf 1 destination. The second lot cannot reuse it because its tracking number differs, so `_findLine` returns nothing and `_getNewLineDefaultValues` builds a new line with `location_dest_id` set to `_defaultDestLocation()`, the picking's default destination (WH/Stock). https://github.com/odoo/enterprise/blob/314a79b774f30dc9377b2971492576c4b84483e1/stock_barcode/static/src/models/barcode_picking_model.js#L1591-L1601 Putaway relocates the destination on the move line at reservation, never on the picking, so only the reserved line carries Shelf 1. Since `groupKey` includes `location_dest_id`, the new line does not group with the first lot and shows separately at WH/Stock. This is not a regression: new lines have always defaulted to the operation destination. https://github.com/odoo/enterprise/blob/314a79b774f30dc9377b2971492576c4b84483e1/stock_barcode/static/src/models/barcode_picking_model.js#L239-L241 The new line now inherits the selected line's `location_dest_id`, already relocated by putaway, instead of the default. opw-6317077 Forward-Port-Of: odoo/enterprise#127906 Forward-Port-Of: odoo/enterprise#125309
2 changes
Resolved issues and error corrections
Historical Luxembourg payslips now use the wage index that was active at the payslip date instead of the current index. This helps ensure past payroll calculations remain accurate when wage index values change over time.
Original PR description
Historical payslips incorrectly used today's wage index instead of the index active during the payslip period. Now, salary rules evaluate the indexed wage using `payslip.date_to` via the new `_get_l10n_lu_indexed_wage(date)` contract method. Task: 6395557 Forward-Port-Of: odoo/enterprise#125861
8 changes
Enhancements to existing features
Spreadsheet pivot tables can now include calculated fields based on SQL data, expanding what users can analyze directly in spreadsheets. This improves reporting flexibility for teams that rely on pivot views to explore business data without leaving Odoo.
Original PR description
Task: 6442237 Forward-Port-Of: odoo/enterprise#126645
Fixed an access issue that prevented regular timesheet users from creating or duplicating their own assistant rules. The shared user setting is now protected for non-administrators while still allowing users to manage rules intended for themselves.
Original PR description
Steps to reproduce --- - Log in as a user with "User: all timesheets" access rights. - Open the assistant rules list or kanban view. - Create a new assistant rule. Issue --- - Normal users get an…
Steps to reproduce --- - Log in as a user with "User: all timesheets" access rights. - Open the assistant rules list or kanban view. - Create a new assistant rule. Issue --- - Normal users get an Access Error saying "Only Timesheet Administrators are allowed to modify the 'Shared With' field." The create and write methods check for shared_user_ids in the values. When creating a rule, this field is also set by default to the current user, so the check incorrectly blocks the creation. - An Access Error is raised when a user tries to duplicate a rule they don't have access to. - In the kanban view, using the avatar widget raises an Access Error instead of being read-only. Expected behavior --- - Users should be able to create their own assistant rules. - shared_user_ids field should be read-only for non-admins. - Users should be able to duplicate a rule they don't have access to, with themselves set as "Shared With". - The avatar widget should be read-only for non-admins. Fix --- - Move the validation to a constraint on shared_user_ids. - Override copy_data to set shared_user_ids to the current user for non-admins. - Make the kanban avatar widget read-only for non-admins. saas-19.4 replaced the "Shared With" mechanism with an "Applies To" field to control which employees a rule applies to Related - https://github.com/odoo/enterprise/pull/117235 task-6460116
Belgian payroll meal voucher reports now calculate the total value correctly when vouchers are postponed. This helps payroll teams rely on more accurate reporting for employee benefits and related follow-up.
Original PR description
-Adjust the total value for meal voucher report in case of postponed meal vouchers. Forward-Port-Of: odoo/enterprise#127941
Subscription and rental portal pages now use the refreshed sale order layout, making key details such as rental dates, subscription plans, periods, and invoices easier to find in the sidebar. The update also improves status labels and action placement, creating a clearer and more consistent customer experience across related portal pages.
Original PR description
*: sale_renting, helpdesk, planning_field_service, sign Before this commit, subscription and rental portal pages still relied on the previous sale order layout, with key info (rental dates, plan, start/period, invoices,.) living in the main view as table-based blocks. This commit aligns subscriptions and rentals with the upcoming sale order portal design: rental dates, subscription plan/period and invoices are moved from the main view to the sidebar, the intro row is reworked with restyled status badges and inline metadata, sidebar actions are re-hierarchized.. requires: https://github.com/odoo/odoo/pull/264918 task-5404797
Bank statement reconciliation can now match invoices even when payment references are written with minor formatting differences, such as missing slashes. This helps reduce manual reconciliation work and improves automatic matching accuracy.
Original PR description
Before this commit, the "try_auto_reconcile" algorithm was finding moves when there was a perfect match with either the ref of a move line, the move name, the payment reference and now a sanitize version of the payment ref. For example if an invoice had SO12/1234 as the payment reference, if the statement line has a label SO121234 nothing was found. This commit will then add a new non stored computed field to sanitize the payment ref on the invoice level to help those cases task-6119841
Resolved issues and error corrections
Belgian payroll reporting now allocates severance-related periods using the employee's actual departure date through the theoretical notice end date. Seniority is also calculated without including the notice period, helping produce more consistent payroll declarations across quarters.
Original PR description
- previously, the termination period was split from notice period start to actual departure date, ignoring the theoretical notice duration. Now, it correctly splits from actual departure date to theoretical end date, ensuring proper multi-quarter severance (Code 003) allocation. - Seniority calculation no longer includes the notice period, ensuring consistent results regardless of notice duration Task: 5407737
This fixes an appraisal campaign issue where managers without HR permissions could not start campaigns for employees reporting to them. It also prevents campaigns from accidentally applying to all employees when the selected employee list could not be read.
Original PR description
**Issue**: -User without hr rights is not allowed to launch campaigns for employees under him in the hierarchy. -This issue appears only in master, but it discovered another issue from 19.3, where the value for `employee_ids` was not accessed by the normal user. Thus, appraisals are created for all employees in the list, because not selecting an employee means selecting "All Employees". **Solution**: -SUDOing the read to allow the compute to see what the user has selected. Forward-Port-Of: odoo/enterprise#127391
Annotated Deferred Revenue Reports can now be exported to XLSX without triggering a server error. This prevents interruptions for accounting users who rely on spreadsheet exports for review and reporting workflows.
Original PR description
**Steps to reproduce:** * Install the **Accounting** module. * Unhide the **Start Date** and **End Date** fields on invoice lines. * Create and post a customer invoice with deferred dates. * Go to…
**Steps to reproduce:** * Install the **Accounting** module. * Unhide the **Start Date** and **End Date** fields on invoice lines. * Create and post a customer invoice with deferred dates. * Go to **Accounting → Reports → Deferred Revenue Report**. * Add an annotation to a deferred revenue line by clicking the **annotate** from three dots next to the account. * Export the report in **XLSX** format. **Observed behavior:** * The export fails with a server error: `UnboundLocalError: cannot access local variable 'annotations_x_offset' where it is not associated with a value` **Cause:** * The variable `annotations_x_offset` is assigned inside the `for header_level_index, header_level in enumerate(options['column_headers'])` loop, which writes the "Annotations" column header for each header level. * The Deferred Revenue Report produces an empty `column_headers` list, so the loop body never executes and `annotations_x_offset` is never assigned. * When the code later tries to write annotation data for each report line, it references the unassigned variable, causing Python to raise `UnboundLocalError`. **Fix:** * Introduce a boolean flag `annotations_header_written = False` before the header loop to explicitly track whether the "Annotations" column header has already been written. * Inside the header loop, set `annotations_header_written = True` after writing the header. * After writing all individual column headers (where `x_offset` already points to the first free column after all data columns), add a fallback: if `report_annotations` is set but `annotations_header_written` is still `False`, assign `annotations_x_offset` from the current `x_offset` and write the "Annotations" header. opw-6354473 Forward-Port-Of: odoo/enterprise#127840 Forward-Port-Of: odoo/enterprise#122768
Fixed an issue where switching to a pivot view through the AI agent could cause the view to crash or open without selected measures. The AI adjustments now wait until the pivot view is ready, preserving default measures when none are specifically requested.
Original PR description
When the AI agent switched from another view to a pivot view, the pivot view could crash or open without any active measures. The AI controller patch applies the agent's adjustments upon receiving…
When the AI agent switched from another view to a pivot view, the pivot view could crash or open without any active measures. The AI controller patch applies the agent's adjustments upon receiving the `APPLY_AI_ADJUST_MODEL` bus event. However, the event could be processed while the pivot model was still executing `_loadData()`. In that case, the following sequence occurred: * `_loadData()` started and awaited. * The controller patch was executed. * The patch called `toggleMeasures()`. * `toggleMeasures()` waited for `_loadData()` to complete. * `_loadData()` finished and updated the metadata with the available measures. * `toggleMeasures()` resumed and wrote back the metadata snapshot it had taken before waiting. Since `toggleMeasures()` operates on a snapshot of the metadata, the measures populated by `_loadData()` were lost when the snapshot replaced the current metadata, leaving the pivot model without its `measures` metadata and causing the view to crash. Prevent this race condition by waiting for the pivot model initialization to complete before applying the AI adjustments. Also preserve the default active measures when the AI agent does not explicitly request any measures instead of clearing them and opening an empty pivot view. task-6384368