Daily updates from Odoo
Wednesday, July 29, 2026
16 changes · 19.0
Enhancements to existing features
Companies using Chilean electronic invoicing can now select only up to four business activities, matching the official XML requirements. This helps prevent electronic documents from being rejected because too many activities were included.
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#123856
Resolved issues and error corrections
Expense card authorization updates now keep the merchant currency instead of falling back to the company currency when the currency lookup is less exact. This helps keep expense amounts accurate for businesses using Stripe-issued cards across different currencies.
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
The Benefits form now stops users from creating new employee, cost, or mandatory benefit records directly from selection fields. This helps keep salary benefit setup consistent by ensuring related records are created through the proper workflows.
Original PR description
This commit prevents creating new employee, cost or mandatory benefits records directly from the Benefits form by setting these fields' `'no_create'` to `True`. task-5156844 Forward-Port-Of: odoo/enterprise#96770
Resource-based appointments can now use the configured staff member as the event organizer instead of always using the appointment type creator. This prevents the wrong person from being shown as the notification sender or receiving booking updates, and lets businesses adjust the organizer later.
Original PR description
**Steps to reproduce:** - Install Appointment app - Create an appointment_type based on resources - Book this appointment to create the calendar event - The creator of the appointment type is used as the notification sender (organizer) - He also gets notified on each further booking - It can't be changed afterwards **Issue:** `calendar.event` has its `user_id` set using `self.create_uid.id` for event-based appointments when handling the form. Then this `user_id` is used to send the notification mail using the related template. **Fix:** We allow `appointment_type.staff_user_ids` to be used when based on resources, and we try to use its first record as the default organizer instead (so that it can be updated later on). opw-6042615
This fix keeps Australian payroll accounting tests consistent by locking them to a specific date. It prevents recent payroll rule changes from causing unrelated test failures, helping maintain reliable payroll updates.
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)
Accrual list reports now remember the selected "As of" date when users open a record and return via breadcrumbs. This prevents the report from unexpectedly resetting to today's date and helps accounting teams keep reviewing the same period without reapplying filters.
Original PR description
Issue: In accrual list reports (Billed Not Received / Invoiced Not Delivered), selecting an "As of" date, opening a line, and returning with the breadcrumb resets the date filter to the default value…
Issue: In accrual list reports (Billed Not Received / Invoiced Not Delivered), selecting an "As of" date, opening a line, and returning with the breadcrumb resets the date filter to the default value (today's date) Steps to reproduce: 1) Open an accrual list report ( Accounting > Audit > Purchases > Bill to receive / Billed Not Received OR Invoices to be issues / invoiced Not delivered) 2) Pick any "As of" date 3) Open any row 4) Click breadcrumb to return to the accrual list 5) Observe the "As of" date has been reset to today's date To generate some data you could: create a PO, then upload the bill, validate the receipt, then you'll find it in bills received Cause: `AccrualListController.setup()` always initialized state.date with a fresh default date and did not re-put the previously saved `accrual_entry_date` from restored context https://github.com/odoo/enterprise/blob/899f0d45b2ae1dc4e5e06a2e0acb3d006d12d563/account_reports/static/src/views/accrual_list_controller.js#L10-L16 Although `setDate()` stored the selected date in context, `setup()` overwrote the UI state on controller recreation https://github.com/odoo/enterprise/blob/899f0d45b2ae1dc4e5e06a2e0acb3d006d12d563/account_reports/static/src/views/accrual_list_controller.js#L61-L65 Solution: - Persist `accrual_entry_date` in `AccrualListSearchModel` via `exportState()` / `_importState()`, so the date is restored in search context before the list model loads on breadcrumb navigation. - Initialize the date picker through `setDate()` in `onWillStart()` instead of hardcoding `DateTime.now()` in `setup()`, so restoration and user changes share the same code path. - In `setDate()`, reset grouped list caches (`currentGroups` and `groups`) before `root.load()`, because those caches are not keyed on `accrual_entry_date` and would otherwise show stale vendor groups after a date change or breadcrumb restore. opw-6232263 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix ensures that Tyro payment surcharge fees are added to the point-of-sale order before the order is finalized. It helps prevent checkout discrepancies where surcharge amounts could be missed due to timing issues.
Original PR description
Currently when completing a Tyro payment with a surcharge fee in some cases there is a race condition preventing the surcharge line to be added to the pos order before its validation This PR fixes that issue opw-6402191
Uninstalling the AI Documents module now properly removes leftover auto-sorting rules. This prevents errors when users later upload files to folders that previously used AI auto-sort, keeping document workflows running smoothly.
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-7607903354Installing related apps such as Point of Sale no longer resets customized payroll account settings. This preserves manual salary rule account configurations and prevents unexpected accounting changes after adding modules.
Original PR description
### Steps to reproduce: - In a database with Switzerland localization, install 'Accounting' and 'Payroll' - Manually change the debit and credit accounts on the Swiss ELM salary rules (rule code…
### Steps to reproduce: - In a database with Switzerland localization, install 'Accounting' and 'Payroll' - Manually change the debit and credit accounts on the Swiss ELM salary rules (rule code 1000) - Install 'POS' - Check the accounts you configured on the salary rules >The accounts are reset to their default values ### Cause of Issue: POS depends on the module `stock_account`. When `stock_account` is installed, the `_configure_journals` method in its `__init__.py` creates a new `account.journal` for inventory valuation. To apply default values to this journal, the method retrieves data from the chart template. https://github.com/odoo/odoo/blob/7d16ef88784e18e885b97dbded3231775f1349d2/addons/stock_account/__init__.py#L41 The `hr_payroll_account` module overrides `_post_load_data` and unconditionally calls `_load_payroll_accounts(template_code, company)`. https://github.com/odoo/enterprise/blob/fcf06997a0eb999af86e4b6917311a86f04a390e/hr_payroll_account/models/account_chart_template.py#L16-L18 This triggers the reinstallation of the default payroll accounts, which overwrites and discards any manual configuration changes the user has made to their salary rules. ### Fix: Ensure that default payroll accounts are only reset during a genuine chart of accounts loading process, and not during localized post-load operations triggered by other modules. opw-6251112 Forward-Port-Of: odoo/enterprise#121687
Chilean invoice PDF copies now always show the legally required CEDIBLE disclaimer in Spanish. This prevents the footer from appearing in English when the customer's language is not Spanish, supporting correct legal presentation of Chilean electronic invoices.
Original PR description
Steps to reproduce: - Set the database language to Spanish (Latin America). - Create a customer invoice, confirm it and send it to the SII. - Print it using Print > Invoice PDF copy (Chile). - Scroll…
Steps to reproduce:
- Set the database language to Spanish (Latin America).
- Create a customer invoice, confirm it and send it to the SII.
- Print it using Print > Invoice PDF copy (Chile).
- Scroll to the CEDIBLE section at the bottom of the PDF.
Cause of the issue:
The CEDIBLE footer is merged into l10n_cl.report_invoice_document, which account.report_invoice (odoo/addons/l10n_cl/views/report_invoice.xml) renders with t-lang set to the invoice partner's lang, not the database/user language. The disclaimer text was hardcoded in English and relied on the regular translation to be shown in Spanish, so as
soon as the partner's lang field isn't Spanish, the translation lookup falls back to the untranslated English source, regardless of the database language.
Solution:
This disclaimer is boilerplate mandated by Chilean law: it must always be printed in Spanish, independently of the invoice partner's or current user's language. The same template already follows that rule a few lines above for the SII stamp block ("Timbre Electrónico SII..."), which is hardcoded in Spanish instead of relying on translation.
opw-6390207
Forward-Port-Of: odoo/enterprise#124916Changing a payslip to a payroll structure that does not use worked day lines now properly removes old worked day entries. Belgian payroll reporting is also adjusted so off-cycle payslips without worked days still include the correct remuneration amounts.
Original PR description
hr_payroll: Previously, changing to a structure with `use_worked_day_lines = False` (e.g., 13th month) caused `valid_slips` to be empty and return early, leaving stale worked day lines on the payslip. This commit resets the worked_days_lines before filtering for valid payslips. l10n_be_hr_payroll: After fixing the payroll bug and clearing worked_days_lines correctly, the DMFA report fails to correctly consider remunerations since the off-cycle payslips do not have worked_days_lines anymore. This commit backports a fix from odoo/enterprise#106689 to not skip remunerations for payslips with no worked days lines. task-6401942 Forward-Port-Of: odoo/enterprise#124986
Australian payroll no longer crashes if an employee's Tax Treatment Category is temporarily removed. The system now safely leaves the related tax treatment code empty until the required category is set again, helping payroll users continue editing employee records without interruption.
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
The payment status display now refreshes correctly when users move between batch payment records. This prevents outdated payment information from being shown, helping users see the correct signing or initiation status for each batch.
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
Mexican payroll CFDI payslips will now have their SAT validation status refreshed correctly in Odoo. This prevents valid payslip tax documents from incorrectly appearing as unknown, improving payroll compliance visibility for users.
Original PR description
l10n_mx_hr_payroll_account_edi introduces new l10n_mx_edi.document states (payslip_sent, payslip_sent_failed, payslip_cancel, payslip_cancel_failed) but never extends the two hooks the base l10n_mx_edi module relies on to keep sat_state in sync: - _get_update_sat_status_domains(), which builds the domain used by the SAT-status cron (and manual refresh) to pick documents to poll. Payslip states were missing from it, so their SAT status was never fetched at all. - _update_document_sat_state(), which routes a fetched SAT status to a per-source-document handler. It has no branch for the payslip states, so even a manual poll would silently do nothing. As a result, payslip CFDIs validated in the SAT always appeared as "not_defined" in Odoo. opw-6192651
This fixes an issue where Mexican electronic payment XML could show incorrect related-document balances when exchange rate differences were involved. Payments, credit notes, and invoices are now processed in the proper order so fully settled invoices are reported accurately.
Original PR description
### Issue: Attributes of DoctoRelacionado node in the XML display an incorrect value because the exchange rate difference entry distorts the calculation, even though the invoice was fully settled.…
### Issue: Attributes of DoctoRelacionado node in the XML display an incorrect value because the exchange rate difference entry distorts the calculation, even though the invoice was fully settled. https://drive.google.com/file/d/1ntQny0o8bkkfYtY5ZNBK0Yq7Rq0I-yfz/view ### Fix: Sorting partials by "not exchange_move_id" first broke the chronological order whenever the invoice/payment partial itself carried an exchange difference (e.g. a foreign currency payment settled at another rate). This made the residual-chain algorithm consume the credit note's "other_residual" on the wrong payment, so ImpSaldoAnt/ImpPagado/ ImpSaldoInsoluto in the payment CFDI's DoctoRelacionado stayed wrong even though the invoice was fully paid. Populate the exchange move mapping in a separate first pass and sort the partials purely by date/id, so credit notes are always deducted from the correct payment. task-id:[6363092](https://www.odoo.com/odoo/project/49/tasks/6363092) Forward-Port-Of: odoo/enterprise#124882
Automatic bank reconciliation rules now use clearer matching logic and consider transaction amounts, helping avoid incorrect or duplicate rules. Users will also see only reconciliation rules relevant to the selected journal, making bank reconciliation more accurate and easier to manage.
Original PR description
Reconcile models automatically created now use contains instead of match regex and take the amount into consideration when creating the rule as well as checking for existing rules, it's checked whether all of the lines are positive or negative. Added an extra filter on the reconcile models so that it only shows rules that would be applied on the journal, and did some optimizations in the substring matching. task-6140372