Daily updates from Odoo
Friday, July 24, 2026
17 changes · 19.0
Security fixes and vulnerability patches
This fix ensures Belgian POS Blackbox employee clock-in and clock-out records are only visible to users with the appropriate HR permissions. It resolves a failing access-rights test and helps keep employee attendance-related information protected.
Original PR description
Test `test_employee_fields_groups` failed because of the absence of HR group restrictions on the `pos_clock_in_out_ids` field. ----- runbot-938852
Resolved issues and error corrections
Malaysia Statement of Account PDFs now calculate total and overdue amounts using the selected statement date. This keeps the totals aligned with the balances shown in the report, improving accuracy for backdated customer account reviews.
Original PR description
## Current behavior: In Malaysia's Statement of Account, the total and total overdue amounts dont consider the selected Statement Date, and will calculate all the balances up until today in the generated PDF report ## Expected behavior: The total and total overdue amounts should only sum the balances included in the report up until the selected Statement Date ## Steps to reproduce: 1. Install l10n_my_reports module, switch to Malaysian company 2. Go inside Invoicing > Report > Aged receivable 3. Select a specific date in the past 4. Observe that the total amounts dont match with the balance column, and wont change regardless of the date selected ## Cause of the issue: The template used o.total_overdue which ignores the report domain and statement date ## Fix: Accumulate overdue_total in the template loop with the same domain and date_to cutoff as the balance lines, so it always matches the displayed Balance lines for the selected Statement Date opw-6332970
This fixes how Peruvian addresses are formatted in electronic invoices so they match SUNAT's current UBL 2.1 requirements. It helps invoices pass official validation by correctly structuring district and urban subdivision information.
Original PR description
Update electronic invoicing address nodes to align with current SUNAT requirements. This transitions the geographic data formatting from the legacy UBL 2.0 schema to the standard UBL 2.1 specification, ensuring proper structural validation for districts and urban subdivisions. Documentation used: https://cpe.sunat.gob.pe/sites/default/files/inline-files/guia+xml+factura+version+2-1+1+0+(2)_0+(2).pdf opw-6282314
This fix prevents Odoo from automatically selecting a package from a different storage location when counting inventory by barcode. It helps avoid validation errors and keeps inventory counts aligned with the location that was actually scanned.
Original PR description
Steps to reproduce --- 1. Enable Storage Locations, Lots & Serial Numbers and Packages. 2. Put a lot of a product inside a package located in Section 2. 3. In the Barcode app, start an inventory…
Steps to reproduce --- 1. Enable Storage Locations, Lots & Serial Numbers and Packages. 2. Put a lot of a product inside a package located in Section 2. 3. In the Barcode app, start an inventory count, scan Section 1, then scan the product and the lot (without scanning the package). 4. Odoo fills the package from Section 2 on the Section 1 count line; validating fails because the same package cannot be in two locations. Issue --- When a product/lot is scanned, _processBarcode prefills package_id from a matching quant, but the location it passes to the lookup at https://github.com/odoo/enterprise/blob/c30ca22971fb1418f08c5543c646497ffdebbd13/stock_barcode/static/src/models/barcode_model.js#L1506-L1507 is read only from the current line, which does not exist yet while a new line is being created, so locationId is false. With no location, getQuants takes the branch at https://github.com/odoo/enterprise/blob/c30ca22971fb1418f08c5543c646497ffdebbd13/stock_barcode/static/src/lazy_barcode_cache.js#L151-L155 that collects quants across every location, so the lot's quant stored in another location is matched and its package is copied onto the count line. opw-6273909
Customers can no longer pay for planning-based rental services when the required resource is already booked. The cart now checks planning availability before payment, helping avoid failed orders and post-payment issues.
Original PR description
**Problem:** On a website with rental planning enabled, a customer can book a planning-backed rental product through eCommerce even when no planning resource is free for the requested window. The…
**Problem:** On a website with rental planning enabled, a customer can book a planning-backed rental product through eCommerce even when no planning resource is free for the requested window. The cart lets them increase the quantity past the available capacity and proceed all the way through checkout without any availability gate. **Steps to reproduce:** 1. Install `website_sale_renting_planning`. 2. Create a planning role with `sync_shift_rental` and one resource. 3. Create a service product with `rent_ok=True`, `planning_enabled=True` and the role above. 4. Pre-book the resource for some window via a `planning.slot`. 5. From eCommerce, add the product to the cart for the same window. 6. Proceed to checkout/payment. **Current behavior:** The cart is considered ready, no warning is shown, and payment can proceed even though no planning resource is free for the chosen period. **Expected behavior:** The cart should be flagged as not ready and pre-payment validation should refuse to confirm until the customer picks a different date or quantity. **Cause of the issue:** `sale.order._available_dates_for_renting` in `website_sale_renting` is the documented hook for "stock availability" gating of the cart and pre-payment flow (called from `_is_cart_ready` and from `_check_cart_is_ready_to_be_paid`). `website_sale_stock_renting` overrides it to apply a per-line stock check, but `website_sale_renting_planning` has no such override, so planning-backed rental services reach payment with no availability gate at all. **Fix:** Apply the same gating pattern that `website_sale_stock_renting` already uses: override `_available_dates_for_renting` in `website_sale_renting_planning` so that, for each rental line whose product is a planning-synced rentable service, the cart is only considered valid when at least the requested quantity of planning resources is free during the rental window (mirroring the resource and leave filtering already done by `_planning_slot_vals_list_per_sol` at SO confirmation time). This puts the gate at the same point the stock-renting flow enforces it, keeping the public cart/checkout flow consistent across rentable product types. opw-6247034
Manually printed confirmed payslips now save the generated PDF to the payslip record, matching the automatic send flow. This helps payroll teams keep a complete document history in the employee payslip chatter without extra manual uploads.
Original PR description
Right now, manually printing a confirmed payslip from the list view downloads the pdf but never links it to the chatter, unlike the automatic generate and send flow. This backports the fix from the odoo/enterprise#94019 pull request, making the print controller also create the attachment on the payslip. taskid-6391358
Fixed a rounding issue that could show a tiny leftover amount instead of zero in exported Trial Balance reports. This prevents confusion when accounts are actually balanced and improves the reliability of financial report exports.
Original PR description
Steps to reproduce -------------------- - Install account_reports module; - Create a new account; - Create a miscellanous operation for the previous month using thenew account with a credit amount of $8.28; - Create a second MISC for the current month with two lines using the account : debit = 262.67 and credit = 254.39; - Open the trial balance report and filter the new account (end balance should be 0); - Export the report as XLSX; The end balance value is 2.84e-14 due to float rounding issues. opw-6369016 Forward-Port-Of: odoo/enterprise#123896
Sales users without Project permissions can now add products from the catalog on quotations without encountering an access error. The change prevents the system from checking project-related information unless the user has the required rights, reducing disruption in the sales workflow.
Original PR description
A user without Project rights cannot add a product from the catalog on a sale order Steps to reproduce: 1. Install industry_fsm_sale module 2. Go to Settings > Users & Companies > Users and open user Marc Demo 3. Set Field Service and Project rights to No 4. Log in as Marc Demo 5. Go to Sales and open any quotation 6. Click on Catalog in the order lines 7. An access error is raised Issue: industry_fsm_sale overrides `action_add_from_catalog` and tries to read sale.order.tasks_ids but users can't always access this field as it requires Project rights Solution: Check that the user has Project rights before trying to read tasks_ids opw-6315647
Users with manufacturing access but limited sales permissions can now update manufacturing orders linked to rental sales without being blocked by sales order access rules. This prevents unnecessary access errors and keeps production work moving while preserving sales document restrictions.
Original PR description
### Steps to reproduce: - Ensure `sale_stock_renting` is installed - Enable Multi-Steps Routes > Unarchive MTO - Create a product P with a BoM and the routes MTO + manufacture - Create anc confirm a…
### Steps to reproduce: - Ensure `sale_stock_renting` is installed - Enable Multi-Steps Routes > Unarchive MTO - Create a product P with a BoM and the routes MTO + manufacture - Create anc confirm a sale order for A unit of P - Log in with an other user with with mrp User rights and sales User: Own Documents Only (he should not have access to the SO) - Open the MO, add a component line and save #### > Access Error: Blame the following rule: - Personal Order ### Cause of the issue: Writing on the `move_raw_ids` will trigger a call of the `_autoconfirm_production` in order to confirm the newly created move: https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/mrp/models/mrp_production.py#L990-L991 https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/mrp/models/mrp_production.py#L1422-L1423 During this confirmation process, one calls the `_merge_moves` method in order to merge this new move (if relevant) to any already existing one. https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/stock/models/stock_move.py#L1575-L1576 Now, the issue is that, `sale_stock_renting` module overrides the method `_prepare_merge_moves_distinct_fields` determining the fields relevant to the merge by requiring a read access to the `is_rental_order` compute field of the `sale_order` linked to the MO: https://github.com/odoo/enterprise/blob/b66097122ba3a758734ac6fb2b26579c35cb72c2/sale_stock_renting/models/stock_move.py#L34-L40 However, due to the 'Personal Orders' ir.rule, the user does not have a read access to this record: https://github.com/odoo/odoo/blob/e447f4849056a0aab35966fb6ba595ebaadb79ab/addons/sale/security/ir_rules.xml#L44-L49 Community: https://github.com/odoo/odoo/pull/271017 opw-6275658 Forward-Port-Of: odoo/enterprise#121510 Forward-Port-Of: odoo/enterprise#121135
Fixed an issue where importing a Chilean electronic document file with multiple documents could incorrectly combine all invoice lines and references into the first vendor bill. Each document is now handled separately, helping prevent amount mismatches and incorrect vendor bill data.
Original PR description
When importing an EnvioDTE XML containing several DTEs (journal upload or incoming DTE mail server), one vendor bill is created per DTE, but the first bill receives the invoice lines and references…
When importing an EnvioDTE XML containing several DTEs (journal upload or incoming DTE mail server), one vendor bill is created per DTE, but the first bill receives the invoice lines and references of ALL the DTEs in the file, causing the total amount mismatch.
Cause: `_split_xml_into_new_attachments()` creates new attachments for the documents beyond the first one but leaves the original `file_data['xml_tree']` untouched; the decoder must scope itself to the first document (as l10n_it_edi and l10n_es_edi_facturae do), which `_l10n_cl_import_dte()` never did.
e.g. l10n_es_edi_facturae:633:
```python
# Only decode the first invoice of the Factura-e file.
tree = tree.xpath('//Invoice')[0]
```
Fix: scope the tree to the first DTE node before filling the bill. Kept behind a `len > 1` guard so files with a bare <DTE> root (matched by `xpath('//ns0:DTE')` but not by `findall('.//ns0:DTE')`) keep working.
Introduced in: https://github.com/odoo/enterprise/pull/75327.
opw-6378954
Forward-Port-Of: odoo/enterprise#124691Fixes an error that could appear when editing analytic distribution information on employee records with analytic accounting enabled. The change stops tracking a field type that the system cannot safely track, improving stability for payroll accounting users.
Original PR description
This commit partially reverts [1] To reproduce the issue: 1. Enable analytic accounting 2. Try to edit the analytic distribution field on an Employee Error: a traceback appears Commit [1] makes a JSON field tracked, which is forbidden: https://github.com/odoo/odoo/blob/2aa35eb9c7a709126dca65e81ca6e823706fbb19/addons/mail/models/mail_tracking_value.py#L172 We cancel the tracking part of [1] so the production versions will follow the code on master: the field `analytic_distribution` will be both whitelisted and untracked, as done by [2]. [1] https://github.com/odoo/enterprise/commit/88a3e70bba20c2d508f8970d31ce6ee7afd11ee4 [2] https://github.com/odoo/enterprise/commit/55bec464e3861d5023f7e78588142ddc22d500d8 opw-6405122 opw-6416523 opw-6412398 opw-6411399 opw-...
The Stripe expense cardholder field has been corrected so it uses the standard selection behavior. This ensures filters set in the view are properly applied, helping users see only the relevant cardholders when entering expenses.
Original PR description
After https://github.com/odoo/odoo/issues/196785; the standard way to build a custom m2o field in JS is to call a method from the Many2one module, instead of extending an object from it. This commit solves issues regarding domain in the view not being passed to the widget opw-6399906
This update prevents an error that could occur when multiple equity transactions were processed at the same time. It improves reliability for users working with cap tables and equity transaction records.
Original PR description
When the ``_compute_security_price`` method is called on multiple records, a traceback will appear. Traceback: ```py ValueError: Expected singleton: equity.transaction(1, 2) ``` https://github.com/odoo/enterprise/blob/314a79b774f30dc9377b2971492576c4b84483e1/equity/models/equity_transaction.py#L218 The method filters newly created records using ``self._origin.id``. Since ``self`` is the whole recordset, accessing ``self._origin.id`` on multiple records raises a singleton error. sentry-7626410485
This fix prevents a test helper for appointment CRM flows from affecting later steps unexpectedly. It keeps automated validation more reliable, reducing false failures or hidden side effects in quality checks.
Original PR description
Capturing `oldWriteText` at module import and relying on a subsequent tour step to restore it can cause state leakage if the subsequent step doesn't exactly target a resulting effect of the mocked `writeText` call. Refactor the tour step to capture `writeText` dynamically and restore the original method on first call. runbot-241004
Deleting a middle quality check in a manufacturing work order now keeps the remaining checks properly connected. This prevents later quality checks from disappearing on the shop floor, helping operators continue inspections without missing required steps.
Original PR description
Steps to reproduce the bug: - Create a BOM for product P1 with one work order WO1 - Create 3 quality points linked to WO1 via the `operation_id` field - Confirm a manufacturing order for P1: - 3…
Steps to reproduce the bug:
- Create a BOM for product P1 with one work order WO1
- Create 3 quality points linked to WO1 via the `operation_id` field
- Confirm a manufacturing order for P1:
- 3 quality checks A → B → C are generated
- Open the shop floor for the work order:
- Observe that all 3 quality checks are displayed
- Delete quality check B (the middle one)
- come back to the shop floor for the work order:
- Observe that quality check C is no longer displayed in the shop floor
Problem:
After deleting check B, check C disappeared from the shop floor. Quality checks are stored as a doubly-linked list via the `next_check_id` and `previous_check_id` fields on `quality.check`. The shop floor JS (`mrp_display_record.js`) traverses this list starting from the check with no `previous_check_id`, then follows `next_check_id` until the chain ends. When check B was deleted, it nullified the FK references pointing to it, leaving check A with `next_check_id = False` and check C with `previous_check_id = False`. The traversal from A therefore stopped immediately, and C was never reached.
No `unlink` override existed on `quality.check` to repair the chain before deletion.
Solution:
Added an `unlink` override that, before deleting each check, reconnects its predecessor and successor: if the deleted check has both a previous and a next, `prev.next_check_id` is set to `next` and `next.previous_check_id` is set to `prev`, preserving a valid chain for the remaining checks.
opw-6369298This fixes an issue where Avalara tax fields could disappear on customer or vendor contacts in Canada when using a US company setup. Businesses using Avalara can now see and maintain the correct tax codes, partner codes, and exemption details for affected contacts.
Original PR description
**Steps to reproduce:**
- Install Accounting and account_avatax
- Use a US company (by default)
- Create a contact with Canada as country
**Issue:**
In "Sales & Purchase" tab, all the fields from avatax module are not displayed (i.e. "Avalara Code", "Avalara Partner Code", "Avalara Exemption").
**Cause:**
The `invisible` property of those fields is using `fiscal_country_codes` char field.
If no company is set on the record, `fiscal_country_codes` will contain the country code of the selected companies in addition to the country code of the record.
In this case, the value of `fiscal_country_codes` will be `US,CA` string, which triggers `fiscal_country_codes not in ('US', 'CA')` invisible condition.
opw-6328395
Forward-Port-Of: odoo/enterprise#124619Trash cleanup now skips deleted document records whose attachments are still needed by signed documents. This prevents the automated cleanup job from failing and helps keep the database trash clearing normally for all users.
Original PR description
### Before this PR sign.document.attachment_id is an ondelete='restrict' foreign key. When a trashed documents.document shares its attachment with a sign.document, the trash autovacuum _gc_clear_bin unlinks the document, cascades to the ir.attachment, and hits that constraint: ``` update or delete on table "ir_attachment" violates foreign key constraint "sign_document_attachment_id_fkey" on table "sign_document" ``` The autovacuum aborts on the first such record, so the trash stops being cleared for every user on the database. The existing override already skips documents whose res_model is sign.request or sign.document. It misses the shared-attachment case: a document can hold that attachment while its own res_model stays empty or points elsewhere, so the res_model filter never catches it. ### After this PR No error raised during garbage collector because trashed attachment linked to a sign.document are not catched by garbage collector