Daily updates from Odoo
Monday, August 3, 2026
13 changes · master
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