Daily updates from Odoo
Thursday, June 11, 2026
11 changes · 19.0
Enhancements to existing features
This update enhances the synchronization of sales transactions with Fiskaly, the payment processing system. It separates flows for retail and restaurant orders, ensuring more accurate and timely updates are sent, particularly during kitchen synchronization for restaurants. This improves the reliability of payment processing and reporting.
Original PR description
In this commit: ------------------ - Maintain separate Fiskaly transaction flows for retail (short tx) and restaurant (long tx) orders as discussed with the Fiskaly team. - `Initialize order…
In this commit: ------------------ - Maintain separate Fiskaly transaction flows for retail (short tx) and restaurant (long tx) orders as discussed with the Fiskaly team. - `Initialize order transactions` with an empty payload when the `first product` is added. - Start `receipt transactions` with an empty payload when the `first payment line` is added. - For retail flows, no intermediate order updates are sent to Fiskaly before finalization. - For restaurant flows, create additional transaction updates during kitchen synchronization. Ensure already synchronized products are not resent, and only newly added or updated quantities are included in the payload. - `Finalize order and receipt transactions` with complete order lines and payment details when we validate the order. task: 6208963 Reference: <img width="1863" height="1285" alt="de_tss_flow" src="https://github.com/user-attachments/assets/9140788e-7948-4a08-9f11-27197b22ca8b" /> Forward-Port-Of: odoo/enterprise#119765 Forward-Port-Of: odoo/enterprise#117526
Resolved issues and error corrections
This update corrects a bug in the POS system's price conversion for test products. Previously, products without a company assigned would incorrectly convert prices to PEN, causing errors in the refund process. Now, test products are correctly assigned the PE test company, ensuring accurate price display and functionality.
Original PR description
Description of the issue this commit addresses: The POS frontend converts prices using the product's currency_id. Test products created without a company_id had their currency_id fall back to the main company, causing the 5.10 PEN price to be converted unexpectedly and the l10n_pe_edi_pos refund tour to fail its orderline check. --- Desired behavior after this commit is merged: This commit sets the test product's company_id to the PE test company so its currency_id resolves to PEN. This prevents unintended currency conversion in the POS UI and restores the expected displayed price (5.10) in the refund tour. --- runbot-[242597](https://runbot.odoo.com/odoo/error/242597)
This update resolves an issue where users could view financial budgets created in other companies. The fix adds a security rule to the budgeting module, ensuring that users only see budgets associated with the company they are actively working with. This improves data security and prevents unauthorized access to financial information.
Original PR description
**Steps to reproduce:** - Install the `account_reports` module. - Create a new company. - Navigate to Accounting > Configuration > Financial Budgets. - Create a new budget record. - Switch to another company. - Open the list view of Financial Budgets. **Observation:** The budget record created in another company is still visible. **Root Cause:** The model `account.report.budget` does not have any record rule restricting access based on company. As a result, users can see financial budgets belonging to other companies even if they are not connected to them. **Fix:** This commit allows users to hide financial budgets from companies they are not connected to by adding a record rule on `account.report.budget` opw-6083892 Forward-Port-Of: odoo/enterprise#120059 Forward-Port-Of: odoo/enterprise#114771
This update fixes an error in how Odoo validates invoice dates for Colombian DIAN reporting. Previously, the system incorrectly interpreted invoice dates due to timezone differences, causing validation failures. Now, the system accurately uses Bogota local time for date comparisons, ensuring correct DIAN document generation.
Original PR description
**Steps to reproduce:** * Install `l10n_co_edi` module with DEMO DIAN mode enabled. * Go to Accounting > Vendor > Bills and create a new bill. * Select any Colombian partner different from…
**Steps to reproduce:** * Install `l10n_co_edi` module with DEMO DIAN mode enabled. * Go to Accounting > Vendor > Bills and create a new bill. * Select any Colombian partner different from `Consumidor Final`. * Set the invoice date to 6 days in the past. * Select the DIAN Support Documents journal and a product with UNSPSC category. * Confirm the bill and click `Send Support Document to DIAN` after 5 PM Colombia time. **Observed behavior:** * An error is raised stating the issue date cannot be older than 6 days or more than 6 days in the future, even though the invoice date is within the allowed window in Colombia local time. **Cause:** * The date window validation in `_check_move_configuration` used `fields.Datetime.now()` which returns UTC time. Since Colombia is UTC-5, after 5 PM local time the UTC clock has already rolled over to the next calendar day, making a 6-day-old invoice appear 7 days old and failing the validation incorrectly. **Fix:** * Convert the current UTC datetime to the `America/Bogota` timezone and extract its local date before computing the allowed date window. * Compare directly against `move.invoice_date` (a `date` field) instead of using `fields.Datetime.to_datetime()`, keeping the comparison consistent as `date` vs `date`. opw-6011502 Forward-Port-Of: odoo/enterprise#119913 Forward-Port-Of: odoo/enterprise#115256
This update resolves an issue where users with limited accounting rights incorrectly marked invoices as 'Fully Paid' when reconciling bank statements. The fix ensures accurate payment matching and prevents the creation of unwanted Account Receivable lines, maintaining proper financial reporting. It achieves this by safely bypassing a user permission check during automated reconciliation.
Original PR description
### Issue When you have an invoice partially paid via a method using an Outstanding Account, the payment can be kept open, leaving the invoice considered as partially paid If a user with only…
### Issue When you have an invoice partially paid via a method using an Outstanding Account, the payment can be kept open, leaving the invoice considered as partially paid If a user with only "Invoicing & Banks" rights tries to reconcile a Bank Statement with the same partner, amount, and the invoice name as the memo, the automatic reconciliation fails to properly match the payment Instead, the invoice is incorrectly considered as Fully Paid with an unwanted extra Account Receivable line added ### Cause When a new Bank Statement is created, `_try_auto_reconcile_statement_lines()` is called and matches the outstanding credit, which invokes `set_line_bank_statement_line()` This function creates a balancing line and triggers `move._compute_checked()` to update dependencies However, `move.checked` requires `_is_user_able_to_review()` to be True A user with "Invoicing & Banks" rights lacks the `account.group_account_user` group, meaning the move is not marked as checked, preventing dependencies from computing correctly Consequently, the statement line's `amount_residual` is not cleared and the line is not removed from `remaining_st_line_ids` Later in the process, `_try_auto_reconcile_statement_lines()` is called again with `with_user(SUPERUSER_ID)` Because the payment matching was never finalized in the previous step, the engine fallback matches against the full invoice, adding an incorrect Account Receivable line to close it ### Steps to reproduce - Install `accountant` - Go to Accounting / Configuration / Accounting / Journals - Open the Bank, under Incoming Payments tab, set the Manual Payment method's Outstanding Receipts account to 101403 Outstanding Receipts - Update the Demo user's accounting rights to Invoicing & Banks - Log in with the Demo user - Create and confirm an invoice for Acme Corporation (Amount: $1100) - Register a payment on the invoice (Amount: $500, Keep open) - Copy the invoice name - Open the Bank Reconciliation widget from the Accounting Dashboard - Create and add a new Bank Statement Line (Label: Invoice name, Partner: Acme Corporation, Amount: $500) Before the fix, an unexpected Account Receivable line is created and the invoice is marked as Fully Paid ### Notes Instead of processing the entire block under SUPERUSER_ID, which would hide the creator identity in logs and chatter, the context key `skip_account_review_check=True` is injected during the automated statement line reconciliation This safely bypasses the group check inside `_is_user_able_to_review` for this specific automated flow A fallback using `.with_user(SUPERUSER_ID)` is already implemented twice within the same `_try_auto_reconcile_statement_lines` method for this specific use case, but avoiding it here preserves data auditability opw-6077137 Forward-Port-Of: odoo/enterprise#118023
This update fixes an issue where VAT reports in Spain incorrectly showed withholding taxes included in the VAT total. The fix ensures that the VAT column accurately displays only the VAT amount, resolving a discrepancy in reported financial data. This improves the accuracy of VAT reporting for Spanish businesses.
Original PR description
**Steps to reproduce:** * Install `l10n_es`. * Create an invoice/bill with both a VAT tax and a withholding (`retencion`) tax applied. * Confirm the invoice/bill. * Navigate to Accounting → Reports →…
**Steps to reproduce:** * Install `l10n_es`. * Create an invoice/bill with both a VAT tax and a withholding (`retencion`) tax applied. * Confirm the invoice/bill. * Navigate to Accounting → Reports → VAT Books. **Observed behavior:** * The VAT column shows `VAT amount − withholding amount` instead of the VAT amount alone. **Cause:** * `_query_invoices` aggregated **all** lines where `tax_line_id IS NOT NULL` into a single `tax_amount` sum. Withholding taxes (`l10n_es_type = 'retencion'`) produce negative-balance tax lines, so they incorrectly reduced the displayed VAT total. * The XLSX export (`_l10n_es_libros_merge_line_tax`) already handled this correctly by treating `retencion` lines separately and never adding them to `taxed_amount`. The on-screen report lacked the equivalent logic. **Fix:** * `LEFT JOIN account_tax` on `tax_line_id` in `_query_invoices` and exclude `retencion` lines from the `tax_amount` aggregation via `AND tax_line.l10n_es_type != 'retencion'`. opw-6246633
This update resolves an issue in the l10n_mx_edi module related to its dependencies on PINT and CEN. The change inverts the dependency, ensuring proper functionality for Mexican electronic invoicing processes. This fix improves the reliability of the module for our Mexican clients.
Original PR description
X-original-commit: 3675550ec7a8ccc0b4646f8e24aa38a3b52cf36c Forward-Port-Of: odoo/enterprise#119979
This update ensures that orders configured with 'pay after meal' are automatically sent to the preparation display as soon as they are placed, regardless of payment status. Previously, the display wasn't updated until payment was made, which wasn't aligned with the customer's expected workflow. This change improves the user experience and operational efficiency for self-order systems.
Original PR description
When using a self order configuration with "pay after meal" and a valid online payment method. The order would not be sent to the preparation display until the order was paid. This is not expected because the customer is expected to pay after the meal. Steps to reproduce: ------------------- * Setup a self order with pay after meal and a valid online payment method * setup a preparation display linked to the same PoS configuration * Open the PoS and the self order * Make an order with any product and validate it without paying > Observation: The order is not sent to the preparation display Why the fix: ------------ When the configuration is set to "pay after meal", we always send the order to the preparation display. opw-6238352
This update resolves an issue where report customizations made in Odoo's Studio were incorrectly applied to shared layouts, leading to unexpected behavior and potential rendering problems. The fix ensures that report edits are now saved within the report's specific document view, preventing these issues and improving Studio's reliability.
Original PR description
Report edits could be applied on shared layouts such as web.basic_layout instead of the report-specific document view. This caused Studio customization diffs to affect unrelated reports and could also lead to rendering errors when report-specific fields were evaluated in a different report context. The issue occurred because content was inserted directly into the shared layout article section instead of the nested report document view. Steps to reproduce: 1. Open Studio on any module and create or edit a report. 2. Select any of the External, Minimal, or Blank report types. 3. Add content to the report body and save the report. 4. Open another module and create a report using the same report type. 5. Observe that the previous customization is already present. Before this fix, the generated diff could inherit from web.basic_layout. After this fix, body edits are kept inside the report-specific document view. Related Ticket: opw-6245485
This update fixes an issue where both units involved in a quality control failure were incorrectly moved to the designated failure location. The fix ensures that the destination of moved goods is accurately determined based on remaining demand, preventing unintended misdirection of inventory. This improves the reliability of the quality control process.
Original PR description
Version: ---------- - 18.0+ Steps to reproduce: ------------------- 1. Install *quality_control* module. 2. Go to *Settings* and enable *Storage Locations*. 3. Open Quality module go to the Quality…
Version:
----------
- 18.0+
Steps to reproduce:
-------------------
1. Install *quality_control* module.
2. Go to *Settings* and enable *Storage Locations*.
3. Open Quality module go to the Quality control -> Quality points
4. Create a *Quality Point* with:
* *Product* set.
* *Control per* set to *Quantity*.
* *Operation* set to *Receipts*.
* *Failure Location* set to *WH/Stock/Shelf1*.
5. Create a *Receipt* with demand of *2 units* for the product used in QP.
6. Mark the quality check as *To Do*.
7. Update the *Done Quantity* to *1*.
8. Open the quality check and click *Fail*.
9. Update the *Done Quantity* back to *2* and save.
10. Open the quality check again, click *Pass*, and validate the receipt.
11. Open the *Detailed Operations* to inspect move lines.
Issue:
------
* Both units (failed and passed) are moved to the *failure location*.
Cause:
------
When a user fails a move line via the QC wizard, the flow is:
do_fail() → show_failure_message() → confirm_fail()
→ check._move_to_failure_location(failure_location_id, failed_qty)
Inside `_move_to_failure_location`, when `failed_qty == move_line.quantity`,
the condition:
https://github.com/odoo/enterprise/blob/a33f580455a54a81d89a848f7b493d9dcc9ba2b2/quality_control/models/quality.py#L458
e.g. 1 == 1
was True even when `move.product_uom_qty = 2` (demand still 2). It only
compared the done quantities, ignoring that unfulfilled demand remained.
As a result, `move.location_dest_id` was set to the failure location.
Later, when the user increases the quantity from 1 to 2 on the move form,
the flow is:
_set_quantity → process_increase → _set_quantity_done → _prepare_move_line_vals
In `_prepare_move_line_vals` :
'location_dest_id': self.location_dest_id.id,
https://github.com/odoo/odoo/blob/47bf284e1e9d8be0d4255418e0a3f67c74fa5114/addons/stock/models/stock_move.py#L1688
The new move line inherits `move.location_dest_id` directly, which at this
point is already the failure location.
When the user then calls `do_pass()` on the second unit, `do_pass()` only
writes `quality_state = 'pass'` and never touches `location_dest_id`. So
the second (passed) move line silently retains the failure location.
Solution:
---------
Add the guard `move.product_uom_qty <= move_line.quantity` to the condition
so the entire move's destination is only redirected when there is genuinely
no remaining unfulfilled demand:
When demand > done qty, the else-branch runs instead: it reduces the
original move's demand and creates a new separate move pointing to the
failure location, leaving the original move's `location_dest_id` pointing
to stock. Any subsequent move lines created on the original move therefore
correctly inherit the stock destination.
---
opw-6080871
Forward-Port-Of: odoo/enterprise#120041
Forward-Port-Of: odoo/enterprise#112859This update corrects a bug where worked-time leave entries could be duplicated when overlapping with public holidays, particularly with flexible work schedules. The fix ensures public holidays are prioritized, preventing the creation of multiple work entries for the same period and improving payroll accuracy.
Original PR description
Issue: When work entries are generated from Attendances, a worked-time time off created by the Indian sandwich rule can overlap a public holiday and generate duplicate work entries for the same day.…
Issue: When work entries are generated from Attendances, a worked-time time off created by the Indian sandwich rule can overlap a public holiday and generate duplicate work entries for the same day. Steps to reproduce: - Create an employee with Work Entry Source set to Attendances - Use a flexible working schedule on the employee - Configure a public holiday on a scheduled day with work entry type (Paid time off) - Create a time off type with Count as set to Worked Time - Generate time off for the period so the public holiday entry exists (maybe a day before and a the public holiday and the day after) - Open Payroll > Work Entries (Observe the date of the public holiday will have more than 8h entry) Cause: In `_get_version_work_entries_values()`, calendar leaves are split by `hr_holidays` `time_type` into: - leaves: absences and public holidays - worked_leaves: worked-time time off For attendance-based contracts, both sets were turned into work entries without removing overlap between a public holiday and a worked-time leave on the same period. https://github.com/odoo/odoo/blob/3a088e23d3e563c39cdcb252edc8c7cc74981de4/addons/hr_work_entry/models/hr_version.py#L222-L226 For non-flexible calendar: Public holidays and worked-time leaves are both clipped to the static working schedule (e.g. 8h per working day). overlap was kept in both result sets. https://github.com/odoo/odoo/blob/3a088e23d3e563c39cdcb252edc8c7cc74981de4/addons/hr_work_entry/models/hr_version.py#L260 For flexible calendar: The one-day intervals are kept as the actual interval (often 00:00-23:59 for a public holiday). The worked-time on that day is schedule-shaped (e.g. 8h). Subtracting intervals on a full-day public holiday left a 16h fragment instead of removing the public holiday entry. https://github.com/odoo/odoo/blob/3a088e23d3e563c39cdcb252edc8c7cc74981de4/addons/hr_work_entry/models/hr_version.py#L242-L249 Solution: We need to make regular leaves take priority over worked-time leaves, compute the real regular leave intervals first, then remove those intervals from the worked-time leave intervals before work entries are created: - for fully flexible employees, subtract regular leaves from worked leaves; - for flexible calendars, keep one-day regular leaves as is and subtract them from worked-time leaves - for non-flexible attendance-based calendars, clip regular leaves on the static schedule, then subtract them from worked-time leaves clipped on the same schedule. This means that when a sandwich worked-time leave overlaps a public holiday, the public holiday consumes that period first. The overlapping part is then removed from `real_worked_leaves`, so no second worked-time entry is generated for the same public holiday period. opw-6237163 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr