Daily updates from Odoo
Monday, August 3, 2026
25 changes · master
New functionality added to Odoo
Adds support for Mexican expense workflows by letting employees upload CFDI XML documents directly from an expense. This helps companies handle local compliance needs before the expense is approved and fully connected to the accounting entry.
Original PR description
Currently, the expenses module is not compatible on how the mexican market manages the expenses. The usual way of creating an expense and waiting to approval is not compatible on how in Mexico the expenses are usually done. To target this, a new button is added in the expense form view to upload a CFDI xml and create or link an existing edi document, instead of linking with the accounting entry, allowing to have access to this entry until the expense is approved and the expense is completely linked to the entry target: master task: 4455671
Adds the Slovak VIES Summary Statement for reporting intra-EU goods, services, and triangular transactions to the Slovak Financial Administration. Users can generate the required XML file directly from a dedicated submission wizard, improving compliance workflows for Slovak VAT reporting.
Original PR description
This commit introduces the VIES Summary Statement (Súhrnný výkaz DPH) as required by the Slovak Financial Administration. The report is built on top of the generic EC Sales List engine and aggregates intra-community supplies by customer VAT number and transaction type. It covers intra-community supplies of goods, services and triangular transactions. Also adds a dedicated return type and a submission wizard with direct XML download. Section II (call-off stock transactions) is exported as empty records, as the required call-off stock events are not tracked by standard Odoo data. Documentation: https://www.financnasprava.sk/sk/podnikatelia/dane/dan-z-pridanej-hodnoty/suhrnny-vykaz-dph see https://github.com/odoo/odoo/pull/271293 task-6041417
Enhancements to existing features
The Chilean F29 tax report has been optimized to calculate all report lines in a single process, improving performance and consistency. The update also refines the six-column report layout, tax calculations, withholding sections, and submission flow to better support Chilean tax reporting needs.
Original PR description
This commit optimizes the F29 report by using just one big query to compute the data for all the report lines at once. task-4329648 Forward-Port-Of: odoo/enterprise#106701
Spreadsheet date fields now use Odoo’s standard date picker in calendar buttons. This makes choosing dates in conditional formatting and data validation panels more consistent and easier for users.
Original PR description
DateTimePickerPopover from Odoo is now used in the CalendarButton component of spreadsheet (CF and DV side panels) Task: 5395190
Clicking an unlocated record in the map side panel now opens its form in a dialog instead of taking over the full screen. This keeps users in the map context while they review or edit the record, making Planning map workflows smoother.
Original PR description
Before this commit, clicking on an unlocated record opens the form in fullscreen, which leads to a loss of context. To avoid this behavior, now when a user clicks an unlocated record in the side panel, it's open the form record inside a dialog. Steps to reproduce: - Open Planning - Open the menu Maps > By Resource - Click on an unlocated item on the side panel. task-6369589
The Executive Summary report’s cash row now opens the new cashflow analysis, helping users move directly from headline cash figures to deeper cashflow details. Bank reconciliation labels were also clarified from deposits and payments to cash in and cash out, making the wording easier to understand.
Original PR description
This commit makes the cash row action, of the executive summary report, redirect to the newly added cashflow analysis. task-6373692
The appointment scheduling module was adjusted to stay aligned with related changes in the community version. This helps keep the enterprise feature consistent and easier to maintain, with minimal expected impact for users.
Original PR description
Adjust override definition based on community PR. task-6349421
New appointment types will now automatically use a standard email reminder sent 3 hours before the appointment. This removes manual default reminder configuration, simplifying setup while ensuring external participants still receive reminders.
Original PR description
Removing the possibility to choose the alarm(s) set by default on new appointment types. Using a field on the alarm model for that has been considered a bit weird and overkill. Simplifying things and alarm form by always setting the "email 3 hours" alarm as default for every new appointment types. Using an alarm of type "email" to make sure external users also get the reminder. Also removing the alarm value from the "_prepare_calendar_event_values" method on appointment type to let the compute handle the propagation. Task-6209598
VoIP activity scheduling was simplified behind the scenes so related contacts, leads, tickets, employees, tasks, sales orders, and subscriptions stay aligned more reliably. This reduces maintenance complexity and helps keep the scheduling experience consistent across VoIP-connected business apps.
Original PR description
… fields Remove all @api.onchange in favor of compute/inverse fields for MailActivitySchedule wizards across voip and voip_* modules. Key changes: · Rename res_model_field_selection → res_model_selection, use pure model name keys (e.g. "crm.lead") instead of "model/field" format · Rename _get_res_model_field_selection → _selection_res_model · Convert contact_id, lead_id, ticket_id, employee_id, task_id, sale_order_id, and subscription_id to compute + inverse fields · Replace all onchange logic with compute (default values) and inverse (res_ids sync) methods
Bank statement reconciliation now includes opening balance entries in the reconciliation chain, helping balances stay consistent from the start. The statement error experience has also been improved so accounting users can more easily understand and resolve issues.
Original PR description
This task improves the consistency of the bank statements by adding the opening balance move to the reconciliation chain as well as improving the UX of the statement errors Task ID: 5435413
Resolved issues and error corrections
Ecuadorian invoice printouts now show the company logo in the header again. The header layout was slightly adjusted so the logo fits cleanly within the existing invoice format.
Original PR description
### Issue: In 19.3, the EC invoice header completely replaces the standard header in `report_invoice_document` after commit `08d17cc49c` The company logo was not included in the custom header, leaving invoices without a logo ### Cause: The logo was simply missing from the header template ### Fix: The logo is added and some header elements are resized (`h5` → `h6`, reduced margin) to keep the layout within the existing paper format without requiring a new one ### Steps to reproduce: - Install `l10n_ec_edi` with demo data - Open and print any invoice Before the fix, the company logo is missing from the header opw-6377830 Forward-Port-Of: odoo/enterprise#125469
Fixes an issue where changing and then removing the root report on the Generic Tax Report could cause the Journal Audit report to fail with an internal server error. This ensures accounting users can open the report reliably after configuration changes.
Original PR description
Step To Reproduce: - Install the Accounting module. - Go to Accounting -> Configuration -> Accounting Reports -> Generic Tax Report. - Set the Root Report to "Balance Sheet" and save. - Remove the…
Step To Reproduce:
- Install the Accounting module.
- Go to Accounting -> Configuration -> Accounting Reports -> Generic Tax Report.
- Set the Root Report to "Balance Sheet" and save.
- Remove the Root Report and save again.
- Open Accounting -> Reporting -> Journal Audit.
Issue:
Opening the Journal Audit report raises an Internal Server Error with: psycopg2.errors.UndefinedTable: missing FROM-clause entry for table "account_move_line__move_id"
Reason:
The code that recreates the missing "account.move" join was not updated consistently with the other "_join()" usages. Without calling "._sudo()", the ORM builds the join using a filtered subquery (for example, adding the company filter), which changes the generated join alias(https://github.com/odoo/odoo/blob/saas-19.1/odoo/orm/fields_relational.py#L559). The SQL query still references the regular alias (account_move_line__move_id), causing the query to fail.
Reference PR:- https://github.com/odoo/enterprise/pull/101230
Solution:
Use "query.table._sudo()._join()" when recreating the missing "account.move" join, matching the other "_join()" usages and ensuring the expected join alias is generated.
before fix:-
`'account_move_line__move_id__2': (SQL('JOIN'), SQL('(SELECT "account_move".* FROM "account_move" WHERE "account_move"."company_id" IN %s)', (1,)), SQL('"account_move_line"."move_id" = "account_move_line__move_id__2"."id"'))`
Query : `JOIN (
SELECT
account_move.*
FROM account_move
WHERE account_move.company_id IN (1)
) AS account_move_line__move_id__2
ON account_move_line.move_id = account_move_line__move_id__2.id`
after fix:-
`'account_move_line__move_id': (SQL('JOIN'), SQL('"account_move"'), SQL('"account_move_line"."move_id" = "account_move_line__move_id"."id"'))`
Query : `JOIN account_move AS account_move_line__move_id
ON account_move_line.move_id = account_move_line__move_id.id`
opw-6425842
Forward-Port-Of: odoo/enterprise#125968Users in single-company setups can now change the journal on depreciation models when no company was previously set. This removes a configuration blocker that prevented asset depreciation settings from being updated correctly.
Original PR description
When no company is set on a depreciation model, we only display the `journal_placeholder_id` field which is readonly. But in a single company environment, the 'company_id` field is hidden, therefore it becames impossible to change the journal for depreciation models. Fix: Always display the `company_id` field, but we remove the warning in the onchange when we are in a single company environment. opw-6299390 Forward-Port-Of: odoo/enterprise#121518
The Belgian payroll help text for spouse fiscal status thresholds has been corrected to reduce ambiguity and help users apply the right status. The update also includes the 2026 low-income threshold, supporting more accurate payroll handling for upcoming fiscal rules.
Original PR description
The spouse fiscal status thresholds help text was not accurate enough and could lead to misinterpretation. This commit updates the help text to provide a more accurate description of the thresholds, and adds the low income threshold for 2026. task-6320606
Dragging and dropping planning events no longer crashes when a related resource filter is absent. This keeps scheduling workflows stable after configuration changes in field service planning.
Original PR description
A [recent change](https://github.com/odoo/enterprise/pull/122027/changes#diff-48a8aacbd3dc336e47073b496aa80c310674bc0fd0f84fbb05d9472a9289afe4R264) in `planning_field_service` uses `position="replace"` to completely remove the `resource_ids` field. Because the field is missing from the XML, the frontend never builds `this.data.filterSections.resource_ids`. Dragging and dropping an event blindly assumes this object exists, resulting in a `TypeError` crash. task: 6421678
Attachments now appear consistently in the bank reconciliation list view and kanban view. This helps users see the relevant supporting documents in the right place, reducing confusion during reconciliation.
Original PR description
The aim of this commit is showing the same attachment in the bank reconciliation list view than in the kanban view. Before this commit, the field used to display the attachments was attachment_ids, this field were a related on the attachment_ids from account.move. This fix, removes the related to only keep a domain on the One2Many field. Thanks to the relational database, Odoo is giving us the right attachments when we want to display the field. task-6153002 Forward-Port-Of: odoo/enterprise#124914 Forward-Port-Of: odoo/enterprise#117245
Imported Shopee and Lazada orders now better match the totals shown on each marketplace, including discounts, vouchers, coins, shipping fees, taxes, and minor rounding differences. This reduces reconciliation issues and helps businesses trust that Odoo sales orders reflect the amounts customers paid on the platform.
Original PR description
Marketplace orders with discount lines could not match the platform total: Odoo accumulated a small rounding residue vs Shopee's total_amount / Lazada's order price. sale_shopee ----------- Changes:…
Marketplace orders with discount lines could not match the platform total: Odoo accumulated a small rounding residue vs Shopee's total_amount / Lazada's order price. sale_shopee ----------- Changes: - Fetch buyer-side escrow amounts via `_fetch_order_income` and pass them through `self.env.context` (`order_income`). - Build item lines from the buyer-paid item price with `discount=0` and a recomputed tax-exclusive `price_unit`. - Distribute order-level discounts (seller/platform vouchers and coins) as dedicated negative lines per product tax group via `_prepare_discount_lines_values`. - Append a shipping line from `buyer_paid_shipping_fee` with fiscal-position mapped taxes. - Reconcile any leftover residue with `_adjust_order_total` using a single tax-free amount-adjustment line. - Register `default_discount_product` and configure it on upgrade (v1.1). sale_lazada ----------- - Port the same reconciliation model as shopee: reconciled line specs, discount=0 with discounted unit from paid_price, shipping line from shipping_fee, order-level "Discount line" distributed at order-level. task-6112062 Forward-Port-Of: odoo/enterprise#126004 Forward-Port-Of: odoo/enterprise#117561
Users can now click and edit custom fields directly in the Documents list view. This removes an extra step and makes fields added through Studio behave like standard editable fields.
Original PR description
**Description of the issue/feature this PR addresses:** When adding a custom field (e.g., via Studio) to the Documents list view, clicking the cell directly does not trigger inline edit mode. The…
**Description of the issue/feature this PR addresses:** When adding a custom field (e.g., via Studio) to the Documents list view, clicking the cell directly does not trigger inline edit mode. The user has to first click a standard editable field (like "Owner") to put the row into edit mode before they can modify the custom field. This occurs because we use a hardcoded whitelist (`editableColumns`) of standard fields allowed to trigger edit mode. Custom fields (`x_`) are missing from this static list. This commit resolves the issue by dynamically injecting visible, non-readonly custom fields into the `editableColumns` whitelist. This allows user-created fields to be edited inline as expected. **Steps to reproduce:** - Documents > Studio > List view > Add any field that accepts user input (e.g. Text/char) > save/exit - In the same Documents list view > select a row > click the cell belonging to the newly created field > observe that the row does not enter edit mode - In the same Documents list view > select a row > click a standard editable cell, then click the cell belonging to our newly created field > observe that this then allows us to edit our field **Current behavior before PR:** - Custom fields do not trigger inline edit mode **Desired behavior after PR is merged:** - Custom fields trigger inline edit mode opw-6378102 Forward-Port-Of: odoo/enterprise#125378 Forward-Port-Of: odoo/enterprise#125239
The ESG module now declares a required dependency that it was already using behind the scenes. This prevents automated tests and module loading checks from failing, with no expected change for everyday users.
Original PR description
Before this commit, the esg cog menu imports @base_import/import_records/import_records while esg does not depend on base_import. This goes unnoticed in the backend, where every installed module lands in the same bundle, but a Hoot test file only loads the modules of the dependency closure of its addon, so the first test suite added to esg dies on "error while registering suite". This commit adds the missing dependency. base_import is auto installed on top of web, so it is already there in every database.
This change makes a Swedish Point of Sale test finish its order creation consistently. It reduces random test failures, helping keep automated checks stable without changing day-to-day user behavior.
Original PR description
## Issue The tour `test_l10n_se_pos_01` does not consistently create its `pos_order`. This leads to the following assert failing:…
## Issue The tour `test_l10n_se_pos_01` does not consistently create its `pos_order`. This leads to the following assert failing: https://github.com/odoo/enterprise/blob/0f6f6fac892bc8cec477160a790d52fbf053be99/l10n_se_pos/tests/test_se_pos.py#L40-L42 ## Steps to reproduce 1. Install `l10n_se_pos` 2. Run the test `test_l10n_se_pos_01` 3. **The test fails non-deterministically** ## Fix We use `clickNextOrder()` at the end of the tour to ensure the creation of the order, like other tests already do (e.g., [FinishResidualOrder](https://github.com/odoo/odoo/blob/7fc645e5a3fad9255432e7cc68d47bd0971d3d77/addons/pos_restaurant/static/tests/tours/pos_restaurant_tour.js#L676-L677), [test_name_preset_skip_screen](https://github.com/odoo/odoo/blob/7fc645e5a3fad9255432e7cc68d47bd0971d3d77/addons/pos_restaurant/static/tests/tours/pos_restaurant_tour.js#L1333-L1334), [PosOrderCreationTourPdis](https://github.com/odoo/enterprise/blob/08d5172a8c3310af0c51e18a281c544f83f5aed7/pos_enterprise/static/tests/tours/point_of_sale/pos_tour.js#L141-L142), ...). runbot-238568 Forward-Port-Of: odoo/enterprise#125672
This fix ensures Swiss payroll amounts are rounded directly to the required 0.05 precision instead of using an unreliable manual workaround. It prevents tiny calculation differences from affecting salary declarations and helps payroll reports stay accurate and consistent.
Original PR description
In multiple places within l10n_ch_hr_payroll_elm we use float_round to a precision of 0.01 but then manually round to 0.05 precision. 1. Open a python terminal 2. Enter 1000 % 0.05 >= 0.025 3. See this results to true, even though it shouldn't Fix this by using float_round with a precision of 0.05 instead. https://github.com/odoo/enterprise/blob/7f9cd01ff3dd470b06ae176982fd042243be8f3c/l10n_ch_hr_payroll_elm/models/hr_payslip.py#L102-L105 The change to `ema_declaration.json` is needed as previously it was expected that there was a small difference between salary over the months due to the odd rounding (a difference of like 0.000000000001). Adding the new rounding makes the values equal and test_ema_declaration_2023_01 would fail due to changeSalary no longer being in the computed dict. All the way to master! opw-6322937 Forward-Port-Of: odoo/enterprise#121401
The timesheet overtime indicator now keeps the selected day-based display even when users switch to another language. This prevents confusing changes from days back to hours for multilingual teams using Timesheets.
Original PR description
Steps to reproduce: ------------------- 1. Install Timesheets. 2. Create a new employee with a fully fixed working schedule (40h/week). 3. Open Timesheets > All Timesheets and create a new timesheet…
Steps to reproduce: ------------------- 1. Install Timesheets. 2. Create a new employee with a fully fixed working schedule (40h/week). 3. Open Timesheets > All Timesheets and create a new timesheet in the past week for this employee (e.g. 8 hours). 4. Observe the overtime indicator for the employee (it shows 32 hrs) (Click the left arrow to display it). 5. Change the timesheet encoding unit to "Days / Half-Days". 6. Return to Timesheets and observe the overtime indicator (it now correctly shows 4 days). 7. Install a language other than English (e.g. French). 8. Return to Timesheets and observe the overtime indicator again. Issue: -------- The remaining time value changes unexpectedly and displays 32 hours instead of 4 days. Cause: --------- In `get_timesheet_and_working_hours_for_employees`, the code determines whether the timesheet UoM is expressed in days by comparing the UoM name with the string `"days"`. Since UoM names are translatable, this comparison becomes invalid when the user language changes (e.g. `"jours"` in French), causing the logic to skip the day conversion and return values in hours instead. https://github.com/odoo/enterprise/blob/c48290e90fdeadf4f9ca8c44b035e601e7ed380a/timesheet_grid/models/hr_employee.py#L165-L169 Solution: ----------- Compare the timesheet UoM record with the day UoM record directly instead of relying on translated string values. see commit: https://github.com/odoo/enterprise/commit/5fbf194c5056566453a124812fd2614edfe19a82 opw-6279133 Forward-Port-Of: odoo/enterprise#126256 Forward-Port-Of: odoo/enterprise#120595
The batch payment screen now refreshes the online payment status when users move between records. This prevents outdated status information from being shown, helping users see whether each payment has been signed or is still pending.
Original PR description
To display the `payment_online_status` field, we use a widget called `account_online_payment_refresh_button`. The issue is that the widget don't update the field value when switching from one record to another. Steps to reproduce: 1. Create 2 batch payments 2. Do a payment initiation with the first one, and sign it 3. Do another payment initiation with the second one, but don't sign it. 4. Open 1 batch, and try to switch records with the pager 5. You should see the value is not updated task-6420585 Forward-Port-Of: odoo/enterprise#126278 Forward-Port-Of: odoo/enterprise#125643
Code cleanup and technical improvements
This update standardizes how several enterprise modules describe the data they send to the mail interface, making future changes safer and easier to maintain. It also fixes an issue where one AI prompt setting was sent under the wrong name and therefore was not used by the client.
Original PR description
Enterprise counterpart of "[REF] mail, *: declare the store fields a payload fills", which explains the why and the placement rule. This also fixes are_prompt_from_local_storage, sent under a name the client never reads, so the value landed nowhere. https://github.com/odoo/odoo/pull/279131
The Point of Sale routing layer was reworked to use the newer plugin approach across several related POS modules. This is an internal modernization that helps keep POS screens, appointments, IoT, restaurant, settlement, and delivery integrations compatible with the latest frontend framework.
Original PR description
Convert router service owl2 to owl3 plugin.