Tuesday, September 8, 2026
5 changes · saas-18.4
Resolved issues and error corrections
The registration flow now checks for an existing local proxy user before contacting the external IAP service. This avoids rare race conditions that could leave a company database with outdated credentials and prevent later proxy communications until manual re-registration.
Original PR description
In the current flow, _register_proxy_user first calls IAP create_user, then inserts the returned credentials in account_edi_proxy_client.user. At the same time, IAP create_user_2 may replace an existing user with a new one with different credentials before local persistence settles. So Tx A calls IAP and gets credentials for remote user U1. Tx B calls IAP and gets credentials for remote user U2 and unlinks U1. Tx A persists U1 locally. Tx B fails local insert due to a unique constraint. Client DB keeps U1 credentials, but IAP now expects U2. Subsequent proxy calls from the client fail. The DB is left with stale, unusable credentials and cannot recover without re-registration. IAP: https://github.com/odoo/iap-apps/pull/1816 task-6520501 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#285648
Early payment discount entries now preserve the original invoice line's analytic distribution for all discount calculation methods. This prevents reporting details from being lost when invoices use mixed or excluded discount settings, improving accuracy in accounting analysis.
Original PR description
_get_invoice_counterpart_amls_for_early_payment_discount_per_payment_term_line only split the early payment discount amount per invoice line (and thus preserved each line's own analytic distribution)…
_get_invoice_counterpart_amls_for_early_payment_discount_per_payment_term_line only split the early payment discount amount per invoice line (and thus preserved each line's own analytic distribution) when the payment term's early_pay_discount_computation was "included". For "mixed" and "excluded", it instead built a single counterpart line, discarding the analytic distribution of the invoice lines. Compute the per-invoice-line base amounts (and the corresponding price_unit for "mixed") for all three computations, keeping only the tax calculation restricted to "included". This way "mixed" and "excluded" discount entries now keep the analytic distribution of the invoice line they come from, while behavior for "included" is unchanged. Steps: - Create 3 payment terms with EPD, each one with a different `early_pay_discount_computation` setting - For each payment terms, create one invoice with two lines, only one having an analytic distribution - Confirm and pay the 3 invoices (early payment, discount applied) Issue: For 'mixed' and 'excluded', the discount line is the sum of the discount from the 2 invoice lines, and the analytic distribution is lost. opw-6380278 Forward-Port-Of: odoo/odoo#286816 Forward-Port-Of: odoo/odoo#282541
This fixes an issue where approved time off that was shortened, such as after an employee departure date was set, could stop blocking the employee calendar correctly. Payroll calculations now continue to treat those days as time off instead of attendance, helping prevent incorrect payslip worked-day lines.
Original PR description
Problem ------- Fixes bug caused by PR odoo#249527. When a validated time off's dates are shortened while it stays validated (e.g. when the employee's departure date falls int he middle of the…
Problem ------- Fixes bug caused by PR odoo#249527. When a validated time off's dates are shortened while it stays validated (e.g. when the employee's departure date falls int he middle of the leave), the linked resource.calendar.leaves record was unconditionally unlinked. To reproduce: 1. Create and validate a time off request covering a whole month. 2. Register the employee's departure with a departure date in the middle of that time off. 3. Generate the employee's last payslip. The leave is correctly cut at the departure date, but since it never leaves the `validate` state, it never goes through `_validate_leave_request()` again, so its resource.calendar.leaves record is never recreated. The days that were covered by the deleted entry are no longer blocked in the employee's resource calendar, so the payslip's worked day lines (computed from resource.calendar.leaves) count them as attendance instead of time off. Cause ----- `hr.leave.write()` removed the resource.calendar.leaves record any time either the state changed away from `validate` or the leave's dates changed, regardless of whether the leave remained validated. Date-only changes on an already-validated leave never re-trigger validation, so the entry was not recreated. Solution -------- Only remove the resource.calendar.leaves record when the leave actually loses its validated state. When a validated leave's dates change but it stays validated, amend the existing resource.calendar.leaves record in place instead, falling back to creating one if none exists. Related PR: odoo#249527 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#286465
Fixed an issue where automatic bank reconciliation could create journal items with labels in the wrong language or from an unrelated copied model. Labels are now taken in the company's language, making accounting entries more consistent across users and automated processes.
Original PR description
### Problem `label` on `account.reconcile.model.line` is a **translatable** field, but its value is written onto the journal item created when the model is applied (`account.move.line.name`). That…
### Problem
`label` on `account.reconcile.model.line` is a **translatable** field, but its value is
written onto the journal item created when the model is applied (`account.move.line.name`).
That means the label is read in the language of whoever applies the model:
- a user working in another language writes the translated value;
- the auto-reconciliation cron writes the **source** value, since it runs as OdooBot.
So the very same reconcile model ends up writing two different labels on the journal items,
depending on who applied it.
### How it shows up
It becomes visible when a reconcile model is created by **duplicating** an existing one and
the label is then edited while working in a non-source language. The translation holds the
new text, while the source value silently keeps the label of the original model — and the
source value is exactly the one the cron writes. The result is a set of journal items where
some carry the intended label and some carry the label of an unrelated model.
### Fix
The journal item belongs to the company, so the label is read in the **company** language
via a small `_get_aml_label()` helper, instead of the language of the current environment.
It falls back to the current behaviour when the company has no language set.
`_prepare_aml_vals()` is the only place in 18.0 that reads `self.label` for the journal item.
### Test
Adds `TestBankRecWidget.test_auto_reconcile_model_label_uses_company_lang`: a reconcile model
whose line label is translated in the company language, applied by the auto-reconciliation
cron running in the source language, and asserts the journal item carries the company-language
label.
```
odoo -d <db> -u account_accountant --test-enable --stop-after-init \
--test-tags /account_accountant:TestBankRecWidget.test_auto_reconcile_model_label_uses_company_lang
```
Without the fix the test fails with `[{'name': 'Frais bancaires'}] != [{'name': 'Bank fees'}]`;
with the fix it passes. The full `account_accountant` suite was also run on a clean 18.0
database: 203 tests, 0 failed, 0 errors.
Forward-Port-Of: odoo/enterprise#130550
Forward-Port-Of: odoo/enterprise#128433Inventory users without Accounting permissions can now view and create Indian E-Waybills without being blocked by access errors. This helps warehouse teams complete shipping and compliance workflows more smoothly without requiring extra accounting access.
Original PR description
Before this commit Inventory users without Accounting permissions could get an Access Error when viewing or creating an E-Waybill because they could not access the required document types. After this commit Inventory users can now view and create E-Waybills without an Access Error. task-6515093 Forward-Port-Of: odoo/odoo#285023