Daily updates from Odoo
Wednesday, June 10, 2026
23 changes · 18.0
Enhancements to existing features
This update introduces a new 'PINT' layer in the account_edi_ubl_cii module, bridging the gap between UBL and BIS3 invoice formats. This enhancement supports compliance with European regulations and standards, particularly those related to PEPPOL, by providing a standardized layer for invoice processing and data exchange.
Original PR description
Add the layer PINT between UBL and BIS3. task: 5890887
This update moves a key test case related to UBL (Universal Business Language) billing in Belgium (account_edi_ubl_cii) to the new testing framework. This ensures better test coverage and reliability for our UBL billing processes, improving the overall quality of the system. The change was prompted by a previous update to the test suite.
Original PR description
Move test introduced by https://github.com/odoo/odoo/pull/265261 to the new test suite in account_edi_ubl_cii --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Resolved issues and error corrections
This update fixes an issue where holiday allocation hours were incorrectly set to zero for employees with no working schedule. The change ensures accurate hour calculations, particularly for flexible employees, preventing misallocation of time off. This improves the reliability of holiday tracking.
Original PR description
Pre-requisite: ------------------------------ 1. Install the Time Off module with the demo 2. Working schedule > Duplicate 'Standard 40 hours/week' schedule 3. Rename it > Add any Date in 'Starting…
Pre-requisite: ------------------------------ 1. Install the Time Off module with the demo 2. Working schedule > Duplicate 'Standard 40 hours/week' schedule 3. Rename it > Add any Date in 'Starting Date' for all days of the schedule 4. Create a new employee with this New Working Schedule 5. Create a new Time off type with 'Take Time Off in' field set to 'Hours' Steps to reproduce: ------------------------------ 1. Time off > Management > Allocations 2. Click 'New' > Change time off type to Newly created time off type 3. Add the Newly Created Employee to Allocation Observation: ------------------------------ 1. Allocation hours are automatically set to 0 2. Even after manually updating the hours, saving the record resets them to 0 Issue: ------------------------------ The computed field `number_of_hours_display` relies on `_get_hours_per_day` method to get the hours per day. In the `_get_hours_per_day` method, it will return the calendar hours even when they are 0 and return 24h for the employee with no calendar (fully flexible). This results in allocation hours always being computed as 0 In the previous version, it was not the issue, as we had statically passed 8 hours, If the calendar has no `hours_per_day` https://github.com/odoo/odoo/blob/97bde303ab3dae81215f8a1c52714d44916d79e1/addons/hr_holidays/models/hr_leave_allocation.py#L236 Solution: ------------------------------ 1. For an employee with no working schedule (Fully flexible) returns 24 2. Returned HOURS_PER_DAY (8h) if the calendar has 0 working hours, as allocation with 0 hours makes no sense opw-6042203
This update resolves a problem where the journal report incorrectly displayed tax grids when multiple countries were selected. The fix ensures that all countries are accurately represented in the report, regardless of the number of tax jurisdictions used. This improves the accuracy of financial reporting.
Original PR description
When more than 2 country are used in the taxes, the colspan of the header is wrong. When more than 2 country are used in tax grids, the country isn't displayed anymore. Forward-Port-Of: odoo/enterprise#119348
This update fixes an issue where users without HR access were seeing a placeholder image instead of their avatar in the timesheet kanban view. The fix ensures all users can see their avatar, improving the user experience and visual consistency within the HR timesheet module.
Original PR description
Steps to reproduce: ------ - Install the hr_timesheet module - Create a user without HR access rights - Create a timesheet - Log in with the above user - Open the kanban view Issue: ------- Instead of showing the employee's avatar, a placeholder image is displayed. Reason: --- The user does not have access to the hr.employee model. Fix: -------- In this commit, if the user does not have access to hr.employee, we fetch the image from the hr.employee.public model. task: 4461272 Forward-Port-Of: odoo/odoo#210039
This update fixes a security issue where users could view financial budgets belonging to other companies. The change adds a security rule to the budget module, ensuring that users only see budgets associated with the company they are actively working with. This enhances data privacy and control.
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
This update fixes an issue where HR users couldn't update employee information, specifically related to payroll slip IDs. The change allows HR staff to modify employee records without errors, ensuring consistent data management. This resolves a restriction that prevented updates, streamlining HR processes.
Original PR description
Steps to reproduce: -------------------------- 1. Install l10n_ch_hr_payroll_elm_transmission. 2. Switch to a Swiss company. 3. Create an employee and create a user with HR rights but without Payroll…
Steps to reproduce: -------------------------- 1. Install l10n_ch_hr_payroll_elm_transmission. 2. Switch to a Swiss company. 3. Create an employee and create a user with HR rights but without Payroll rights. 4. Log in with this new user. 5. Update any value on the employee form (e.g., marital status or add a tag). Issue: ----------- Updating the employee raises the following error: ```python You do not have enough rights to access the fields "slip_ids" on Employee (hr.employee). Please contact your system administrator. Operation: read User: 2 Fields: - slip_ids (allowed for groups 'Payroll / Officer: Manage all contracts') ``` Cause: --------- After this 4416eda, open payslips are recomputed automatically on every employee update: https://github.com/odoo/enterprise/blob/8f7a43eebdc8f7f46f9d61ab7084e036c20f778e/l10n_ch_hr_payroll_elm_transmission/models/hr_employee.py#L210-L213 `slip_ids` is restricted to payroll users: https://github.com/odoo/enterprise/blob/8f7a43eebdc8f7f46f9d61ab7084e036c20f778e/hr_payroll/models/hr_employee.py#L14 As a result, when an HR user without payroll rights updates an employee, accessing slip_ids raises an **AccessError**. Solution: ----------- Use sudo() when accessing slip_ids so HR users can update employee records without issue. **NOTE:** The issue has been resolved from version saas~18.4 with the following commits: 279f09a9587674c035c514f966788a4dddfe9794 and 75d66d8 opw-6210358
This update resolves an issue where SEPA QR codes were occasionally displaying incorrect decimal places due to floating-point calculations in the system. The change ensures the QR code amount accurately reflects the currency's precision, preventing potential payment errors. This improves the reliability of vendor bill payments generated via QR code.
Original PR description
**Description of the issue/feature this PR addresses:** When generating a SEPA QR code for a vendor bill payment, the embedded amount could occasionally contain excess decimal places instead of…
**Description of the issue/feature this PR addresses:** When generating a SEPA QR code for a vendor bill payment, the embedded amount could occasionally contain excess decimal places instead of respecting the currency's expected precision. This occurs because the `amount` variable in `_get_qr_vals` was being converted directly using `str(amount)`. Due to Python's floating-point arithmetic, the float value in memory can contain decimal drift. Directly casting it to a string exposes this drift in the payload. This commit resolves the issue by replacing `str(amount)` with `float_repr(amount, currency.decimal_places)`. This safely bypasses the float representation issue, ensuring the string strictly respects the currency's configured decimal precision before being injected into the QR code. opw-5504258 **Steps to reproduce:** - Select company “My Belgian Company” - Create a 23% purchase tax - Create vendor bill - Select Vendor “BE Company CoA” - Choose any single product, change price to 37.18 and choose the 23% tax. The Untaxed Amount should be 37.18, VAT tax should be 8.55, and Total should be 45.73 - Confirm > Register Payment > scan QR code. EUR45.730000000000004 should show **Current behavior before PR:** - When generating a SEPA QR code for a payment, the embedded amount can contain excess decimal places due to floating-point drift. **Desired behavior after PR is merged:** - The SEPA QR code is generated with the correct number of decimal places. Forward-Port-Of: odoo/odoo#267293
This update fixes a bug where untaxed invoice lines were incorrectly inheriting the Datev code from the previous line, leading to inaccurate reports. The change ensures that untaxed lines now correctly have an empty Datev code, resolving a reporting discrepancy. This improves the accuracy of financial reports generated for German businesses using the Datev system.
Original PR description
**PROBLEM** Untaxed move lines would take the datev code of the previous line instead of having no datev code like they should. **STEP TO REPRODUCE** 1. On a german company, create an invoice with a line with tax 19% I, and a line that is untaxed (with a non-null price). 2. On the general ledger, generate the datev zip. 3. Unzip, and open the account entries csv, and notice the 2nd line of the invoice as the datev code set to something instead of it being empty (column BU-Schlüssel). opw-6141003 Forward-Port-Of: odoo/enterprise#118486
This update resolves a problem where DHL delivery confirmations were failing due to incorrect scheduled dates (past dates). The system now automatically sets a future date (one hour ahead) to ensure successful confirmation, preventing delivery errors and improving order processing.
Original PR description
When confirming the delivery of an order using DHL shipping method we get an error that the date must be in the future. This happens when the scheduled date was not set, or set for a time in the past. This commit automatically sets the time to 1 hour in the future and bypasses the user error. opw-6148927 Forward-Port-Of: odoo/enterprise#116211
This update resolves a rounding issue that occurred when generating PEPPOL invoices, specifically impacting unit prices. The change reverts a previous update that introduced this problem, ensuring accurate pricing calculations for international transactions. This improves the reliability of invoices for our business partners using PEPPOL.
Original PR description
Reverts https://github.com/odoo/odoo/pull/262242 opw-6293201
This update resolves a problem where the PDF Quote Builder generated incorrect data due to how it handled temporary records during the demo setup. The fix ensures that all data changes are immediately applied within the transaction, preventing inconsistencies and errors when the builder is enabled. This ensures the PDF quote builder functions correctly after demo data is used.
Original PR description
Steps to produce: --- - Install sale_management and website_sale modules with demo data. - From settings, disable the PDF Quote Builder. - Go to Settings > Technical > Sequences & Identifiers >…
Steps to produce:
---
- Install sale_management and website_sale modules with demo data.
- From settings, disable the PDF Quote Builder.
- Go to Settings > Technical > Sequences & Identifiers > External Identifiers.
- Delete the `consu_delivery_02_product_template` identifier.
- From settings, try to enable the PDF Quote Builder again.
Issue:
---
```py
insert or update on table "quotation_document_sale_pdf_form_field_rel" violates foreign key constraint
"quotation_document_sale_pdf_form_fie_quotation_document_id_fkey"
DETAIL: Key (quotation_document_id)=(1) is not present in table "quotation_document".
```
Cause:
---
When the XML demo loader processes **`sale_pdf_quote_builder_demo.xml`**, it calls `create()` on `quotation.document` for each of the 5 demo records one by one. Each create() call receives vals_list that contains datas, the actual PDF base64 content.
Inside `super().create(vals_list) `[1], the ORM writes datas to `ir_attachment`. Since `form_field_ids` is a `store=True` computed field with `@api.depends('datas')` [2], the ORM knows it needs to recompute `form_field_ids`. But it does not run the computation immediately. It simply registers the records in a pending recompute set and moves on. Nothing hits the DB yet for this compute.
After `super().create() `returns, the `write({'res_model': ..., 'res_id': ...})` runs. Since `res_model` and `res_id` live on `ir_attachment` (the parent table via _inherits), this write is also not immediately flushed to the DB. The ORM marks it as dirty in the cache and defers it.
So after all 5 records are created, the ORM holds two deferred things: a dirty UPDATE ir_attachment write for all 5 records, and a pending recompute for `form_field_ids` on all 5 records. Nothing has been flushed to the DB yet.
When the demo XML tries to reference `product.consu_delivery_02_product_template` [3], which no longer exists,
a ValueError is raised. From `load_demo()` [4], the savepoint is rolled back.
After the except block logs the failure, execution continues in l`oad_module_graph()` which calls `env.cr.commit()`. This triggers f`lush() -> transaction.flush() -> flush_all() -> _recompute_all()`. The ORM processes the pending recompute registry and finds `form_field_ids` needs recomputing for quotation.document(1, 2, 3, 4, 5). It calls `_compute_form_field_ids`() on those stale ids. Inside that compute, `_create_or_update_form_fields_on_pdf_records()` tries to insert into `quotation_document_sale_pdf_form_field_rel` with quotation_document_id=1. But quotation_document id 1 no longer exists in the DB — it was rolled back — so PostgreSQL raises the foreign key violation.
This is confirmed by the traceback from `_compute_form_field_ids`, which shows the call chain going through `commit() -> flush_all() -> _recompute_all()` rather than through `create()`, proving the compute fired after the rollback using stale ORM cache state.
Fix:
---
Calling `docs.flush_recordset()` at the end of `create()` forces all pending writes and pending recomputes to be executed immediately, while still inside the savepoint scope:
- It flushes the dirty res_model/res_id write on the ir_attachment parent table, so UPDATE ir_attachment hits the DB inside the savepoint.
- It triggers `_recompute_all()` for the pending `form_field_ids` compute on docs, so `_compute_form_field_ids()` runs inside the savepoint and the INSERT into `quotation_document_sale_pdf_form_field_rel` happens while the quotation_document rows still exist in the DB.
If the savepoint then rolls back, the ORM cache has nothing dirty or pending left. The subsequent commit() in `load_module_graph()` finds nothing to flush, so no stale writes execute against non-existent ids and no foreign key violation occurs.
[1]https://github.com/odoo/odoo/blob/8791cdcd89ea3cb56b1fac63b3e2ffbd2956a912/addons/sale_pdf_quote_builder/models/quotation_document.py#L93-L98
[2]https://github.com/odoo/odoo/blob/8791cdcd89ea3cb56b1fac63b3e2ffbd2956a912/addons/sale_pdf_quote_builder/models/quotation_document.py#L62-L71
[3]https://github.com/odoo/odoo/blob/8791cdcd89ea3cb56b1fac63b3e2ffbd2956a912/addons/sale_pdf_quote_builder/data/sale_pdf_quote_builder_demo.xml#L44-L51
[4]https://github.com/odoo/odoo/blob/8791cdcd89ea3cb56b1fac63b3e2ffbd2956a912/odoo/modules/loading.py#L89-L90
opw-6139555
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis update improves the security of our bank account import process. It now only uses bank accounts designated as 'trusted' (with `allow_out_payment=True`) when matching partner information. This prevents potential errors and ensures data accuracy during bank account retrieval.
Original PR description
Restrict the matching domain to bank accounts with `allow_out_payment=True` so that only trusted bank accounts are used when retrieving a partner from a bank account number
This update fixes an issue where product matching by name was incorrectly associating products across multiple lines in imports. The fix adds a necessary cache key, ensuring that products are matched accurately based on their unique characteristics, preventing incorrect product assignments during import processes. This improves data integrity and import accuracy.
Original PR description
**PROBLEM** When retrieving a product by name, there is no cache_key for the search_method criteria. This leads to the cache_key frozendict being an frozen dict with None values. This means, once we retrieve a first product with the search_method criteria, all following product will match its cache_key, so we ends up associating a product to all subsequent lines, even if they don't have anything in common. **STEP TO REPRODUCE** 1. Create a product with the name: "CASTELTORRE MERLOT DELLE VENEZIE 75CL 10,5i" (it's important the name is not exactly matching) 2. Import the xml which is attached to the bug fix ticket. 3. Notice the product column on all the lines after a certain point have the CASTELTORRE product, even though the corresponding line in the ubl is for another product. opw-6227280
This update fixes a minor inconsistency in Polish VAT invoice calculations (l10n_pl_edi) related to unit prices. Increasing the precision of the unit price field ensures that the total without tax accurately reflects the invoice amount, aligning with FA(3) format requirements. While technically valid, this change improves invoice accuracy and data consistency.
Original PR description
**STEP TO REPRODUCE** 1. Create an invoice with a unit price of 10.005 and qty of 2. 2. Send the invoice to ksef. 3. Open the xml and notice P_9A (unit price) is 10.00 and P_11 (total without tax) is 20.01 Which is inconsistent (10.00 * 2 =/= 20.01). This PR increase the decimal places of P_9A to 8 digits which is the maximum allowed by the FA(3) format. Note that Ksef doesn't verify the untaxed unit price * quantity = total without tax, so the invoice we send are technically valid. However, it's best to generate invoice where the numbers add-up. opw-6203896
This update fixes an issue where refunds made from the PoS interface didn't accurately update the quantity invoiced on the associated sale order. The fix ensures that refund lines are correctly considered when calculating the invoiced quantity, resolving a previous inconsistency between PoS and backend refund processes.
Original PR description
When making a refund of a PoS order that was created from a sale order, the sale order qty_invoice was not updated correctly. Steps to reproduce: ------------------- * Create a sale order with any product and confirm it * Open a PoS and settle the order * At this point the qty_invoiced should be 1 on the sale order line * Refund the PoS order from the PoS > Observation: The qty_invoiced is still one. Why the fix: ------------ We now take refund lines into account when computing the qty_invoiced. Note: ------------ There was an inconsistency between a refund made from the PoS and a refund made from the backend. The former is not linking the sale order line to the refund line, while the latter does. This was causing issue when refunding from the backend as it would count the refund twice. To fix this we now remove the link to the sale order line when refunding from the backend. opw-4991405
This update resolves a problem where PDF links within the Odoo viewer were not working correctly. The fix adjusts the layering of elements to ensure clicks are properly directed to the PDF links, improving document navigation. This ensures users can reliably access links within PDF documents.
Original PR description
Version - 18.0 Steps to reproduce: 1. Upload a PDF document containing bookmarks and internal/external links 2. Open the document 3. Click on the links, some work and some do not Issue: `canvas_layer_0` is positioned over the PDF viewer with `z-index: 1`, intercepting clicks intended for PDF link annotations and making internal/external links unresponsive. The `.textLayer` already has `z-index: 2 !important` in iframe.css to prevent the same problem for text selection Fix: Added `z-index: 2 !important` to `.annotationLayer section` in `iframe.css` raising it above `canvas_layer_0`. Taskid = 6237688
This update resolves a requirement from Luxembourg auditors regarding the classification of partners in our SAFT reports. Specifically, it ensures that less than 30% of transactions with payable or receivable accounts have missing supplier or customer IDs, aligning with Luxembourg's FAIA reporting standards. The changes automatically update partner listings and maintain compatibility with older report formats.
Original PR description
This PR is one of many triggered by responses from Luxembourg auditors. See PR #113316 for a full list of these PRs. As described in PR #117799, the \CustomerID and \SupplierID elements on…
This PR is one of many triggered by responses from Luxembourg auditors. See PR #113316 for a full list of these PRs. As described in PR #117799, the \CustomerID and \SupplierID elements on \Transaction\Line elements is determined by a partner's `customer_rank` and `supplier_rank`. This is a binary designation, one or the other. The Luxembourg FAIA report requires that less than 30% of \Transaction\Line elements with payable accounts (class 6) can not have \SupplierID. The same applies for \Transaction\Line elements with receivable accounts (class 7) and the \CustomerID element. TSB clarified that any partner on an receivable or payable line should be added to the Customer list or Supplier list respectively https://github.com/odoo/enterprise/pull/100749#issuecomment-3655127511. In addition, I verified that Luxembourg's analysis of four separate FAIA files (from ticket 5427296) aligns with this expectation. <img width="1322" height="690" alt="image" src="https://github.com/user-attachments/assets/1a82f99e-5b32-4dbb-96e1-1b25bab2629b" /> This commit adds partners to the \Supplier and \Customer lists if they have any payable or receivable lines, respectively. It also picks between the \CustomerID and \SupplierID based on a line's `account_type`. This logic is applied to `account_saft` and updates the other, country-specific SAFT reports where appropriate. It also retains the previous `customer_rank` and `supplier_rank` logic as a fallback for older XML reports and for accounts other than `asset_receivable` or `liability_payable`. opw-6118024 Forward-Port-Of: odoo/enterprise#118714
This update resolves an issue where attempting to create a new Global Invoice after cancelling a refund in the Mexican CFDI POS module would fail. The fix ensures that refund CFDI documents are correctly updated during the cancellation process, allowing for seamless invoice creation. This improves the reliability of the POS system for Mexican businesses.
Original PR description
Steps to reproduce 1. With a Mexican POS configured, create a POS order and sign a Global Invoice for it. 2. Open a new session and partially return the order; close the session. 3. On the original…
Steps to reproduce 1. With a Mexican POS configured, create a POS order and sign a Global Invoice for it. 2. Open a new session and partially return the order; close the session. 3. On the original order, cancel the Global Invoice through the CFDI page. 4. Try to create a new Global Invoice for the original order. Issue The wizard raises "Orders <REFUND-NAME> are already sent or not eligible for CFDI." Validating the refund auto-signs an `invoice_sent` CFDI on the refund pos.order because its parent is `global_sent`, see `_l10n_mx_edi_check_autogenerate_cfdi_refund` at https://github.com/odoo/enterprise/blob/5af8048f0b0956a024d7eaeb10600eec74bdf3ee/l10n_mx_edi_pos/models/pos_order.py#L98. Cancelling the GI only flips its own document to `ginvoice_cancel`; the refund's `invoice_sent` doc stays untouched, so the refund's computed `l10n_mx_edi_cfdi_state` stays `'sent'`. The chain check in `_l10n_mx_edi_check_orders_for_global_invoice` at https://github.com/odoo/enterprise/blob/5af8048f0b0956a024d7eaeb10600eec74bdf3ee/l10n_mx_edi_pos/models/pos_order.py#L184 then rejects the refund as already sent and the new GI cannot be created. opw-6181136
This update resolves an issue where users without HR access rights were seeing a placeholder image instead of their avatar in the timesheet kanban view. The fix ensures that all users can see their avatar, improving the user experience and making timesheet management more visually clear.
Original PR description
Steps to reproduce:
- Install the hr_timesheet module
- Create a user without HR access rights
- Create a timesheet
- Log in with the above user
- Open the kanban view
Issue:
Instead of showing the employee's avatar, a placeholder image
is displayed.
Reason:
The user does not have access to the hr.employee model.
Fix:
In this commit, if the user does not have access to hr.employee,
we fetch the image from the hr.employee.public model.
Task: 4461272
X-original-commit: b3018b1ab4bcdfebd8bb83bad38209b96646da3c
Description of the issue/feature this PR addresses:
Current behavior before PR:
Desired behavior after PR is merged:
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis update fixes an issue where the 'Due' button wasn't appearing for customers when their outstanding balance was present, specifically when the customer was only linked to a journal entry at the line level. The fix ensures all customers with balances are correctly identified, improving the user experience and preventing missed follow-up actions.
Original PR description
Steps to Reproduce: 1. Install Accounting module (without Point of Sale). 2. Create a customer. 3. Create a journal entry with that customer set only at line level. 4. Post the journal entry. 5. Open…
Steps to Reproduce: 1. Install Accounting module (without Point of Sale). 2. Create a customer. 3. Create a journal entry with that customer set only at line level. 4. Post the journal entry. 5. Open the customer form. Issue: The Due smart button is not visible on the partner form even though an outstanding balance exists for the customer. Note: This issue does not reproduce when Point of Sale is installed, as the POS module overrides `_compute_has_moves` with its own implementation that checks the outstanding balance directly. Root Cause: The `_compute_has_moves` method queries only `account.move `for partner matching. When a partner is referenced only at the account.move.line level, the partner is never picked up by this query, resulting in `has_moves = False` and the Due button remaining hidden. Fix: Replaced the EXISTS-based implementation with a UNION-based approach as the EXISTS implementation evaluated the query per partner row, whereas UNION processes all partners in a single batch query. Additionally extended the UNION to also include account.move.line partner matching, ensuring partners referenced only at the line level, are correctly detected and has_moves is set to True. Result: The Due smart button is now correctly visible for all partners with an outstanding balance, regardless of whether the partner is set at the journal entry level or only at the line level. owp = 6243562
This fix corrects a bug where refunded items appeared twice in POS receipts, leading to incorrect totals. The update ensures that refunded items are treated as a single line, resolving the issue and preventing double charges. This improves the accuracy of payment processing within the Point of Sale system.
Original PR description
**Steps to reproduce:** - Make a sale in the frontend - Refund it on the order in the backend - Reload the frontend page, the order is automatically set as the current one - Try to pay for it - There…
**Steps to reproduce:** - Make a sale in the frontend - Refund it on the order in the backend - Reload the frontend page, the order is automatically set as the current one - Try to pay for it - There are 2 lines on the ticket, and the total is thus wrong **Why the fix:** A line that has been refunded through the backend will appear twice in the receipt, causing it to be wrong. When loading the order from the backend, when we refresh the page after refunding it from the backend, we load the order and it's lines. The lines are found but they don't have any uuid set, so the pos sets one. Then at paying time, we load them again to check that nothing changed, but when loading the lines, we see that it does not have a uuid, as we did not write the frontend uuid to the backend yet. https://github.com/odoo/odoo/blob/0b17840fb3cc72935e1a6302a057fb55c253c498/addons/point_of_sale/static/src/app/store/pos_store.js#L1277-L1279 As we see we don't have a uuid on the line, we set it. The line is found again in the data in the snipped above. The line is then considered missing from the missingRecursive function, and when we try merge them with the existing lines, they don't have the same uuid so they are treated as different. This means we set 2 different uuids to a line that was in fact the same. The pos then sees 2 lines with 2 differents uuids, so it treats them as 2 different lines and we have to pay for both, even though they are the same and the second one should not have been added to the order and should have been ignored. Without this fix, the pos will think we don't have the line yet, even though we do, but just with another uuid so it will add it to the order even though it should not. We will then have the same line with two different uuid, so it will be considered as 2 different lines and both will be added to the receipt and have to be paid for. With this fix, the two lines now have the same uuid, and will be treated as the same line, as it should. opw-6235870
This update corrects a technical issue where a portal user's ID was incorrectly assigned as the author of system activity logs when orderpoints failed during a checkout process. This prevented accurate tracking of errors and could lead to access issues. The fix ensures that all system activities are properly attributed to OdooBot, improving log reliability and security.
Original PR description
Description of the issue/feature this PR addresses: When an orderpoint fails during a portal user's transaction (e.g., eCommerce checkout), the system catches the `ProcurementException` and logs a…
Description of the issue/feature this PR addresses:
When an orderpoint fails during a portal user's transaction (e.g., eCommerce checkout), the system catches the `ProcurementException` and logs a warning activity on the product template. The exception handler uses `.sudo().activity_schedule()`, which bypasses the write access restriction but leaves `env.uid` as the portal user. Therefore, the restricted portal user permanently becomes the `create_uid` (Author) of the activity.
System exception activities should always be authored by the system (OdooBot), never by a portal or public user. This context leak corrupts the activity metadata by injecting an external user ID into internal backend logs.
Chain `.with_user(SUPERUSER_ID)` to the `.sudo()` call in `stock_orderpoint.py` when scheduling the exception activity. This ensures the environment context is stable and the activity is authored by OdooBot, which transcends multi-company record rules.
Steps to Reproduce on Runbot/Fresh Database on version 18.0:
1. Enable Multi-Company with Company A and Company B. Set Company B as the active company for the website.
2. Restrict the main Admin (Runbot) user strictly to Company A.
3. Create a Shared Product (Company field left blank).
4. Set a Reordering Rule (Orderpoint) for the product that is guaranteed to fail routing.
5. Navigate to the frontend website and sign up as a new user (this creates a Portal User in Company B).
6. As the newly signed-up Portal User, complete an eCommerce checkout for the shared product.
7. The checkout succeeds, but the backend triggers the orderpoint failure and logs the exception activity on the product template.
8. Check the `mail.activity` record for this product: the `create_uid` is incorrectly set to the Portal User instead of OdooBot (1).
9. (In 19.0 Upgrade) Log in as the Admin user (set strictly to view Company A), navigate to the product, and the AccessError for reading will appear due to this leaked id.
[opw-6253978](https://www.odoo.com/odoo/my-support-tasks/6253978?debug=assets)
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr