Daily updates from Odoo
Thursday, June 18, 2026
123 changes
13 changes
New functionality added to Odoo
This update adds new invoice types specifically designed for Jordan's export regulations, including 'transit,' 'foreign trade,' and 'free zone transfer.' The system now validates that these types are only accessible to registered Jordanian taxpayers, ensuring compliance with local tax laws. This improves the accuracy of financial reporting for businesses operating in Jordan.
Original PR description
Extend l10n_jo_edi_invoice_type with JoFotara scope codes (3-5): transit (3), foreign trade (4), and free zone transfer (5). Validate that scope codes 3-5 are only available to registered taxpayers. task-4769255 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269632 Forward-Port-Of: odoo/odoo#268839
Resolved issues and error corrections
This fix resolves a problem where emails sent in bulk to accounting aliases could intermittently fail to process, resulting in bounced emails. The issue stemmed from concurrent database updates triggered by email attachments and OCR processing, leading to serialization errors. This update prevents these errors by improving how the system handles these concurrent operations.
Original PR description
Since https://github.com/odoo/odoo/commit/17893089e8b21c0ecab5e61ed8e2c33f3731b3ac, in certain cases, customers sending large batches of emails to an accounting email alias would report a small…
Since https://github.com/odoo/odoo/commit/17893089e8b21c0ecab5e61ed8e2c33f3731b3ac, in certain cases, customers sending large batches of emails to an accounting email alias would report a small number of emails being bounced (ca. 5%). Context: 1. While processing an email (after matching mail.alias, with the thread going through `message_process`), if an error is uncaught and raised, the mailgate generates a bounce email, as we presume that the email could not be processed correctly. 2. When sending an email with an attachment to an accounting journal alias, depending on the DB configuration, IAP calls for automatic OCR are triggered asynchronously. These calls trigger callbacks from the IAP server, which might hit the DB in parallel while another thread is processing another email. Given their nature, they trigger updates on the relevant account.move, thus triggering downstream computes in the model. 3. When processing an attachment, the account module triggers `_extend_with_attachments`, which tries decoding the attachment in a rollback context (see: https://github.com/odoo/odoo/blob/31df5033e31c193b4576ef37dfbc5fc683817bc5/addons/account/models/account_document_import_mixin.py#L343-L344). If a SerializationError happens during that process (concurrent update), it will NOT use the retry mechanism of the ORM because the error is caught in the `except Exception` block. Instead, it will try to post a message to the record to inform the user that the attachment could not be processed. 4. The commit mentioned above changes the way `_update_sequence_made_gap` works. One side effect seems to be that every time `made_sequence_gap` is re-assigned (even if the value does not change per se), the ORM tries to update the `write_date` on the flagged invoice that generated a sequence gap. Bug: Given the above context, emails might bounce unnecessarily for a valid email alias and a valid email with an attachment if: 1. The journal is not using a slash-based sequence pattern (e.g., using "1234" for the naming instead of "INV/2026/1234"). In that case, `sequence_prefix` == "". 2. The first invoice does not start at "1". 3. When sending a burst of simultaneous emails in a multi-worker setup, each thread will trigger `message_process` and downstream accounting computes while processing the invoice. It will also trigger IAP calls and callbacks asynchronously when automatic digitization is activated. 4. Each draft invoice that is created is named "/", meaning `sequence_prefix` == "", which in turn re-triggers the checks in `_update_sequence_made_gap`. 5. This increases the chances dramatically of a serialization error while all the parallel processes indirectly trigger an update on the `made_sequence_gap` field of invoice "1234". 6. Most of the time, the serialization error is not triggered in the thread processing the email, which correctly retries it. But in the few unlucky cases where it is raised in the thread processing the email, it will be triggered in the transaction rollback in `_extend_with_attachments`. While handling the exception, it triggers a second error because it tries to post a message to the record that was just rolled back: -> `ERROR: current transaction is aborted, commands ignored until end of transaction block` is raised in the thread running `message_process`, which in turn triggers a bounce email. Example logs (simplified): ``` 2026-06-12 14:12:15 [Worker-Thread-101] INFO mail_thread: Routing email (1) 2026-06-12 14:12:15 [Worker-Thread-102] INFO mail_thread: Routing email (2) 2026-06-12 14:12:16 [Worker-Thread-101] INFO iap_tools: dispatching /parse 2026-06-12 14:12:16 [Worker-Thread-102] INFO iap_tools: dispatching /parse 2026-06-12 14:12:18 [Worker-Thread-101] INFO iap_tools: Webhook received, triggering /get_result 2026-06-12 14:12:18 [Worker-Thread-102] INFO iap_tools: Webhook received, triggering /get_result 2026-06-12 14:12:19 [Worker-Thread-101] INFO odoo.sql_db: UPDATE "account_move" SET "made_sequence_gap" = true WHERE "id" = 1234 -> STATUS: OK (Acquired Row Lock) 2026-06-12 14:12:19 [Worker-Thread-102] ERROR odoo.sql_db: bad query: UPDATE "account_move" SET "made_sequence_gap" = true WHERE "id" = 1234 ERROR: could not serialize access due to concurrent update psycopg2.errors.SerializationFailure: could not serialize access 2026-06-12 14:12:19 [Worker-Thread-102] ERROR odoo.sql_db: bad query: SELECT "mail_message"."id" FROM "mail_message" WHERE ... ERROR: current transaction is aborted, commands ignored until end of transaction block psycopg2.errors.InFailedSqlTransaction: transaction is aborted 2026-06-12 14:12:19 [Worker-Thread-102] INFO "POST /saas_worker/smtp" 200 -> triggers Bounce email ``` Proposed Fix: A) We update the conditions in `check_around` to ignore draft invoices when they are the "previous" entity being checked. Only posted invoices should be considered when doing the gap checks. B) We add some guard clauses to prevent unnecessary writes to invoices that created sequence gaps. Instead of assigning values directly, we store the result of the check and only assign `made_sequence_gap` explicitly if the value is different from the currently stored value. This prevents unnecessary writes to the record if the value did not change. Note: - We chose this approach instead of touching `_extend_with_attachments` and the rollback context directly. Mostly to prevent any unforseen side-effects, given that this methods are used in accounting for all attachments. But it might be worth analysing if those methods might be improved to handle scenarios as described above in multi-worker setups + email handling. - fixing the rollbackable context might tricky because the serialization error happens at the first `cr.commit()` inside the context manager - raising explicitly with `except psycopg2.extensions.TransactionRollbackError:` in `_extend_with_attachments` retries the whole request to the `message_process`, which might not be a good idea OPW-6272396 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270251
This update resolves an issue where the EC List XML export incorrectly treated invoices with the same VAT number as separate partners, leading to rejection by tax agencies. The fix ensures that invoices with identical VATs are correctly grouped, resolving the rejection and improving compliance. This impacts the Belgian VAT reporting process.
Original PR description
With l10n_be: - Create two contacts with the same VAT - Create an invoice for each that is EC List compatible - Generate the return and export the EC List XML In the generated xml the two partners with the same vat are treated as different partners, which causes a rejection by the tax agency. opw-6109585 Forward-Port-Of: odoo/enterprise#120305 Forward-Port-Of: odoo/enterprise#117702
This update resolves an issue where product images in the self-order point-of-sale system were appearing distorted. The team applied a technical fix to ensure all product images are fully visible and displayed correctly, improving the customer experience. This change impacts the cart, combo, product list, and product detail pages within the self-order module.
Original PR description
In this commit: ------------------- - Applied `object-fit: scale` to ensure product images are fully visible and properly displayed without distortion. task: [6260046](https://www.odoo.com/odoo/project.task/6260046) Forward-Port-Of: odoo/odoo#270387 Forward-Port-Of: odoo/odoo#268521
This update fixes an issue where Point of Sale reports were incorrectly showing the session start date instead of the user-selected date range. The change ensures that reports accurately reflect the date range specified by the user, improving the accuracy of sales reporting. This was caused by a recent update to how the report determines session data.
Original PR description
Steps to reproduce ------------------ 1. Open a PoS session, e.g. at 1h45 2. Wait a bit and make an order, e.g. at 1h55 3. Keep the session open and go to PoS > Reporting > Sale Details. 4. Select a…
Steps to reproduce ------------------ 1. Open a PoS session, e.g. at 1h45 2. Wait a bit and make an order, e.g. at 1h55 3. Keep the session open and go to PoS > Reporting > Sale Details. 4. Select a starting date before the ordre and after the session open, e.g. at 1h50 5. Generate the report. The header shows the starting date of the session, i.e. at 1h45, instead of that of the selected date, i.e. 1h50 Why it's happening ------------------ Commit 5003774bf2a7 changed the way the report decides if the data comes from a single session: now if all the orders in the user selected start and end date belong to one particular session, the start and end date on the report are overriden to be those of that particular session, ignoring the user selected ranges. The fix ------- Only overwrite the start and end dates when `session_ids` was passed (i.e. the report is about a specific session). When called via date range + `config_ids` (from the backend wizard like in our reproduction steps), keep the user-selected range. opw-6185106 Forward-Port-Of: odoo/odoo#270310 Forward-Port-Of: odoo/odoo#267200
This update resolves an error that prevented users from opening the Gantt view for work orders. The fix ensures the system correctly handles resources without calendars, preventing a system crash when calculating availability. This improves the reliability of the work order scheduling process.
Original PR description
Currently, an error occurs when opening the gantt view of work orders. **Steps to Reproduce:** - Install `mrp_workorder` with demo data. - Go to `Settings` > `Technical` > `Resource` > `Resources`. -…
Currently, an error occurs when opening the gantt view of work orders. **Steps to Reproduce:** - Install `mrp_workorder` with demo data. - Go to `Settings` > `Technical` > `Resource` > `Resources`. - Open the `Assembly 1` resource and remove its `working time`. - Go to `Manufacturing` > `Operations` > `Work Orders`. - Switch to the `Gantt view`. `KeyError: 22` when the user opens the Gantt view, the system checks the unavailability of work centers and employees based on their resource calendars. While computing unavailable intervals for resources [1], resources without a calendar are flexible resources. If no leave interval exists within the specified start and end range that matches the domain, the resource is not included in the result [2]. when updating the unavailable intervals dictionary [3], the resource is missing. As a result, when it later tries to access the unavailable intervals for that resource, it raises an error [4]. This commit prevents the error by safely handling resources that are not present in the unavailable intervals dictionary by using an empty list instead. [1]: https://github.com/odoo/odoo/blob/1f666de440479dd3d30b7b6cf7c42862c5fcb37a/addons/resource/models/resource_resource.py#L186 [2]: https://github.com/odoo/odoo/blob/1f666de440479dd3d30b7b6cf7c42862c5fcb37a/addons/resource/models/resource_calendar.py#L532-L536 [3]:https://github.com/odoo/odoo/blob/1f666de440479dd3d30b7b6cf7c42862c5fcb37a/addons/resource/models/resource_resource.py#L187 [4] https://github.com/odoo/enterprise/blob/47f2e9e88fa0bbb8852fe7734c6bece4dca8b9d0/mrp_workorder/models/mrp_workorder.py#L692-L694 sentry-7525704808 Forward-Port-Of: odoo/enterprise#119385
This update resolves an issue where moving Odoo databases via the command line would inadvertently deregister the associated subscription. The new `--move` flag ensures the database's original UUID is retained during a move, maintaining the subscription link. This improves the reliability of server-to-server database transfers.
Original PR description
### What & why `odoo db load` always calls `restore_db(..., copy=True)`, which forces the generation of a new `dbuuid` via `ir.config_parameter.init(force=True)`. That is the right default when…
### What & why `odoo db load` always calls `restore_db(..., copy=True)`, which forces the generation of a new `dbuuid` via `ir.config_parameter.init(force=True)`. That is the right default when *duplicating* a database, but it breaks the intended behaviour when *moving* a database between servers: Enterprise subscription codes are registered against the database UUID, so regenerating it deregisters the moved database. The web database manager already lets the user choose between copying and moving (the `copy` flag of the `/web/database/restore` route), but the CLI exposed no equivalent and forced a copy unconditionally. The CLI is the better tool for server-to-server moves: it isn't subject to reverse-proxy upload/timeout limits and can run unattended or interactively. ### Steps to reproduce the current limitation 1. On server A: `odoo db dump mydb mydb.zip` (Enterprise DB registered to its UUID) 2. On server B: `odoo db load mydb mydb.zip` 3. `database.uuid` has changed → the subscription is deregistered ### Fix Add a `--move` flag to `odoo db load` that maps to `restore_db(copy=False)`, keeping the original UUID. The default remains `copy=True`, so existing behaviour is unchanged. ```sh odoo db load mydb mydb.zip # unchanged: restore as a copy (new UUID) odoo db load --move mydb mydb.zip # new: restore as a move (keep the UUID) ``` ### Backport request This would be greatly appreciated as a backport to 18.0, 17.0, and 16.0 as well. Those are precisely the versions that ship the `odoo db` CLI subcommand, so the fix is applicable to all of them — which is why the backport range is 16.0 → 19.0 and stops at 16.0. Forward-Port-Of: odoo/odoo#268700 Forward-Port-Of: odoo/odoo#268501
This update fixes a bug where rental order PDFs didn't show the pickup and return dates. The fix adds the necessary fields to the PDF report, ensuring consistent presentation with the customer portal. This improves clarity and accuracy for rental order documentation.
Original PR description
**Problem:** On a rental order, the sales order / quotation PDF no longer shows the pickup and return dates. The line description only displays the rental duration (e.g. "2 Days"), so the actual…
**Problem:** On a rental order, the sales order / quotation PDF no longer shows the pickup and return dates. The line description only displays the rental duration (e.g. "2 Days"), so the actual dates are missing from the printout. **Steps to reproduce:** 1. Create a rental order with a rentable product and pickup/return dates 2. Print the order (Print > Quotation / Order) 3. Observe the PDF shows only the duration, with no pickup/return dates **Current behavior:** Neither the rental dates (removed from the description) nor any pickup/return field appear on the PDF. **Expected behavior:** The pickup and return dates are shown on the rental order PDF. **Cause of the issue:** The rental line description was intentionally reduced to only the duration (`_get_rental_duration_description`), the actual dates being meant to appear as dedicated Pickup/Return fields. This was added to the customer portal (`sale_rental_portal_details` inherits `sale.sale_order_portal_content`) but the equivalent was never added to the `sale.report_saleorder_document` PDF report, so the dates disappeared from the printout. **Fix:** Inherit the sale order report to render the order-level pickup and return dates for rental orders, mirroring the existing portal presentation so the PDF and the portal stay consistent. opw-6268640
This update fixes an issue where canceling a CFDI incorrectly triggered a cancellation of the associated down payment. The system now correctly uses the '04' origin code for CFDI cancellations, aligning with Mexican regulations and preventing unintended down payment cancellations. This ensures accurate CFDI processing and compliance.
Original PR description
**Steps to reproduce:** - Install Sales, Accounting and l10n_mx_edi - Switch to a Mexican company (e.g. ZAPATERIA URTADO ÑERI) - Create a SO: * Customer: [a Mexican customer] (e.g. INMOBILIARIA CVA) * Payment Way: Efectivo * Payment Policy: PUE * Product: [any product with a UNSPSC Category] * Taxes: [any] (e.g. 16%) - Confirm the SO - Create a down payment (e.g. 60%) - Confirm the down payment - Send it to CFDI - Copy the fiscal folio - Go back to SO - Create the final invoice - Set the copied fiscal folio prepend with "07|" as CFDI Origin - Confirm the invoice - Send to CFDI **Issue:** A cancellation request is sent to CFDI for the down payment. "07" origin code is used to link the invoice to a down payment. It should not cancel the down payment. It should only be done with "04" origin code used for substitution of a previous invoice. opw-6266678 Forward-Port-Of: odoo/enterprise#120757
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, respectively. The changes update the XML data to align with audit guidelines and maintain compliance.
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#120790 Forward-Port-Of: odoo/enterprise#118714
This update corrects a bug where the timesheet timer was incorrectly adding extra seconds, leading to inaccurate overtime calculations and marking workdays as exceeding their allotted hours. The fix ensures that the user-entered time is accurately saved, preventing this overtime display issue. This change was introduced in the saas-19.2 release.
Original PR description
Steps to reproduce --- 1. Set an employee to work 8 hours per day. 2. Open the timesheet timer in the systray, type a duration like 8:00 and save. 3. Open the My Timesheets grid for that day. The day…
Steps to reproduce --- 1. Set an employee to work 8 hours per day. 2. Open the timesheet timer in the systray, type a duration like 8:00 and save. 3. Open the My Timesheets grid for that day. The day is marked as overtime (yellow) even though only 8 hours were logged. Issue --- While the entry is open the timer keeps running and, every second, writes the elapsed time into unit_amount down to the second. https://github.com/odoo/enterprise/blob/a3c9295cf28b47f43233ac6a9f4106810842e37a/timesheet_grid/static/src/components/timesheet_timer_inline_form/timesheet_timer_inline_form.js#L89-L102 When the duration is set by hand, the save skips the usual rounding and keeps the value as it is. https://github.com/odoo/enterprise/blob/a3c9295cf28b47f43233ac6a9f4106810842e37a/timesheet_grid/static/src/components/timesheet_timer_inline_form/timesheet_timer_inline_form.js#L120-L132 So the clean 8:00 the user typed gets a few extra seconds from the next timer tick (8h 1s, stored as 8.000277) and is saved with them. The seconds are hidden in the HH:MM display but are enough to push the day above its working hours, so the grid paints it as overtime. This timer form is new in saas-19.2 (c3dac6ccdb5), which is why earlier versions are not affected. The fix ignores timer ticks once the duration has been set by hand, so the typed value is kept. opw-6180676 --- Forward-Port-Of: odoo/enterprise#120601
This update resolves an issue where the appointment calendar displayed 'no slots available' in future months due to incorrect calculation of availability. The fix accounts for appointment lead times, ensuring the calendar accurately reflects available slots when navigating forward. This improves the user experience for scheduling appointments.
Original PR description
The website appointment calendar fills availabilities one month at a time and the update_available_slots route maps the calendar month index to an absolute month from datetime.now(). This only…
The website appointment calendar fills availabilities one month at a time and the update_available_slots route maps the calendar month index to an absolute month from datetime.now(). This only matches the displayed months when the first one is the current month. When the first bookable slot is later, a punctual appointment starting in a future month or any appointment whose "at least X hours before start time" lead time pushes the first slot past the current month, navigating forward requests the wrong month and the reached month renders empty. In update_available_slots, take the lead time into account when computing the reference month so it lands on the first displayed month: the start datetime for a punctual appointment starting in the future, otherwise now plus the minimum schedule hours. The navigated month index is then added to that reference. This extends https://github.com/odoo/enterprise/commit/f0e5b14a823cf97218f4094d287a328e2744fd73 which only handled the future start datetime. Steps to reproduce: 1. Open the Appointments app 2. Open an appointment type, set Schedule to Weekly and Allow Bookings to On specific dates with a range ending a few months out 3. Set the "at least N hours before start time" field to 360 4. Save and click the Preview button in the header 5. Pick a resource or staff member to reach the calendar 6. Click the right arrow to navigate to the next month => the next month shows "Sorry, we have no more slots available for this month" opw-6206293 Forward-Port-Of: odoo/enterprise#120715
This update fixes an issue where the system wasn't accurately tracking component usage when creating backorders on manufacturing orders. Specifically, the component quantity wasn't being fully consumed, leading to incorrect inventory levels. This change ensures that the correct amount of components is deducted from stock when a backorder is created, improving inventory accuracy.
Original PR description
### Steps to reproduce: - In the settings enable: Multi-Steps Routes - Set your warehouse to manufacture in 2 steps (pick then manufacture). - Create a final product (FP) with a BOM in flexible…
### Steps to reproduce: - In the settings enable: Multi-Steps Routes - Set your warehouse to manufacture in 2 steps (pick then manufacture). - Create a final product (FP) with a BOM in flexible consumption: - 2 x COMP (lot tracked) - Put a lot for 6 units in of COMP in stock - Create and confirm an MO for 5 units of FP - Set the quantity producing on the MO to 1, requiring 2 of the 6 available units of COMP - Validate the MO and create a backorder for the remaining quantity. #### > The consumed qty on the main MO is of 0 units rather than 2. ### Cause of the issue: Since the component is tracked, and since the pbm move was backordered, the move quantity will not be automatically set when setting the `qty_producing`: https://github.com/odoo/odoo/blob/a1bcd917846493d08dd02b63e6110078ff5156a3/addons/mrp/models/mrp_production.py#L1405-L1411 And in particular, the move is not picked as it would if the product was untracked or if the pbm move was not backordered: https://github.com/odoo/odoo/blob/a1bcd917846493d08dd02b63e6110078ff5156a3/addons/mrp/models/mrp_production.py#L1421-L1427 And, since the move will not be picked at any other point in this flow, the move will be unreserved during the `button_mark_done`: https://github.com/odoo/odoo/blob/7c35e183d6cc33a6e5d20e5e97ffef79e03b49d4/addons/mrp/models/mrp_production.py#L2216 https://github.com/odoo/odoo/blob/7c35e183d6cc33a6e5d20e5e97ffef79e03b49d4/addons/mrp/models/mrp_production.py#L1895-L1896 https://github.com/odoo/odoo/blob/7c35e183d6cc33a6e5d20e5e97ffef79e03b49d4/addons/mrp/models/mrp_production.py#L1901 opw-6128575 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269535 Forward-Port-Of: odoo/odoo#269235
14 changes
Resolved issues and error corrections
This fix addresses a problem where processing large batches of emails to the accounting system could trigger errors and cause emails to be marked as bounced, even when valid. The issue stemmed from concurrent updates to invoice records during email processing and IAP calls, leading to rollback errors and bounce notifications. This change improves email processing reliability and reduces unnecessary bounces.
Original PR description
Since https://github.com/odoo/odoo/commit/17893089e8b21c0ecab5e61ed8e2c33f3731b3ac, in certain cases, customers sending large batches of emails to an accounting email alias would report a small…
Since https://github.com/odoo/odoo/commit/17893089e8b21c0ecab5e61ed8e2c33f3731b3ac, in certain cases, customers sending large batches of emails to an accounting email alias would report a small number of emails being bounced (ca. 5%). Context: 1. While processing an email (after matching mail.alias, with the thread going through `message_process`), if an error is uncaught and raised, the mailgate generates a bounce email, as we presume that the email could not be processed correctly. 2. When sending an email with an attachment to an accounting journal alias, depending on the DB configuration, IAP calls for automatic OCR are triggered asynchronously. These calls trigger callbacks from the IAP server, which might hit the DB in parallel while another thread is processing another email. Given their nature, they trigger updates on the relevant account.move, thus triggering downstream computes in the model. 3. When processing an attachment, the account module triggers `_extend_with_attachments`, which tries decoding the attachment in a rollback context (see: https://github.com/odoo/odoo/blob/31df5033e31c193b4576ef37dfbc5fc683817bc5/addons/account/models/account_document_import_mixin.py#L343-L344). If a SerializationError happens during that process (concurrent update), it will NOT use the retry mechanism of the ORM because the error is caught in the `except Exception` block. Instead, it will try to post a message to the record to inform the user that the attachment could not be processed. 4. The commit mentioned above changes the way `_update_sequence_made_gap` works. One side effect seems to be that every time `made_sequence_gap` is re-assigned (even if the value does not change per se), the ORM tries to update the `write_date` on the flagged invoice that generated a sequence gap. Bug: Given the above context, emails might bounce unnecessarily for a valid email alias and a valid email with an attachment if: 1. The journal is not using a slash-based sequence pattern (e.g., using "1234" for the naming instead of "INV/2026/1234"). In that case, `sequence_prefix` == "". 2. The first invoice does not start at "1". 3. When sending a burst of simultaneous emails in a multi-worker setup, each thread will trigger `message_process` and downstream accounting computes while processing the invoice. It will also trigger IAP calls and callbacks asynchronously when automatic digitization is activated. 4. Each draft invoice that is created is named "/", meaning `sequence_prefix` == "", which in turn re-triggers the checks in `_update_sequence_made_gap`. 5. This increases the chances dramatically of a serialization error while all the parallel processes indirectly trigger an update on the `made_sequence_gap` field of invoice "1234". 6. Most of the time, the serialization error is not triggered in the thread processing the email, which correctly retries it. But in the few unlucky cases where it is raised in the thread processing the email, it will be triggered in the transaction rollback in `_extend_with_attachments`. While handling the exception, it triggers a second error because it tries to post a message to the record that was just rolled back: -> `ERROR: current transaction is aborted, commands ignored until end of transaction block` is raised in the thread running `message_process`, which in turn triggers a bounce email. Example logs (simplified): ``` 2026-06-12 14:12:15 [Worker-Thread-101] INFO mail_thread: Routing email (1) 2026-06-12 14:12:15 [Worker-Thread-102] INFO mail_thread: Routing email (2) 2026-06-12 14:12:16 [Worker-Thread-101] INFO iap_tools: dispatching /parse 2026-06-12 14:12:16 [Worker-Thread-102] INFO iap_tools: dispatching /parse 2026-06-12 14:12:18 [Worker-Thread-101] INFO iap_tools: Webhook received, triggering /get_result 2026-06-12 14:12:18 [Worker-Thread-102] INFO iap_tools: Webhook received, triggering /get_result 2026-06-12 14:12:19 [Worker-Thread-101] INFO odoo.sql_db: UPDATE "account_move" SET "made_sequence_gap" = true WHERE "id" = 1234 -> STATUS: OK (Acquired Row Lock) 2026-06-12 14:12:19 [Worker-Thread-102] ERROR odoo.sql_db: bad query: UPDATE "account_move" SET "made_sequence_gap" = true WHERE "id" = 1234 ERROR: could not serialize access due to concurrent update psycopg2.errors.SerializationFailure: could not serialize access 2026-06-12 14:12:19 [Worker-Thread-102] ERROR odoo.sql_db: bad query: SELECT "mail_message"."id" FROM "mail_message" WHERE ... ERROR: current transaction is aborted, commands ignored until end of transaction block psycopg2.errors.InFailedSqlTransaction: transaction is aborted 2026-06-12 14:12:19 [Worker-Thread-102] INFO "POST /saas_worker/smtp" 200 -> triggers Bounce email ``` Proposed Fix: A) We update the conditions in `check_around` to ignore draft invoices when they are the "previous" entity being checked. Only posted invoices should be considered when doing the gap checks. B) We add some guard clauses to prevent unnecessary writes to invoices that created sequence gaps. Instead of assigning values directly, we store the result of the check and only assign `made_sequence_gap` explicitly if the value is different from the currently stored value. This prevents unnecessary writes to the record if the value did not change. Note: - We chose this approach instead of touching `_extend_with_attachments` and the rollback context directly. Mostly to prevent any unforseen side-effects, given that this methods are used in accounting for all attachments. But it might be worth analysing if those methods might be improved to handle scenarios as described above in multi-worker setups + email handling. - fixing the rollbackable context might tricky because the serialization error happens at the first `cr.commit()` inside the context manager - raising explicitly with `except psycopg2.extensions.TransactionRollbackError:` in `_extend_with_attachments` retries the whole request to the `message_process`, which might not be a good idea OPW-6272396 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270251
This update resolves an issue where product images in the self-order point-of-sale system were appearing distorted. The team applied a technical fix to ensure all product images are fully visible and displayed correctly, improving the customer experience. This change enhances the visual presentation of products during self-ordering transactions.
Original PR description
In this commit: ------------------- - Applied `object-fit: scale` to ensure product images are fully visible and properly displayed without distortion. task: [6260046](https://www.odoo.com/odoo/project.task/6260046) Forward-Port-Of: odoo/odoo#270387 Forward-Port-Of: odoo/odoo#268521
This update corrects a bug in how overtime calculations are handled, specifically when overtimes span multiple days and employee timezones. The fix prevents incorrect interval overlaps that occurred due to rounding errors, ensuring accurate overtime tracking. This improves the reliability of employee time reporting.
Original PR description
**Problem:** When an attendance has overtimes across multiple days, those overtimes can overlap when calculating their intervals. There will always be rounding errors since only the durations are…
**Problem:** When an attendance has overtimes across multiple days, those overtimes can overlap when calculating their intervals. There will always be rounding errors since only the durations are saved to 3 decimals, but this is normally fine since the durations are accumulated when calculating the next interval. However, on a day boundary in the employee timezone, the end of the interval is forced to the end of day, which incidentally removes the rounding error. This causes the overlap when calculating the next interval since its start will be based on the rounded duration, not the actual end of day. **Steps to Reproduce:** - Configure an overtime rule where >8 hours is considered overtime, and a second rule applies to non-working days - Set Overtime Rule on employee "Anita Oliver" - Set employee work entry source to "Attendances" - Create an attendance that exceeds 8 hours in a day and crosses into a non-working day and creates enough of a rounding error (see unit test) -> Traceback error: `ValueError: Expected singleton: hr.attendance.overtime.line(1, 2)` **Solution:** Add an additional check to ensure the overtime cannot start on the previous day. opw-6067969 Forward-Port-Of: odoo/enterprise#118825 Forward-Port-Of: odoo/enterprise#118570
This update fixes an issue where the system wasn't accurately tracking component usage when creating backorders for manufacturing orders. Specifically, the system wasn't consuming the expected quantity of a tracked component, leading to incorrect inventory levels. This change ensures that component usage is properly reflected on backordered MOs, improving inventory accuracy.
Original PR description
### Steps to reproduce: - In the settings enable: Multi-Steps Routes - Set your warehouse to manufacture in 2 steps (pick then manufacture). - Create a final product (FP) with a BOM in flexible…
### Steps to reproduce: - In the settings enable: Multi-Steps Routes - Set your warehouse to manufacture in 2 steps (pick then manufacture). - Create a final product (FP) with a BOM in flexible consumption: - 2 x COMP (lot tracked) - Put a lot for 6 units in of COMP in stock - Create and confirm an MO for 5 units of FP - Set the quantity producing on the MO to 1, requiring 2 of the 6 available units of COMP - Validate the MO and create a backorder for the remaining quantity. #### > The consumed qty on the main MO is of 0 units rather than 2. ### Cause of the issue: Since the component is tracked, and since the pbm move was backordered, the move quantity will not be automatically set when setting the `qty_producing`: https://github.com/odoo/odoo/blob/a1bcd917846493d08dd02b63e6110078ff5156a3/addons/mrp/models/mrp_production.py#L1405-L1411 And in particular, the move is not picked as it would if the product was untracked or if the pbm move was not backordered: https://github.com/odoo/odoo/blob/a1bcd917846493d08dd02b63e6110078ff5156a3/addons/mrp/models/mrp_production.py#L1421-L1427 And, since the move will not be picked at any other point in this flow, the move will be unreserved during the `button_mark_done`: https://github.com/odoo/odoo/blob/7c35e183d6cc33a6e5d20e5e97ffef79e03b49d4/addons/mrp/models/mrp_production.py#L2216 https://github.com/odoo/odoo/blob/7c35e183d6cc33a6e5d20e5e97ffef79e03b49d4/addons/mrp/models/mrp_production.py#L1895-L1896 https://github.com/odoo/odoo/blob/7c35e183d6cc33a6e5d20e5e97ffef79e03b49d4/addons/mrp/models/mrp_production.py#L1901 opw-6128575 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269235
This update fixes a display issue in the CRM's Kanban view where the progress bar wasn't accurately reflecting the number of opportunities in each stage. The change removed a counter that was previously displayed, and this fix restores the opportunity count alongside 'Planned' activities, improving visibility for sales teams. This resolves a previous issue reported by product owners.
Original PR description
# How to reproduce - Go to the CRM kanban view - Add an oppurtinity where the salesperson is yourself & add another one where it is not in Stage X - Enable the "My pipeline" filter - Hover the progress bar of Stage X # The problem The green part of the progress bar displays "X Planned" while the grey one displays "No activities scheduled" even if there are # Cause This commit introduced the change from "X Other" to "No activities scheduled" : https://github.com/odoo/odoo/commit/ec52375d3b99f42e712b8a44afee43d82ffdf239 But it removed the counter, which the PO wishes to add back opw-6229549 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes a critical issue where leave schedules incorrectly blocked resource allocation, now only applying to resources with matching calendars. Additionally, tests have been reorganized and improved to ensure accurate validation of rental planning functionality.
Original PR description
## [FIX] sale_renting_planning: check global leaves working schedule Before this commit: any `resource.calendar.leaves` with no `resource_id` created would prevent all resources from being allocated…
## [FIX] sale_renting_planning: check global leaves working schedule
Before this commit: any `resource.calendar.leaves` with no `resource_id` created would prevent all resources from being allocated during the leave date.
After this commit: any `resource.calendar.leaves` with `no resource_id` would be applied only to resources with the same `calendar_id` as the leave.
if the leave has no `calendar_id` then the leave applies to all `resource.calendars`
if a resource has no `calendar_id` then leaves with no `calendar_id` apply to it as well
## [IMP] {website_}sale_renting_planning: move tests from industry and fix existing ones
This commit moves the tests from [odoo/industry#1980](vscode-file://vscode-app/snap/code/237/usr/share/code/resources/app/out/vs/code/electron-browser/workbench/workbench.html) to their respective standard modules.
It also fixes the logic behind some tests as they weren't testing a `planning.role` with `sync_shift_rental` enabled.
task-6179505
Forward-Port-Of: odoo/enterprise#120756
Forward-Port-Of: odoo/enterprise#116430This update fixes an issue where Point of Sale reports were incorrectly showing the session start date instead of the user-selected date range. The change ensures that reports accurately reflect the date range specified by the user, improving reporting accuracy and data consistency. This impacts how sales data is summarized and analyzed.
Original PR description
Steps to reproduce ------------------ 1. Open a PoS session, e.g. at 1h45 2. Wait a bit and make an order, e.g. at 1h55 3. Keep the session open and go to PoS > Reporting > Sale Details. 4. Select a…
Steps to reproduce ------------------ 1. Open a PoS session, e.g. at 1h45 2. Wait a bit and make an order, e.g. at 1h55 3. Keep the session open and go to PoS > Reporting > Sale Details. 4. Select a starting date before the ordre and after the session open, e.g. at 1h50 5. Generate the report. The header shows the starting date of the session, i.e. at 1h45, instead of that of the selected date, i.e. 1h50 Why it's happening ------------------ Commit 5003774bf2a7 changed the way the report decides if the data comes from a single session: now if all the orders in the user selected start and end date belong to one particular session, the start and end date on the report are overriden to be those of that particular session, ignoring the user selected ranges. The fix ------- Only overwrite the start and end dates when `session_ids` was passed (i.e. the report is about a specific session). When called via date range + `config_ids` (from the backend wizard like in our reproduction steps), keep the user-selected range. opw-6185106 Forward-Port-Of: odoo/odoo#270310 Forward-Port-Of: odoo/odoo#267200
This update resolves an issue where related fields weren't correctly updating after changes were made in Odoo Studio. Specifically, the system failed to recognize new choices when a field was created or modified within Studio, leading to incorrect data. This fix ensures that related fields are consistently synchronized across Odoo, regardless of how the field was initially created.
Original PR description
This is because webclient knows the current value (c), but not the new available choices, still with the previous one (a, b). Actually this works correctly if the field is created within a model…
This is because webclient knows the current value (c), but not the new
available choices, still with the previous one (a, b).
Actually this works correctly if the field is created within a model
class.
```py
if model_cls._setup_done__ and field._base_fields__:
# the field has been created by model_classes._setup() as
# Field(_base_fields__=...); restore it to force its setup
name = field.name
base_fields = field._base_fields__
field.__dict__.clear()
field.__init__(_base_fields__=base_fields)
field._toplevel = True
field.__set_name__(model_cls, name)
field._setup_done = False
models_field_depends_done.discard(model_cls)
```
It does not works with studio because there are no parent class
(`_base_fields__`), so the if is not reached.
A solution would be to check if the field is a manually created related
and mark the whole model for setup unlike when `_base_fields__` is
present where we only setup this specific field.
opw-6293768
Forward-Port-Of: odoo/odoo#270349This update fixes an issue where self-ordering mobile devices weren't correctly aligning with kiosks, preventing receipt printing. The change ensures that order updates are properly reflected, guaranteeing accurate receipt generation for mobile users. This improves the overall customer experience and reduces potential order discrepancies.
Original PR description
Self ordering mobile now aligns on kiosk avoiding to update last order changes, which would prevent from printing preparation receipts.
This update resolves an issue where imported Peppol/UBL vendor bills with 100% discounts were incorrectly processed. The fix ensures that a line with a LineExtensionAmount of 0 is properly recognized as a fully discounted line, preventing incorrect quantity and discount calculations. This improves the accuracy of imported financial data.
Original PR description
When importing a Peppol/UBL vendor bill containing a line with a 100% discount, the line was created in Odoo with quantity=1 and discount of 100*original_qty, instead of the expected…
When importing a Peppol/UBL vendor bill containing a line with a 100% discount, the line was created in Odoo with quantity=1 and discount of 100*original_qty, instead of the expected quantity=qty_original and discount=100%. This happened because the line-level branching in `_import_ubl_invoice_line_add_price_unit_quantity_discount` relied on the truthiness of `line_extension_amount` to detect whether the `LineExtensionAmount` node was present in the XML. a line with a genuine `<cbc:LineExtensionAmount>0</...>` was indistinguishable from a line where the node was missing, and fell through to the fallback branch intended for incomplete XML. That fallback reconstructs the quantity from `<cbc:BaseQuantity>`, ignoring `<cbc:InvoicedQuantity>`, and then computes the discount percentage against the wrong denominator. a `LineExtensionAmount` of 0 is the only legal way to express a fully discounted line, so this case must be distinguished from the node being absent. the fix is simply checking if the line exist not if its True opw-6176349 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#268954 Forward-Port-Of: odoo/odoo#265261
This update fixes an issue where stock replenishment wasn't working correctly with orderpoints, leading to duplicate purchase orders being created. The change ensures that orderpoints are updated automatically when stock is replenished, preventing unnecessary purchase orders and streamlining the stock management process. This improves efficiency and reduces potential errors.
Original PR description
Replenishing the stock from an orderpoint will look for a purchase order line having the same orderpoint_id in order to update the quantity instead of creating a new one. The issue is manual orderpoint are deleted right after the replenishment. Replenishing two times the same product will always create a new purchase order line. This commit makes the orderpoint_id is pass in the procurement values only in case of `trigger == auto` orderpoint. 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-pr Forward-Port-Of: odoo/odoo#269725
This update corrects a rejection issue with the 3519 VAT reimbursement form submitted to the French tax authority (DGFiP). The fix ensures the correct 'millesime' (form version year) is used, resolving a mismatch that was causing errors. This prevents delays in VAT reimbursement for French customers.
Original PR description
The 3519 reimbursement form is rejected by the DGFiP with "Le millesime 25 du formulaire 3519 est inconnu dans la teleprocedure TVA". The 3310CA3 return is still accepted, because its layout is unchanged year-on-year, which hides the problem, but it is sent with a millesime that no longer matches the campaign. The millesime is the form-version year. The EDI-TVA 2026 campaign opened on 2026-02-09. last update: https://github.com/odoo/enterprise/pull/92542 opw-6275695 Forward-Port-Of: odoo/enterprise#120759
This update resolves a bug that caused the Odoo application to crash when opening articles containing embedded account reports. The fix ensures that component properties are properly initialized, preventing unintended changes during setup and maintaining application stability. This improves the reliability of the accounting module.
Original PR description
When opening an article containing an embedded account report component, the application crashes because the `name` prop is mutated during the component `setup`, which is not allowed.
Steps to reproduce:
1. Create a new audit report
2. Open the "Journal Audit" article containing an embedded account report
=> The following exception is raised:
```
Uncaught (in promise) TypeError: setting getter-only property "name"
setup account_report.js:15
```
To fix the issue, the translation of the `name` prop is moved to `getProps`, which prepares component props before mounting. This ensures the value is already translated at instantiation time, avoids any mutation during setup, and preserves prop immutability throughout the component lifecycle.
Ref: odoo/enterprise#109962
Task-6292898
Forward-Port-Of: odoo/enterprise#120077This update resolves an issue where moving Odoo databases via the command line would inadvertently deregister subscription codes. The new `--move` flag ensures the database's original UUID is retained during a move, maintaining the user's subscription. This improves the reliability of server-to-server database migrations.
Original PR description
### What & why `odoo db load` always calls `restore_db(..., copy=True)`, which forces the generation of a new `dbuuid` via `ir.config_parameter.init(force=True)`. That is the right default when…
### What & why `odoo db load` always calls `restore_db(..., copy=True)`, which forces the generation of a new `dbuuid` via `ir.config_parameter.init(force=True)`. That is the right default when *duplicating* a database, but it breaks the intended behaviour when *moving* a database between servers: Enterprise subscription codes are registered against the database UUID, so regenerating it deregisters the moved database. The web database manager already lets the user choose between copying and moving (the `copy` flag of the `/web/database/restore` route), but the CLI exposed no equivalent and forced a copy unconditionally. The CLI is the better tool for server-to-server moves: it isn't subject to reverse-proxy upload/timeout limits and can run unattended or interactively. ### Steps to reproduce the current limitation 1. On server A: `odoo db dump mydb mydb.zip` (Enterprise DB registered to its UUID) 2. On server B: `odoo db load mydb mydb.zip` 3. `database.uuid` has changed → the subscription is deregistered ### Fix Add a `--move` flag to `odoo db load` that maps to `restore_db(copy=False)`, keeping the original UUID. The default remains `copy=True`, so existing behaviour is unchanged. ```sh odoo db load mydb mydb.zip # unchanged: restore as a copy (new UUID) odoo db load --move mydb mydb.zip # new: restore as a move (keep the UUID) ``` ### Backport request This would be greatly appreciated as a backport to 18.0, 17.0, and 16.0 as well. Those are precisely the versions that ship the `odoo db` CLI subcommand, so the fix is applicable to all of them — which is why the backport range is 16.0 → 19.0 and stops at 16.0. Forward-Port-Of: odoo/odoo#268700 Forward-Port-Of: odoo/odoo#268501
14 changes
Resolved issues and error corrections
This update resolves a crash in the Asset Depreciation Schedule report that occurred when analyzing large groups of assets with period comparisons enabled. The fix ensures the report handles missing data gracefully, preventing errors and allowing customers to accurately view their asset reports. This improves report stability and usability for our enterprise customers.
Original PR description
#### Description of the issue/feature this PR addresses: Opening the Asset Depreciation Schedule report with a period comparison enabled crashes with KeyError: 'no_format' when prefix grouping is…
#### Description of the issue/feature this PR addresses:
Opening the Asset Depreciation Schedule report with a period comparison enabled crashes with KeyError: 'no_format' when prefix grouping is active (large number of assets in one account group). The report becomes unusable for affected customers.
#### Current behavior before PR:
_regroup_lines_by_name_prefix sums each subline column by indexing prefix_subline['columns'][i]['no_format'] directly. Empty columns are built as {} by _build_column_dict (both col_value and col_data are None), so they have no 'no_format' key. With a comparison period enabled, an asset that has no value in the comparison period produces an empty column for that period; once prefix grouping fires (len(lines) >= prefix_groups_threshold, default 4000), the direct lookup hits that empty dict and raises KeyError: 'no_format'.
#### Desired behavior after PR is merged:
The prefix group total treats a missing 'no_format' as 0, matching the sibling caller in account_asset/models/account_assets_report.py that already guards with .get('no_format', 0). The report builds without crashing and the empty comparison column contributes 0 to the prefix group total.
opw-6225639
Forward-Port-Of: odoo/enterprise#119775
Forward-Port-Of: odoo/enterprise#119088This fix resolves a problem where emails with attachments triggered errors due to concurrent updates in the database. The update prevents unnecessary bounce emails by addressing how the system handles updates during email processing and attachment handling, improving email reliability.
Original PR description
Since https://github.com/odoo/odoo/commit/17893089e8b21c0ecab5e61ed8e2c33f3731b3ac, in certain cases, customers sending large batches of emails to an accounting email alias would report a small…
Since https://github.com/odoo/odoo/commit/17893089e8b21c0ecab5e61ed8e2c33f3731b3ac, in certain cases, customers sending large batches of emails to an accounting email alias would report a small number of emails being bounced (ca. 5%). Context: 1. While processing an email (after matching mail.alias, with the thread going through `message_process`), if an error is uncaught and raised, the mailgate generates a bounce email, as we presume that the email could not be processed correctly. 2. When sending an email with an attachment to an accounting journal alias, depending on the DB configuration, IAP calls for automatic OCR are triggered asynchronously. These calls trigger callbacks from the IAP server, which might hit the DB in parallel while another thread is processing another email. Given their nature, they trigger updates on the relevant account.move, thus triggering downstream computes in the model. 3. When processing an attachment, the account module triggers `_extend_with_attachments`, which tries decoding the attachment in a rollback context (see: https://github.com/odoo/odoo/blob/31df5033e31c193b4576ef37dfbc5fc683817bc5/addons/account/models/account_document_import_mixin.py#L343-L344). If a SerializationError happens during that process (concurrent update), it will NOT use the retry mechanism of the ORM because the error is caught in the `except Exception` block. Instead, it will try to post a message to the record to inform the user that the attachment could not be processed. 4. The commit mentioned above changes the way `_update_sequence_made_gap` works. One side effect seems to be that every time `made_sequence_gap` is re-assigned (even if the value does not change per se), the ORM tries to update the `write_date` on the flagged invoice that generated a sequence gap. Bug: Given the above context, emails might bounce unnecessarily for a valid email alias and a valid email with an attachment if: 1. The journal is not using a slash-based sequence pattern (e.g., using "1234" for the naming instead of "INV/2026/1234"). In that case, `sequence_prefix` == "". 2. The first invoice does not start at "1". 3. When sending a burst of simultaneous emails in a multi-worker setup, each thread will trigger `message_process` and downstream accounting computes while processing the invoice. It will also trigger IAP calls and callbacks asynchronously when automatic digitization is activated. 4. Each draft invoice that is created is named "/", meaning `sequence_prefix` == "", which in turn re-triggers the checks in `_update_sequence_made_gap`. 5. This increases the chances dramatically of a serialization error while all the parallel processes indirectly trigger an update on the `made_sequence_gap` field of invoice "1234". 6. Most of the time, the serialization error is not triggered in the thread processing the email, which correctly retries it. But in the few unlucky cases where it is raised in the thread processing the email, it will be triggered in the transaction rollback in `_extend_with_attachments`. While handling the exception, it triggers a second error because it tries to post a message to the record that was just rolled back: -> `ERROR: current transaction is aborted, commands ignored until end of transaction block` is raised in the thread running `message_process`, which in turn triggers a bounce email. Example logs (simplified): ``` 2026-06-12 14:12:15 [Worker-Thread-101] INFO mail_thread: Routing email (1) 2026-06-12 14:12:15 [Worker-Thread-102] INFO mail_thread: Routing email (2) 2026-06-12 14:12:16 [Worker-Thread-101] INFO iap_tools: dispatching /parse 2026-06-12 14:12:16 [Worker-Thread-102] INFO iap_tools: dispatching /parse 2026-06-12 14:12:18 [Worker-Thread-101] INFO iap_tools: Webhook received, triggering /get_result 2026-06-12 14:12:18 [Worker-Thread-102] INFO iap_tools: Webhook received, triggering /get_result 2026-06-12 14:12:19 [Worker-Thread-101] INFO odoo.sql_db: UPDATE "account_move" SET "made_sequence_gap" = true WHERE "id" = 1234 -> STATUS: OK (Acquired Row Lock) 2026-06-12 14:12:19 [Worker-Thread-102] ERROR odoo.sql_db: bad query: UPDATE "account_move" SET "made_sequence_gap" = true WHERE "id" = 1234 ERROR: could not serialize access due to concurrent update psycopg2.errors.SerializationFailure: could not serialize access 2026-06-12 14:12:19 [Worker-Thread-102] ERROR odoo.sql_db: bad query: SELECT "mail_message"."id" FROM "mail_message" WHERE ... ERROR: current transaction is aborted, commands ignored until end of transaction block psycopg2.errors.InFailedSqlTransaction: transaction is aborted 2026-06-12 14:12:19 [Worker-Thread-102] INFO "POST /saas_worker/smtp" 200 -> triggers Bounce email ``` Proposed Fix: A) We update the conditions in `check_around` to ignore draft invoices when they are the "previous" entity being checked. Only posted invoices should be considered when doing the gap checks. B) We add some guard clauses to prevent unnecessary writes to invoices that created sequence gaps. Instead of assigning values directly, we store the result of the check and only assign `made_sequence_gap` explicitly if the value is different from the currently stored value. This prevents unnecessary writes to the record if the value did not change. Note: - We chose this approach instead of touching `_extend_with_attachments` and the rollback context directly. Mostly to prevent any unforseen side-effects, given that this methods are used in accounting for all attachments. But it might be worth analysing if those methods might be improved to handle scenarios as described above in multi-worker setups + email handling. - fixing the rollbackable context might tricky because the serialization error happens at the first `cr.commit()` inside the context manager - raising explicitly with `except psycopg2.extensions.TransactionRollbackError:` in `_extend_with_attachments` retries the whole request to the `message_process`, which might not be a good idea OPW-6272396 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270251
This update corrects a visual issue where product images in the self-order system appeared distorted. By applying a scaling technique, the images are now displayed correctly and fully, providing a better customer experience. This ensures accurate product representation for customers using the self-order functionality.
Original PR description
In this commit: ------------------- - Applied `object-fit: scale` to ensure product images are fully visible and properly displayed without distortion. task: [6260046](https://www.odoo.com/odoo/project.task/6260046) Forward-Port-Of: odoo/odoo#270387 Forward-Port-Of: odoo/odoo#268521
This update resolves an issue where the l10n_sa_edi E-invoicing module would crash during installation if certain taxes were missing. The fix filters out missing taxes during the installation process, ensuring a smoother and more reliable installation experience for users in Saudi Arabia.
Original PR description
**Issue:** Installing the l10_sa_edi E-invoicing module causes an error in versions 19.1 and above if any of the taxes in the account.tax-sa.csv are missing. This behavior was previously avoided via the post init function _l10n_sa_edi_post_init(), which no longer works due to the change made to ir_module.py fetching the template data during the module installation (made in commit 64f9dcb). **Reproduction Steps:** Install Accounting Configuration > Settings > Change "Fiscal Localization" to Saudi Arabia Configuration > Taxes > Delete 0% "Not Subject to VAT" tax Try to install l10n_sa_edi Saudi Arabia - E-invoicing **Fix:** Updated '_get_sa_edi_account_tax()to filter out taxes that don't already exist on the database. Removed the_l10n_sa_edi_post_init()` function since it should now be obsolete. Related ticket: opw-6293740
This update fixes an issue where the chatter in tracked orders incorrectly displayed the employee who made changes, even if that employee wasn't currently logged in. Now, the chatter accurately reflects the employee who made the most recent change, ensuring accurate order tracking and communication.
Original PR description
**Steps to reproduce:** - Enable "Track orders edits" in the settings - Enable "Log in with Employees" - Go to the Restaurant, log in with employee A - Go to a table, order 3 Sushis - Go back to the…
**Steps to reproduce:** - Enable "Track orders edits" in the settings - Enable "Log in with Employees" - Go to the Restaurant, log in with employee A - Go to a table, order 3 Sushis - Go back to the floor plan and change to employee B - Go back to the table and change the qty of 3 Sushis to 2 Sushis - Go to the order in the backend and check the chatter - It will indicate that employee A did the change, but it was employee B **Why the fix:** We always used the cashier set on the order to determine who should be put in the chatter, regardless of who is actually connected at that point. We now use the session's current employee to write who did the change in the chatter. We do not change the order's employee, because it will be done once the order has been paid. In the case where we are not logged in but pos_hr is installed, the employee_id might be the id of a res.user, and browsing it might return the wrong value. To avoid this, we check if the value exists as a hr.employee before assigning the name. The way we return the value has been changed because the linter wasn't happy about it. opw-6213504 Forward-Port-Of: odoo/odoo#265582
This update fixes inaccurate Cost of Goods Sold (COGS) calculations for kit products in Odoo. The fix addresses issues with multiple-step deliveries, multiple kits in a BOM, and FIFO inventory valuation, ensuring correct COGS are calculated for all kit scenarios. The changes improve the accuracy of sales invoices and inventory valuation.
Original PR description
There's a few problems with kits and cogs This PR fixes them and unskips most tests of the test class. **Problems:** - Problem 1 multiple steps delivery - steps to reproduce: - activate 3 steps…
There's a few problems with kits and cogs
This PR fixes them and unskips most tests
of the test class.
**Problems:**
- Problem 1 multiple steps delivery
- steps to reproduce:
- activate 3 steps delivery
- create 2 storable products 'comp A' and 'comp B'
with category standard perpetual
- for both : set a cost of 10 and on on hand quantity
- create a storable kit product with category standard perpetual
- create a kit bom for the kit product with 1 comp A and 1 comp B
- confirm a SO for 1 quantity of the kit prod
- validate only first delivery
- confirm invoice
- Current behaviour:
No cogs line
- expected behaviour :
There should be cogs for 20$
- Problem 2 multiple kits in Bom :
- steps to reproduce:
- (multiple steps delivery not needed)
- use same products as for problem 1 but, in the Bom, set
the number of kit products produced to 2
- confirm a SO for 2 quantity of the kit prod
- validate all pickings
- confirm invoice
- Current behaviour:
Cogs have a value of 10$
- expected behaviour :
There should be cogs for 20$
- Problem 3: fifo comp
- steps to reproduce:
- with 1 step delivery
- create a storable product 'comp A' with fifo perpetual
category
- Confirm a PO and validate receipt for 1 comp A at 10
- Confirm a PO and validate receipt for 1 comp A at 20
- create a storable product 'kit' with fifo perpetual categ
- create a kit bom for the kit product with 1 comp A
- confirm SO for 2 kit
- deliver 1 quantity and create backorder
- confirm invoice for 1
- COGS line are created for 10$ (as expected)
- deliver the backorder
- confirm invoice for 1
- Current Behaviour:
Cogs are created for 15$
- Expected Behaviour:
Cogs should be created for 20$
**Cause of the issues:**
To compute the price_unit used for the cogs we call
_get_cogs_value()
https://github.com/odoo/odoo/blob/f8741728294a5147c7d2427d9997738096386262/addons/stock_account/models/account_move.py#L122
What we want is the price unit for 1 unit of the kit product
So we want :
sum(unit price of each comp * quantity of comp in bom)/ quantity of kit in bom
What is done for now :
Inside the sale_mrp override, for each component of
the bom we call _get_price_unit() on its move and
add the value to 'average_price_unit' and then divide
by the quantity of the kit product in the bom
https://github.com/odoo/odoo/blob/f8741728294a5147c7d2427d9997738096386262/addons/sale_mrp/models/account_move.py#L38-L42
Inside the sale_mrp override of _get_price_unit()
we return _get_kit_price_unit() called on the move,
https://github.com/odoo/odoo/blob/f8741728294a5147c7d2427d9997738096386262/addons/sale_mrp/models/stock_move.py#L15
Inside _get_kit_price_unit(), the variable 'component_qty_per_kit',
contains the quantity of each component as recorded in the bom
times the valued quantity (sale order line quantity).
For each comp :
- we store the return value of _get_price_unit
called on its moves in 'price_unit'.
- we add to 'total_price_unit':
price_unit * component_qty_per_kit/ the kit qty in the bom
we then return total_price_unit / valued quantity
So we actually return:
sum(unit price of each comp * quantity of comp in bom*
valued quantity)/ (quantity of kit in bom * valued quantity)
which is equal to:
sum(unit price of each comp *quantity of comp in bom)
/ quantity of kit in bom
https://github.com/odoo/odoo/blob/38c737c2a4cc29b48235a100cfa9d6152af73826/addons/mrp_account/models/stock_move.py#L40-L44
Problem 1 is caused by the fact that _get_price_unit()
will return 0 if there's only internal moves because
they have a value of 0.
(The problem does not happen with a single component
cause then the fallback on the super method is correct, but
with multiple comp the super method also returns 0
because _get_cogs_price_unit returns 0 when more than
one product).
Problem 2 is caused by the fact that we divide by the
quantity of the kit in the bom (kit_bom.product_qty) here
(inside _get_kit_price_unit) and again inside _get_cogs_value
as mentionned before.
Problem 3 happens because there is no mechanism
to account for already posted cogs inside the sale_mrp
override of _get_cogs_value(), as qty_invoiced
is computed but never used
https://github.com/odoo/odoo/blob/38c737c2a4cc29b48235a100cfa9d6152af73826/addons/sale_mrp/models/account_move.py#L31
**Fix**
As regards to the super methods (so non kit scenario),
_get_cogs_value() is used to :
- use original invoice if needed
- use standard price of the product if no moves
- deduct already posted cogs
- calls get _get_cogs_price_unit() to compute price_unit
based on the moves
All of this is also wanted for kits and don't need adaptation,
therefore the override should be on the _get_cogs_price_unit
where we do need a different behaviour when the product is a kit
Doing this we benefit from the 'already posted mechanism'
from _get_cogs_value which solves problem 3
Additionally, instead of calling get_price_unit we can directly
call the super method _get_cogs_price_unit as we have
already computed all the components quantities needed
for our computation and therefore don't need
_get_kit_price_unit to recompute all of this.
Also, _get_cogs_price_unit will fall back on the product
standard price if the move has no value which solves
problem 1.
That will also prevent dividing twice by the quantity
of kit product in the bom (bom.product_qty)
which solves problem2.
**Tests:**
Out of the 9 existing tests of the class (that were skipped
before this PR) and after adapation to v19 valuation :
- 2 succeeded before and after the fix : this PR unskips them
- 5 failed before the fix and now suceed with the fix : this PR
unskips them
- 2 failed before the fix and after the fix, they were let
skipped
In addition, 2 tests were added to cover problem 1 and 3
(problem 2 is covered in test test_sale_mrp_kit_bom_cogs)
Forward-Port-Of: odoo/odoo#270075This update resolves an issue where related fields weren't correctly reflecting new selection choices, particularly when using the Studio environment. The fix ensures that related fields are properly updated after a selection is changed, preventing data inconsistencies. This improves data accuracy and reliability.
Original PR description
This is because webclient knows the current value (c), but not the new available choices, still with the previous one (a, b). Actually this works correctly if the field is created within a model…
This is because webclient knows the current value (c), but not the new
available choices, still with the previous one (a, b).
Actually this works correctly if the field is created within a model
class.
```py
if model_cls._setup_done__ and field._base_fields__:
# the field has been created by model_classes._setup() as
# Field(_base_fields__=...); restore it to force its setup
name = field.name
base_fields = field._base_fields__
field.__dict__.clear()
field.__init__(_base_fields__=base_fields)
field._toplevel = True
field.__set_name__(model_cls, name)
field._setup_done = False
models_field_depends_done.discard(model_cls)
```
It does not works with studio because there are no parent class
(`_base_fields__`), so the if is not reached.
A solution would be to check if the field is a manually created related
and mark the whole model for setup unlike when `_base_fields__` is
present where we only setup this specific field.
opw-6293768
Forward-Port-Of: odoo/odoo#270349This update corrects a rejection issue with the 3519 VAT reimbursement form by ensuring the correct 'millesime' (form version year) is used when sending data to the French tax authority (DGFiP). Previously, outdated millesimes caused rejection, but the 3310CA3 return was accepted due to its consistent format. This change ensures compliance and accurate VAT reporting.
Original PR description
The 3519 reimbursement form is rejected by the DGFiP with "Le millesime 25 du formulaire 3519 est inconnu dans la teleprocedure TVA". The 3310CA3 return is still accepted, because its layout is unchanged year-on-year, which hides the problem, but it is sent with a millesime that no longer matches the campaign. The millesime is the form-version year. The EDI-TVA 2026 campaign opened on 2026-02-09. last update: https://github.com/odoo/enterprise/pull/92542 opw-6275695 Forward-Port-Of: odoo/enterprise#120759
This update fixes an issue where canceling a down payment invoice incorrectly triggered a CFDI cancellation request. The system now correctly uses the '04' origin type for CFDI cancellations, aligning with Mexican regulations and preventing unintended down payment cancellations. This ensures accurate CFDI processing and compliance.
Original PR description
**Steps to reproduce:** - Install Sales, Accounting and l10n_mx_edi - Switch to a Mexican company (e.g. ZAPATERIA URTADO ÑERI) - Create a SO: * Customer: [a Mexican customer] (e.g. INMOBILIARIA CVA) * Payment Way: Efectivo * Payment Policy: PUE * Product: [any product with a UNSPSC Category] * Taxes: [any] (e.g. 16%) - Confirm the SO - Create a down payment (e.g. 60%) - Confirm the down payment - Send it to CFDI - Copy the fiscal folio - Go back to SO - Create the final invoice - Set the copied fiscal folio prepend with "07|" as CFDI Origin - Confirm the invoice - Send to CFDI **Issue:** A cancellation request is sent to CFDI for the down payment. "07" origin code is used to link the invoice to a down payment. It should not cancel the down payment. It should only be done with "04" origin code used for substitution of a previous invoice. opw-6266678 Forward-Port-Of: odoo/enterprise#120757
This update resolves an issue where recurring plans would disappear when updating product quantities or prices. The fix ensures the selected plan is consistently displayed regardless of changes, improving the subscription experience for users. This was caused by a misinterpretation of the 'allow_one_time_sale' flag.
Original PR description
# Introduction note This PR fixes two bugs introduced by the same commit : https://github.com/odoo/enterprise/commit/106d70a1ef0ddbd61a74b7cac82dfce1e316beaa The original commit fixed multiple issues…
# Introduction note This PR fixes two bugs introduced by the same commit : https://github.com/odoo/enterprise/commit/106d70a1ef0ddbd61a74b7cac82dfce1e316beaa The original commit fixed multiple issues regarding the display of recurring plans when the One-time purchase option was enabled, but it also introduced new ones. Theses new issues are due to multiple new checks on `allow_one_time_sale`, but this variable only indicates that the One-time purchase option is available to the user, not that it is actually selected. So the fixes of the original commit works when first loading the page, but fails when the content of the page is updated. # Shared steps - Activate Subscriptions & eCommerce modules - Create a subscription product, enable 'Accept One-Time' and publish it on the website # Bug 1 ## How to reproduce - Add atleast two recurring plans to the product - Go to the product page on the website - Select one of the recurring plans - Increase the quantity of the product ## The problem The recurring plan selection is removed ## Cause The condition `!combination_info.allow_one_time_sale` was added on the `t-att-checked` of the recurring plan selection display. This correctly fixed the issue when first loading the page, but when the user changes the price or the variant, the recurring plan are recomputed and rerendered : https://github.com/odoo/enterprise/blob/0b408acbadb2cfcbc844521f3244a06b7ae7be22/website_sale_subscription/static/src/interactions/product_page.js#L37-L40 When that is the case, that condition blocks the proper display of the selected recurring plan. ## Proposed Solution When loading the recurring plan selection, what defines wich plan is selected is the `subscription_default_pricing_plan_id` variable, which is based on the `plan_id` value given in the request to the server : https://github.com/odoo/enterprise/blob/0b408acbadb2cfcbc844521f3244a06b7ae7be22/website_sale_subscription/models/product_template.py#L222 We make it so if no `plan_id` is sent to the server and `allow_one_time_sale` is enabled, then the server does not give back any `subscription_default_pricing_plan_id` opw-6131532 # Bug 2 ## How to reproduce - Add an attribute with values A & B for the product - Define atleast two recurring plans for the variant with attribute B - Publish the product - Go to the product page - Select the variant with attribute B ## The problem The recurring plan is not displayed. If the order of the attribute is reversed, then it works as expected. ## Cause The pricings are correcly sent to the front-end but they are not added to selection because of the check on `allow_one_time_sale` : https://github.com/odoo/enterprise/blob/0b408acbadb2cfcbc844521f3244a06b7ae7be22/website_sale_subscription/static/src/interactions/product_page.js#L42-L50 opw-6132160 Forward-Port-Of: odoo/enterprise#115446
This update resolves an issue where creating RFQ approval requests could trigger an access error when using supplier pricelists with inaccessible vendors. The fix ensures the system correctly handles vendor access restrictions, preventing errors during approval workflows. This improves the reliability of the approval process for users with limited vendor access.
Original PR description
**Issue** Having supplier pricelists with at least one vendor inaccessible to the current user can trigger an access error when creating an RFQ approval request. **Steps to reproduce** - Have two…
**Issue** Having supplier pricelists with at least one vendor inaccessible to the current user can trigger an access error when creating an RFQ approval request. **Steps to reproduce** - Have two companies A and B and two users u1 and u2 - user u2 only have access to company A - With user u1: - Create two vendors v1 and v2 without any company assigned - Create vendor pricelists for a product for each vendor and assign the company A to the pricelist - Add the company B for the vendor v2 - With user u2: - Open approval application - Try to create an approval for an RFQ for that product (the vendor v1 will be automatically selected) - Save it -> An access error is thrown **Cause** Saving the approval request computes `has_no_seller`, which calls `_select_seller`: https://github.com/odoo/enterprise/blob/03c737685ff6dfc95a8bc72491646774fc426b1f/approvals_purchase/views/approval_product_line_views.xml#L9 https://github.com/odoo/enterprise/blob/03c737685ff6dfc95a8bc72491646774fc426b1f/approvals_purchase/models/approval_product_line.py#L32 https://github.com/odoo/enterprise/blob/03c737685ff6dfc95a8bc72491646774fc426b1f/approvals_purchase/models/approval_product_line.py#L62-L70 Which filtered the right seller https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_product.py#L759 By preparing the sellers: https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_product.py#L721 https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_product.py#L712 Please note that `self.seller_ids` contains both sellers (even v2) By filtering the suppliers: https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_supplierinfo.py#L104-L105 But at that point, one of the supplier in `self`, can be accessed, thus an access error is thrown while trying to access its associated `partner_id`. opw-6203910 Forward-Port-Of: odoo/odoo#269552
This update resolves an issue where creating RFQ approval requests could trigger access errors when using supplier pricelists with inaccessible vendors. The fix ensures correct vendor selection during approval request creation, preventing errors related to user access restrictions.
Original PR description
**Issue** Having supplier pricelists with at least one vendor inaccessible to the current user can trigger an access error when creating an RFQ approval request. **Steps to reproduce** - Have two…
**Issue** Having supplier pricelists with at least one vendor inaccessible to the current user can trigger an access error when creating an RFQ approval request. **Steps to reproduce** - Have two companies A and B and two users u1 and u2 - user u2 only have access to company A - With user u1: - Create two vendors v1 and v2 without any company assigned - Create vendor pricelists for a product for each vendor and assign the company A to the pricelist - Add the company B for the vendor v2 - With user u2: - Open approval application - Try to create an approval for an RFQ for that product (the vendor v1 will be automatically selected) - Save it -> An access error is thrown **Cause** Saving the approval request computes `has_no_seller`, which calls `_select_seller`: https://github.com/odoo/enterprise/blob/03c737685ff6dfc95a8bc72491646774fc426b1f/approvals_purchase/views/approval_product_line_views.xml#L9 https://github.com/odoo/enterprise/blob/03c737685ff6dfc95a8bc72491646774fc426b1f/approvals_purchase/models/approval_product_line.py#L32 https://github.com/odoo/enterprise/blob/03c737685ff6dfc95a8bc72491646774fc426b1f/approvals_purchase/models/approval_product_line.py#L62-L70 Which filtered the right seller https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_product.py#L759 By preparing the sellers: https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_product.py#L721 https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_product.py#L712 Please note that `self.seller_ids` contains both sellers (even v2) By filtering the suppliers: https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_supplierinfo.py#L104-L105 But at that point, one of the supplier in `self`, can be accessed, thus an access error is thrown while trying to access its associated `partner_id`. opw-6203910 Forward-Port-Of: odoo/enterprise#120251
This update optimizes how Odoo searches for documents, specifically addressing a complex query that slowed down searches for documents not marked as 'SHARED'. This change aligns with the performance of our production database and enhances search efficiency for users.
Original PR description
Searching for "not 'SHARED'" results in a very complex query. Our own production DB prefers this implementation, also easier to read. credit: https://github.com/odoo/enterprise/pull/105915#discussion_r2745148099 Task-5893183
This update resolves an issue where the appointment calendar displayed 'no available slots' for future months when appointment scheduling lead times were long. The fix accounts for lead times to accurately calculate availability, ensuring the calendar correctly reflects available slots when navigating forward.
Original PR description
The website appointment calendar fills availabilities one month at a time and the update_available_slots route maps the calendar month index to an absolute month from datetime.now(). This only…
The website appointment calendar fills availabilities one month at a time and the update_available_slots route maps the calendar month index to an absolute month from datetime.now(). This only matches the displayed months when the first one is the current month. When the first bookable slot is later, a punctual appointment starting in a future month or any appointment whose "at least X hours before start time" lead time pushes the first slot past the current month, navigating forward requests the wrong month and the reached month renders empty. In update_available_slots, take the lead time into account when computing the reference month so it lands on the first displayed month: the start datetime for a punctual appointment starting in the future, otherwise now plus the minimum schedule hours. The navigated month index is then added to that reference. This extends https://github.com/odoo/enterprise/commit/f0e5b14a823cf97218f4094d287a328e2744fd73 which only handled the future start datetime. Steps to reproduce: 1. Open the Appointments app 2. Open an appointment type, set Schedule to Weekly and Allow Bookings to On specific dates with a range ending a few months out 3. Set the "at least N hours before start time" field to 360 4. Save and click the Preview button in the header 5. Pick a resource or staff member to reach the calendar 6. Click the right arrow to navigate to the next month => the next month shows "Sorry, we have no more slots available for this month" opw-6206293 Forward-Port-Of: odoo/enterprise#120715
3 changes
Resolved issues and error corrections
This update resolves an issue where creating approval requests could trigger an access error when using suppliers with inaccessible vendors. The fix ensures the system correctly handles vendor access restrictions during the approval process, preventing errors and improving user experience. This change focuses on the product approval workflow.
Original PR description
**Issue** Having supplier pricelists with at least one vendor inaccessible to the current user can trigger an access error when creating an RFQ approval request. **Steps to reproduce** - Have two…
**Issue** Having supplier pricelists with at least one vendor inaccessible to the current user can trigger an access error when creating an RFQ approval request. **Steps to reproduce** - Have two companies A and B and two users u1 and u2 - user u2 only have access to company A - With user u1: - Create two vendors v1 and v2 without any company assigned - Create vendor pricelists for a product for each vendor and assign the company A to the pricelist - Add the company B for the vendor v2 - With user u2: - Open approval application - Try to create an approval for an RFQ for that product (the vendor v1 will be automatically selected) - Save it -> An access error is thrown **Cause** Saving the approval request computes `has_no_seller`, which calls `_select_seller`: https://github.com/odoo/enterprise/blob/03c737685ff6dfc95a8bc72491646774fc426b1f/approvals_purchase/views/approval_product_line_views.xml#L9 https://github.com/odoo/enterprise/blob/03c737685ff6dfc95a8bc72491646774fc426b1f/approvals_purchase/models/approval_product_line.py#L32 https://github.com/odoo/enterprise/blob/03c737685ff6dfc95a8bc72491646774fc426b1f/approvals_purchase/models/approval_product_line.py#L62-L70 Which filtered the right seller https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_product.py#L759 By preparing the sellers: https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_product.py#L721 https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_product.py#L712 Please note that `self.seller_ids` contains both sellers (even v2) By filtering the suppliers: https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_supplierinfo.py#L104-L105 But at that point, one of the supplier in `self`, can be accessed, thus an access error is thrown while trying to access its associated `partner_id`. opw-6203910 Forward-Port-Of: odoo/enterprise#120251
This update resolves a bug that prevented receipt printing after the initial order in the Italian POS module. The fix ensures receipts are consistently printed via the payment screen, eliminating a printer deadlock and improving the user experience. The change also simplifies settings for Italian fiscal printers.
Original PR description
Module: l10n_it_pos Steps to reproduce: - In the POS settings, enable "Automatic Receipt Printing"; - Enable "ePos Printer" to make the "Skip Preview Screen" option appear; - Disable "Skip Preview…
Module: l10n_it_pos Steps to reproduce: - In the POS settings, enable "Automatic Receipt Printing"; - Enable "ePos Printer" to make the "Skip Preview Screen" option appear; - Disable "Skip Preview Screen"; - Disable "ePos Printer"; - Set up an Italian Fiscal Printer; - Open a POS session and process a first order. Issue: After the first receipt, no other messages (price display, receipt, open register) are sent to the fiscal printer. A page reload is required. Cause: When "Automatic Receipt Printing" is true but "Skip Preview Screen" is false, a race condition occurs. `afterOrderValidation` triggers a print job while simultaneously transitioning to the `ReceiptScreen`. When the `ReceiptScreen` mounts, it triggers a second fiscal print job before the first has resolved. This creates a deadlock in `toHtml` of `renderService`, permanently blocking the printer queue. Solution: Since the italian localisation sending the receipt to the fiscal printer is mandatory, the printing route is now tied to the "Skip Preview Screen" option. UI settings are adjusted to hide the redundant auto-print checkbox when an IT fiscal printer is configured. Community PR: https://github.com/odoo/odoo/pull/256932 [opw-5979212](https://www.odoo.com/odoo/project/49/tasks/5979212) Forward-Port-Of: odoo/enterprise#120747 Forward-Port-Of: odoo/enterprise#112654
This update significantly reduces memory usage and speeds up the loading of large General Ledgers, particularly when displaying journal lines. The change optimizes how Odoo fetches display names, preventing unnecessary data loading and improving overall system performance. This results in a smoother user experience when working with extensive financial reports.
Original PR description
### Issue Loading a large General Ledger (e.g., during an "Unfold All" action) and retrieving display names for thousands of journal lines (`account.move.line`) causes excessive memory and…
### Issue Loading a large General Ledger (e.g., during an "Unfold All" action) and retrieving display names for thousands of journal lines (`account.move.line`) causes excessive memory and performance overhead. Profiling with `memray` showed that one of the main memory hotspots was located in `custom_label_builder`. **Previous behavior:** Accessing `record.display_name` in a loop without an explicit `fetch()` call triggered lazy computation of the field via `_compute_display_name()`. When the compute method accessed stored dependency fields (such as `name`, `ref`, `move_id`), each cache miss went through `_fetch_field()`, which greedily loaded **all fields sharing the same prefetch group** on the model, far beyond the dependencies of `display_name` alone. This caused the ORM cache to be filled with many unnecessary stored fields for every record in the prefetch set. --- ### Dataset Volume The performance metrics were captured using a dataset consisting of: * **455,694** Journal Items (`account.move.line`) * **19,947** Journal Entries (`account.move`) --- ### Solution Add a single `fetch(['display_name'])` call on the browsed recordset. By calling `fetch(['display_name'])` upfront, the ORM goes through `_determine_fields_to_fetch(['display_name'])`, which walks only the declared `field_depends` of `display_name` and fetches **only those specific stored fields**. nothing more. --- ### Impact & Results | Metric | Before Optimization | After Optimization | Change / Note | | :--- | :--- | :--- | :--- | | **Peak Memory** | ~856 MB | ~223 MB | ~74% reduction | | **Execution Time** | 2.48s | 2.13s | About the same time with multiple tries | OPW-6275158
3 changes
Resolved issues and error corrections
This update resolves an issue preventing users with Sales access from inserting data into Quotation templates via the spreadsheet management feature. The change adds a setting to ensure the necessary flag is activated when the module is installed and the user has the appropriate permissions. This improves usability for Sales teams.
Original PR description
Current behavior before PR: - The `can_insert_in_spreadsheet` session flag was not set by the spreadsheet_sale_management module. - Users with proper Sale access rights still could not insert into Quotation templates. Desired behavior after PR is merged: - Added logic to set `can_insert_in_spreadsheet` when the module is installed and the user has the required access rights. Task: [5960761](https://www.odoo.com/odoo/project/2328/tasks/5960761) Forward-Port-Of: odoo/enterprise#120903 Forward-Port-Of: odoo/enterprise#108674
This update resolves an issue where creating RFQ approval requests could trigger access errors when using supplier pricelists with inaccessible vendors. The fix ensures that the system correctly handles vendor access restrictions, preventing errors during approval request creation. This improves the reliability of the approval process.
Original PR description
**Issue** Having supplier pricelists with at least one vendor inaccessible to the current user can trigger an access error when creating an RFQ approval request. **Steps to reproduce** - Have two…
**Issue** Having supplier pricelists with at least one vendor inaccessible to the current user can trigger an access error when creating an RFQ approval request. **Steps to reproduce** - Have two companies A and B and two users u1 and u2 - user u2 only have access to company A - With user u1: - Create two vendors v1 and v2 without any company assigned - Create vendor pricelists for a product for each vendor and assign the company A to the pricelist - Add the company B for the vendor v2 - With user u2: - Open approval application - Try to create an approval for an RFQ for that product (the vendor v1 will be automatically selected) - Save it -> An access error is thrown **Cause** Saving the approval request computes `has_no_seller`, which calls `_select_seller`: https://github.com/odoo/enterprise/blob/03c737685ff6dfc95a8bc72491646774fc426b1f/approvals_purchase/views/approval_product_line_views.xml#L9 https://github.com/odoo/enterprise/blob/03c737685ff6dfc95a8bc72491646774fc426b1f/approvals_purchase/models/approval_product_line.py#L32 https://github.com/odoo/enterprise/blob/03c737685ff6dfc95a8bc72491646774fc426b1f/approvals_purchase/models/approval_product_line.py#L62-L70 Which filtered the right seller https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_product.py#L759 By preparing the sellers: https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_product.py#L721 https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_product.py#L712 Please note that `self.seller_ids` contains both sellers (even v2) By filtering the suppliers: https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_supplierinfo.py#L104-L105 But at that point, one of the supplier in `self`, can be accessed, thus an access error is thrown while trying to access its associated `partner_id`. opw-6203910 Forward-Port-Of: odoo/odoo#269552
This update resolves an issue where creating RFQ approval requests could trigger access errors when using supplier pricelists with inaccessible vendors. The fix ensures that the system correctly handles vendor access restrictions, preventing errors and improving the approval process for users with limited vendor visibility. This improves the reliability of the approval workflow.
Original PR description
**Issue** Having supplier pricelists with at least one vendor inaccessible to the current user can trigger an access error when creating an RFQ approval request. **Steps to reproduce** - Have two…
**Issue** Having supplier pricelists with at least one vendor inaccessible to the current user can trigger an access error when creating an RFQ approval request. **Steps to reproduce** - Have two companies A and B and two users u1 and u2 - user u2 only have access to company A - With user u1: - Create two vendors v1 and v2 without any company assigned - Create vendor pricelists for a product for each vendor and assign the company A to the pricelist - Add the company B for the vendor v2 - With user u2: - Open approval application - Try to create an approval for an RFQ for that product (the vendor v1 will be automatically selected) - Save it -> An access error is thrown **Cause** Saving the approval request computes `has_no_seller`, which calls `_select_seller`: https://github.com/odoo/enterprise/blob/03c737685ff6dfc95a8bc72491646774fc426b1f/approvals_purchase/views/approval_product_line_views.xml#L9 https://github.com/odoo/enterprise/blob/03c737685ff6dfc95a8bc72491646774fc426b1f/approvals_purchase/models/approval_product_line.py#L32 https://github.com/odoo/enterprise/blob/03c737685ff6dfc95a8bc72491646774fc426b1f/approvals_purchase/models/approval_product_line.py#L62-L70 Which filtered the right seller https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_product.py#L759 By preparing the sellers: https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_product.py#L721 https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_product.py#L712 Please note that `self.seller_ids` contains both sellers (even v2) By filtering the suppliers: https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_supplierinfo.py#L104-L105 But at that point, one of the supplier in `self`, can be accessed, thus an access error is thrown while trying to access its associated `partner_id`. opw-6203910 Forward-Port-Of: odoo/enterprise#120251
1 change
Resolved issues and error corrections
This update resolves an issue where creating approval requests with suppliers having inaccessible vendors triggered an access error. The fix ensures the system correctly handles vendor access restrictions during the approval process, preventing errors and improving user experience.
Original PR description
**Issue** Having supplier pricelists with at least one vendor inaccessible to the current user can trigger an access error when creating an RFQ approval request. **Steps to reproduce** - Have two…
**Issue** Having supplier pricelists with at least one vendor inaccessible to the current user can trigger an access error when creating an RFQ approval request. **Steps to reproduce** - Have two companies A and B and two users u1 and u2 - user u2 only have access to company A - With user u1: - Create two vendors v1 and v2 without any company assigned - Create vendor pricelists for a product for each vendor and assign the company A to the pricelist - Add the company B for the vendor v2 - With user u2: - Open approval application - Try to create an approval for an RFQ for that product (the vendor v1 will be automatically selected) - Save it -> An access error is thrown **Cause** Saving the approval request computes `has_no_seller`, which calls `_select_seller`: https://github.com/odoo/enterprise/blob/03c737685ff6dfc95a8bc72491646774fc426b1f/approvals_purchase/views/approval_product_line_views.xml#L9 https://github.com/odoo/enterprise/blob/03c737685ff6dfc95a8bc72491646774fc426b1f/approvals_purchase/models/approval_product_line.py#L32 https://github.com/odoo/enterprise/blob/03c737685ff6dfc95a8bc72491646774fc426b1f/approvals_purchase/models/approval_product_line.py#L62-L70 Which filtered the right seller https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_product.py#L759 By preparing the sellers: https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_product.py#L721 https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_product.py#L712 Please note that `self.seller_ids` contains both sellers (even v2) By filtering the suppliers: https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_supplierinfo.py#L104-L105 But at that point, one of the supplier in `self`, can be accessed, thus an access error is thrown while trying to access its associated `partner_id`. opw-6203910 Forward-Port-Of: odoo/enterprise#120251
32 changes
New functionality added to Odoo
This update allows for automatic sending of receipts to customers via WhatsApp after a self-order payment is confirmed. Customers receive a digital receipt directly to their WhatsApp, improving convenience and order tracking. This enhancement streamlines the post-purchase experience.
Original PR description
In this commit: - Introduced functionality to send receipts via WhatsApp with preset configuration for customer identification using name and/or address. - The receipt is automatically sent to the customer via WhatsApp when the payment is confirmed, and the user reaches the confirmation page. Related: - Community: https://github.com/odoo/odoo/pull/261943 Task-6111947
This update adds support for popular food delivery services – Talabna, Mandoob, Snoonu, DiDi Food, and Zyada – across various countries. This expansion allows our users to offer their customers a wider range of delivery options, improving convenience and market reach.
Original PR description
In this commit: - We are introducing new delivery providers like Talabna, Mandoob, Snoonu, DiDi Food, and Zyada for different countries. Task-6263289,6263272,6263203,6263165,6310690
This update adds support for Belgium's specific prophylactic leave requirements, separating them into two categories: maternity protection and health risk. Both types of leave are now correctly handled in the payroll system as unpaid, ensuring accurate and compliant payroll processing for Belgian users.
Original PR description
# [IMP] hr_work_entry: add prophylactic leave for Belgium Divided existing prophylactic leave into two categories: maternity protection -> LEAVE14849 / dmfa_code: 51 health risk -> LEAVE225 (existing) / dmfa_code: 53 Added both as unpaid in the payroll structure PR community: 269779 task-6285834
This update adds a new payslip layout specifically designed to meet Indonesian payroll regulations. The changes group salary components (income, deductions, benefits) with totals and key figures like 'Take home pay' and 'Gross Income,' ensuring compliance with local standards and improving clarity for employees.
Original PR description
Add an Indonesian payslip layout that groups salary lines into Income, Deduction and Benefits blocks with their respective totals, plus Take home pay and Gross Income, so the printed payslip better follows the Indonesian standard. task-3112794
Enhancements to existing features
This update enhances the sales dashboard by correctly incorporating subscription data. Specifically, the system now recognizes and displays subscription products within the pivot table view. This ensures more accurate reporting and insights related to subscription sales performance.
Original PR description
Domaine updated for Pivot** #2 Addition of Product > Subscription Product is set on Pivot #2 Task: 6079819
This commit implements changes to align with Welmec certification requirements for the point-of-sale system. Specifically, it ensures order lines are visually marked as deleted, units are displayed correctly, and key numbers are large enough for readability. The LNE certificate number is also now prominently displayed.
Original PR description
See: https://github.com/odoo/odoo/pull/269211 This commit makes the following changes in order to satisfy the WELMEC certification requirements: - Whenever a weighed order line is deleted, instead of disappearing completely it remains visible to the customer but with a strikethrough. - The 'kg' unit is now always displayed to the right of the quantity in the order lines, never below it. - The size of the weight and price numbers when weighing a product have been increased (the guide specifies 9.5mm tall, but we have no physical control of the screen/zoom/PPI, so an `h1` equivalent size is used). - When the tare function is inactive on the scale, we now display 'Gross Weight' instead of 'Net Weight'. - The LNE certificate number is now always visible next to the certified scale icon. task-6273412 <img width="402" height="602" alt="image" src="https://github.com/user-attachments/assets/dd866c5b-d6b3-45a6-8d97-59dbe49c0a0a" />
This update simplifies lead management by directly linking existing subscriptions to leads. Salespeople now have a quick way to view and access customer subscriptions, enabling them to accurately create renewals and upsells. The system automatically connects new quotations to the original lead, streamlining the sales process.
Original PR description
Before this commit, leads did not display a customer's active subscriptions. Salespeople had no direct shortcut to existing contracts, making it difficult to ensure new quotations were correctly created as renewals or upsells for those records. After this commit, a smart button is added to the Lead form showing the count of subscriptions linked to the contact or its parent. Clicking it navigates to the subscription(s). Creating a renewal or upsell from this view automatically links the new quotation to the original lead via context. taskid-6124059
This update merges the 'Ask AI' and 'Odoo Agent' into a single 'Odoo AI' agent, streamlining the AI experience for users. It also optimizes how context data is handled, reducing unnecessary information and improving performance. Finally, the AI agent now supports more complex requests and integrates better with SEO optimization.
Original PR description
Purpose: -------- The "Ask AI" and "Odoo Agent" agents are quite similar except that the latter can not open views. However, users may want to go to another view when using AI from a record. So instead of having two almost identical agents, they are merged into a single "Odoo AI" agent. To avoid context bloating, the list of available menus and models are moved from the initial context to the tool result of the load_topics tool, which allows to only include them when needed. Some columns are also removed from the get_menus and get_model tools because they provided duplicate or inaccurate info (eg. app name is in the complete_path, or model_description was included in the result of both tools although the models are always included in the context if the menus need to be included). Task-6234767
This update enhances the user experience when managing holiday pay within the payroll process. The changes include visual cues – color-coding and tooltips – to highlight outstanding holiday balances and required actions, making it easier for HR staff to track and manage time off allocations. This improves clarity and efficiency.
Original PR description
This commit improves the user experience with the following changes: - Remove the global warning alert banner from the form layout view. - Color the background in orange and add a custom tooltip if the "Allocated" value is different than 0. - Color the background in blue if the "To Allocate" value equals 0 to indicate action is required. - Hide the "Postpone Remaining" columns automatically if the total remaining days across all records is 0. Task: 6259158
This update introduces a sticky reminder pop-up that appears when employees are actively working, prompting them to start their timesheets. This prevents inaccurate attendance records and payroll errors caused by employees forgetting to check in. The reminder is targeted based on employee roles and configurations.
Original PR description
Employees working during business hours sometimes forget to check in or start their timesheet session, which leads to inaccurate attendance records and payroll discrepancies. Before: The systray only…
Employees working during business hours sometimes forget to check in or start their timesheet session, which leads to inaccurate attendance records and payroll discrepancies. Before: The systray only displayed a passive check-in indicator that users could easily overlook during their daily workflow. After: A sticky reminder popover appears when the presence service detects activity, then waits 60 seconds. If the tab remains focused for the full duration, the reminder is shown. Subsequent presence events during the wait do not restart the timer, ensuring a single consistent trigger. The reminder only appears for configured employees: - Attendance only: when "Attendance Based" is enabled on the profile. - Timesheets only: for all timesheet users. - Both installed: if either condition is met. The timer cancels if the tab loses focus or the employee checks in. Clicking the reminder opens the systray dropdown, with wording that adapts to attendance or timesheet context. task-6171500
This update streamlines the Gantt chart's progress bars, providing clearer visual indicators of task completion and workload. The redesign focuses on a cleaner, more intuitive display of remaining hours and capacity, enhancing overall project tracking. Technical changes consolidate the progress bar code for improved efficiency.
Original PR description
*: mrp_workorder, planning, project_enterprise These commits revert https://github.com/odoo/enterprise/pull/101732 and introduce a completely overhauled design and architecture for Gantt row progress…
*: mrp_workorder, planning, project_enterprise These commits revert https://github.com/odoo/enterprise/pull/101732 and introduce a completely overhauled design and architecture for Gantt row progress bars: **Visual & UX Overhaul:** * Introduces a slim, always-visible 5px bar below the row title text, spanning from the title's start column to the right edge of the sidebar (removing previous hover interactions). * Displays remaining available hours as a small text label flush-right inside the row title, which turns red when the row is over capacity. * Adds a tooltip to the progress bar showing the raw breakdown: `value / max (ratio%)`. * Hides the progress bar and label entirely on rows lacking a title. * Stops accumulating left-indent for records inside sub-groups; only group header rows now indent based on nesting level. * Aligns the bar's start column with the row title's indentation, keeping nested group rows visually consistent. * Maintains progress bar support to the total row, overlaid at the bottom via absolute positioning so it does not inflate the sidebar height. **Technical Refactoring:** * Reduces `--Gantt__RowHeader-template-column` from 12px to 8px. * Removes the `MRPWorkorderGanttRowProgressBar` override, as the feature it introduced is now core. * Deletes the `GanttRowProgressBar` OWL component entirely; progress bar rendering is now inlined directly into the renderer templates. Adapts the related overrides to that change. task-6268316
This update consolidates external platform filters into a single "Food Platform" button on the TicketScreen. This simplifies order management and improves the overall user experience by removing confusing multiple filter options. Additionally, an unused field has been removed to streamline the system.
Original PR description
*=pos_urban_piper,pos_enterprise, pos_platform_order, pos_blackbox_be Before this commit: =================== - The TicketScreen displayed separate "Plat. Orders" and "Food Platform" filter buttons. Having multiple buttons for external ordering platforms makes the user interface and order management less intuitive. After this commit: ================== - Merged all external platform filters into a single, unified "Food Platform" button. - Also removed the 'iface_print_skip_screen' field as it is no longer used. Task - 6036688 Related Community PR - https://github.com/odoo/odoo/pull/255729 Related Upgrade PR - https://github.com/odoo/upgrade/pull/9815
This update enhances the user interface for managing activities, specifically focusing on sign requests and VoIP interactions. The changes bring greater clarity and consistency to the workflow, particularly when guiding users through activity type changes, and align the UI with the latest 2026 design standards. This improves the overall user experience and streamlines task management.
Original PR description
* More clarity, more 2026 UI. * Improve UX to guide the user trying to change an activity type to sign request as it it not possible. Task-6253574
This update implements Walloon Impulsion reductions for Belgian employees, allowing for monthly deductions based on age (specifically -25 years old) and a 12-month reduction period. The changes ensure accurate payroll calculations and compliance with Belgian regulations, reflecting updates to the country's payroll rules.
Original PR description
Implement Walloon Impulsion reductions in Belgian Payroll. Features: - add support for Impulsion 12 months (monthly deduction from the employee's net salary) - add support for Impulsion -25 years old (monthly deduction from the employee's net salary) - handle old/new regulation rules depending on entitlement start date - add corresponding salary rules on payslips Includes a test for payroll computation. Upgrade PR: https://github.com/odoo/upgrade/pull/10530 task: 6159809
This update prevents customers from viewing detailed timesheets within project sharing portals. It addresses a requirement for some businesses to restrict access to this sensitive information, achieved through website customization settings. This change improves data privacy and control for our enterprise clients.
Original PR description
Some companies may not want customers to see detailed timesheets in project sharing. This change hides all timesheets in the project sharing portal when they are disabled via website customization. task-5139755
This update adds a convenient side panel to the Planning app's calendar and Gantt views, allowing users to easily schedule and reschedule shifts and interventions through drag-and-drop. It also includes improvements to data handling and error prevention, ensuring a smoother and more reliable scheduling experience for Field Service and other planning activities.
Original PR description
This PR adds the side panel feature in the gantt and calendar views of the Planning app (including Field Service). The goal is to allow the user to easily schedule/unschedule their shifts and interventions with a simple drag & drop. related-https://github.com/odoo/odoo/pull/256153 task-5956860
This update enhances the visual appearance of the appointment kanban cards, making them more user-friendly and responsive across different devices. The changes include a refined layout, adjusted column sizes, and a new 'Preview' button replacing the 'Share' button, streamlining the user experience.
Original PR description
This commit improves the visual aspect of the appointment kanban cards by: - reworking the responsive layout - adjusting the size of the columns - hiding unnecessary column when needed It also replaces the "Share" button by a Preview button. task-6069165 & task-5877926
This update simplifies leave scheduling for users and resources within appointments. Previously, managing leaves was complex and inefficient. Now, users can directly create leaves for appointments, streamlining the process and improving scheduling accuracy.
Original PR description
Purpose ======= Make it easier to manage leaves on users and resources in appointment. Specification ============= Previously, from appointment, the user could only set leaves on…
Purpose ======= Make it easier to manage leaves on users and resources in appointment. Specification ============= Previously, from appointment, the user could only set leaves on 'appointment.resource' records, not for users. To make a user unavailable, they would have to either take a leave, create an event set as busy in their calendar for the period, or install hr_holidays to get the time off form. Also, resource leaves were managed using 'resource.calendar.leaves' records, meaning blocking 4 resources for a small period of time on 5 different days would create 20 records. Now, from appointment, leaves can also be created for users completely independently from their regular hr leaves. As 'res.users' records don't have a 'resource.resource' record if they're not linked to an 'hr_employee', it wasn't optimal to use the 'resource.calendar.leave' model to manage leaves like for the resources. That's why we're introducing a new 'appointment.leave' model, which will handle the leave configurations for users and resources for specific appointment types using a method called '_get_appointment_leave_intervals'. As a leave can be set across multiple appointment types, the question of the timezone has been raised. The first idea was to consider the leave in the appointments timezone directly. Example: "From 2-3PM, in the Dental Care timezone, and from 2-3PM in the Tennis Court timezone" However, when creating a leave, the dates are converted from the browser timezone to UTC, meaning that from python it's impossible to remember the initial timezone after save. A timezone field was then considered, but another issue appeared: If the browser tz is different from the one picked in such a field, the dates would still be stored in UTC, shifted from values displayed in the form in the browser tz. A conversion into the picked tz would then not make any sense, as it would be a double shifting with no relevant feedback. As we are setting absolute datetimes, we prefer using the default behavior of the framework instead. For instance, let us consider a user with browser tz Europe/Brussels (summer time, utc+2): If they set a leave on July 8th from 14.00 to 15.00 in the form, then July 8th 12.00-13.00 will be stored (as in UTC). If an appointment with this leave is in utc+4, then their 16.00-18.00 slots will be unavailable. This matches previous datetime selection behavior when creating resource leaves, and also how slots datetimes are selected in flexible appointments. Adding an alert info in the appointment.leave form view to inform users when some of the selected appointment types have a different timezone than the current one used for leave creation. Task-5914412
This update enhances the display of commission achievements by correctly identifying the user associated with each document, particularly within dynamic plans. It also addresses several underlying issues related to target calculations, traceability of adjustments, and data type casting to prevent errors, ultimately improving the accuracy and reliability of commission reporting.
Original PR description
In dynamic plans, achievements can be computed based on other user's documents (invoice, SO etc). This commit ensure that we display the user assigned to the document. task-6253512
This update enhances the visibility of employee and manager feedback within the appraisal process. Changes were made to the underlying logic for hiding feedback, ensuring consistency and a better user experience. This improves the overall efficiency of the appraisal workflow.
Original PR description
In order to maintain the same logic while dealing with the appraisal in terms of hiding employee's and manager's feedback, some publishing conditions have been reworked. Task: 6304238
This update adds a new right-click option to dynamic lists within the Odoo Enterprise application. Users can now sort lists by clicking on the column headers, improving data organization and usability. This enhancement streamlines workflows for managing data within key modules.
Original PR description
Task: 6233381
Resolved issues and error corrections
This update expands the functionality of the sign creation process by enabling drag-and-drop support for all pointer types – including touch and pen – on Odoo Enterprise. This allows users to more easily create, move, and interact with sign elements, improving usability across different devices and workflows.
Original PR description
Dragging sign elements was previously limited to mouse input. This fix ensures full support for all pointer types, including touch and pen, allowing users to drag new sign items, reposition existing ones, and interact with the interface seamlessly. task-5001223
This update ensures that all conversation history and attachments are correctly transferred when converting between Helpdesk tickets and Project tasks. Previously, this information was lost during the conversion process, which is now resolved to provide a more complete and accurate record of project communications and files. This enhances collaboration and data integrity.
Original PR description
Before this commit, attachments and chatter messages were not moved to the new record when converting a Helpdesk ticket to a Project task or a task back to a ticket. This commit ensures that: - The chatter history is transferred to the newly created record. - All attachments linked to the original record are moved to the new one. task-4796664
This update fixes a problem where the Timesheet Assistant was suggesting activities that were already tracked. Now, explicit timer sessions act as 'clipping masks,' ensuring tracked time takes priority. Additionally, the system now automatically updates its data to prevent issues when timesheets are deleted, improving overall accuracy.
Original PR description
The Assistant previously suggested activities for periods already covered by the physical timer. To fix this, explicit timer sessions now act as invisible clipping masks that prioritize tracked time over suggestions. This was implemented fully client-side because live timer interactions are inherently managed there. These local blockouts are merged into the timeline first to naturally clip overlapping events, but are hidden from the UI to prevent redundant cards. Finally, to prevent orphaned blockouts when timesheets are deleted, the cache self-heals by validating its IDs against the database on load instead. Task: 6216903
This update fixes an issue where documents added through the 'Add from Documents' feature didn't display correctly in emails. It now aligns with the standard email attachment flow, eliminating incorrect spacing and ensuring previews are shown, leading to a better user experience when sending documents via email.
Original PR description
**Purpose of this PR:** Before this commit, documents added via "Add from Documents" did not integrate properly with the mail composer: previews were not shown, and when a document was added as a link with an empty body, line breaks were still applied and introduced extra spacing above the attachment. This commit aligns added documents with the regular mail attachment flow so they render correctly in the composer, and avoids inserting unnecessary spacing when no text content is present. Related PR: https://github.com/odoo/odoo/pull/256866 task-5947683
This update ensures that employees are only paid for the actual hours they worked by correctly deducting undertime from their payslips. Previously, the system didn't automatically apply these deductions. The update also removed outdated test cases related to old company-level settings.
Original PR description
Previously, when an employee worked fewer hours than expected, the missing hours (undertime) were correctly tracked but the salary deduction was not applied on the payslip. After this improvement: - Undertime hours are now correctly deducted from the payslip so the employee is only paid for the hours they actually worked. - Removed test cases that were testing old company-level tolerance settings which have been removed. task-5892244
This update fixes a reporting issue where tax information wasn't correctly captured for invoices using group taxes in the Philippines. The change ensures that all child tax tags are included in generic reports, accurately reflecting tax details for SC/PWD exempt components and other tax categories.
Original PR description
When using group taxes, the base invoice lines only store the parent tax in the `account_move_line_account_tax_rel` table. Because of this, if a child tax within the group contains a specific tax report tag (e.g., tag 33A on the SC/PWD exempt component introduced in the base localization), the generic report query would previously fail to pick up those base lines. This commit updates the SQL join conditions in `l10n_ph_generic_report.py` to also match `account_tax.id` against the child taxes of the linked parent tax using the `account_tax_filiation_rel` table. This ensures that base lines are correctly reported under the tags of their respective child taxes. Task-6032306 See: odoo/odoo#269250
This update fixes a problem where users couldn't access payslips related to departing employees. The changes ensure that only the departing employee's payslips are displayed, preventing errors and improving the user experience. A technical update was also made to ensure compatibility with newer Odoo versions.
Original PR description
Bug 1: In the departure tab of the Employee, you can't open the payslip list Fix: Added a check to get the correct departure id depending on the model we are in Bug 2: You can select payslips for…
Bug 1: In the departure tab of the Employee, you can't open the payslip list Fix: Added a check to get the correct departure id depending on the model we are in Bug 2: You can select payslips for other employees than the departing employee and the payslips list is not affected Fix: - made fields `l10n_be_payslip_n_ids` and `l10n_be_payslip_n1_ids` stored and added a domain on them to only show the payslips of the departing employee - when a payslip is validated for the departing employee after creating the departure, it's added to the corresponding field Bug 3: You get an error because you can't read `currency_id` when opening n payslips (happens when the monetary fields are shown in the list) Fix: moved the `currency_id` to be inside the list instead of the parent form Note: the relation names for `l10n_be_payslip_n_ids` and `l10n_be_payslip_n1_ids` are changed to avoid upgrade error `m2m relations have respawn` as they existed before 19.2 in the removed `hr.departure.wizard` model. task-id: 6265648
This update resolves an issue where the appointment calendar displayed 'no available slots' for future months when appointment scheduling lead times were long. The fix accounts for lead times to ensure the calendar accurately reflects available appointments, improving the user experience for booking.
Original PR description
The website appointment calendar fills availabilities one month at a time and the update_available_slots route maps the calendar month index to an absolute month from datetime.now(). This only…
The website appointment calendar fills availabilities one month at a time and the update_available_slots route maps the calendar month index to an absolute month from datetime.now(). This only matches the displayed months when the first one is the current month. When the first bookable slot is later, a punctual appointment starting in a future month or any appointment whose "at least X hours before start time" lead time pushes the first slot past the current month, navigating forward requests the wrong month and the reached month renders empty. In update_available_slots, take the lead time into account when computing the reference month so it lands on the first displayed month: the start datetime for a punctual appointment starting in the future, otherwise now plus the minimum schedule hours. The navigated month index is then added to that reference. This extends https://github.com/odoo/enterprise/commit/f0e5b14a823cf97218f4094d287a328e2744fd73 which only handled the future start datetime. Steps to reproduce: 1. Open the Appointments app 2. Open an appointment type, set Schedule to Weekly and Allow Bookings to On specific dates with a range ending a few months out 3. Set the "at least N hours before start time" field to 360 4. Save and click the Preview button in the header 5. Pick a resource or staff member to reach the calendar 6. Click the right arrow to navigate to the next month => the next month shows "Sorry, we have no more slots available for this month" opw-6206293 Forward-Port-Of: odoo/enterprise#120715
This update resolves an issue where clickable links within tax return anomaly checks were broken, preventing users from accessing detailed reports and resolving errors. The fix restores the functionality of these cards, allowing users to easily investigate and address tax return discrepancies. This ensures accurate reporting and efficient issue resolution.
Original PR description
Steps to reproduce: - Open tax returns menu items and set opening date - Try to click on an anomaly check -> It should open the corresponding action/view to see the failing records or report to solve the check, but the card is not clickable anymore and the cursor isn't displayed as it should.
This update ensures that certain Belgian salary rules are only applied to employees with variable salaries. Previously, these rules were incorrectly applied even when no variable salary was configured. The change verifies the contract's 'commission_on_target' field, preventing the rules from being applied in cases where a variable salary isn't present, improving payroll accuracy.
Original PR description
The Belgian salary rules with codes 'COM_LOSS_PH' and 'COM_LOSS_SICK' should only apply to employees who actually receive commissions.
Update the python condition ('condition_python') on both rules to verify that the contract's structure version ('version_id') contains a non-zero value for the 'commission_on_target' field. This ensures these rules are skipped when no variable salary is configured.
Task: 6300080Code cleanup and technical improvements
This update streamlines how partner identifiers are managed within Odoo, consolidating them into a single JSON field. Removing the outdated 'company_registry' field and standardizing routing identifiers improves compatibility with e-invoicing standards like UBL and Peppol, simplifying reporting and integration. This change enhances data accuracy and reduces complexity for users.
Original PR description
We previously replaced the scattered, country-specific partner identifier fields with one JSON field `additional_identifiers`. This commits continues to clean up after that change, mainly: - Move the…
We previously replaced the scattered, country-specific partner identifier fields with one JSON field `additional_identifiers`. This commits continues to clean up after that change, mainly: - Move the additional_identifiers JSON field into base: some modules (l10n_xx_hr_payroll) don't depend on `account` yet still have similar contact's identifiers. - Drop the company_registry field as now, everything should be more specific, and stored in the JSON field. Smaller changes: - add base helpers selecting a partner's preferred legal-entity, tax and routing identifier, reused by UBL/CII EDI, SAF-T and Peppol/PDP - rename peppol_eas/peppol_endpoint to routing_scheme/routing_endpoint (+ computed routing_identifier) so any e-invoicing network can route using this fields => less confusing. - Some countries have non-stored compute/inverse for convient access (l10n_fr_siret/siren, SG UEN, NO Brønnøysund, ...), - adapt UBL/CII exports, SAF-T reports and invoice reports after the removal of the company_registry. - cleanup of the scheme/endpoint validation so that's it's more coherent. There was 3 different validation before, of only a subset of schemes. task-6140750
7 changes
New functionality added to Odoo
This update adds support for several popular food delivery services – including Talabna, Mandoob, and DiDi Food – expanding our restaurant partner options. These integrations allow Odoo to connect with a wider range of delivery providers, improving convenience for both our restaurants and customers. This is a new feature addition.
Original PR description
In this commit: - We are introducing new delivery providers like Talabna, Mandoob, Snoonu, DiDi Food and Zyada for different countries and backporting Radyes, ToYou, The Chefz, InstaShop and Smiles. Task-6263289,6263272,6263203,6263165,6310690
Resolved issues and error corrections
This update fixes an issue where a specific invoice origin code was incorrectly triggering a cancellation request to Mexican tax authorities (CFDI). The change ensures that only invoices with origin code '04' (for substitution) are used to cancel down payments, preventing unintended cancellations of the initial payment.
Original PR description
**Steps to reproduce:** - Install Sales, Accounting and l10n_mx_edi - Switch to a Mexican company (e.g. ZAPATERIA URTADO ÑERI) - Create a SO: * Customer: [a Mexican customer] (e.g. INMOBILIARIA CVA) * Payment Way: Efectivo * Payment Policy: PUE * Product: [any product with a UNSPSC Category] * Taxes: [any] (e.g. 16%) - Confirm the SO - Create a down payment (e.g. 60%) - Confirm the down payment - Send it to CFDI - Copy the fiscal folio - Go back to SO - Create the final invoice - Set the copied fiscal folio prepend with "07|" as CFDI Origin - Confirm the invoice - Send to CFDI **Issue:** A cancellation request is sent to CFDI for the down payment. "07" origin code is used to link the invoice to a down payment. It should not cancel the down payment. It should only be done with "04" origin code used for substitution of a previous invoice. opw-6266678
This update significantly speeds up appointment scheduling by optimizing how available resources are checked. The system now processes multiple resources simultaneously, reducing the time it takes to determine availability, especially for businesses with many tables or resources. This results in a faster and more responsive scheduling experience.
Original PR description
In the current code, for each slot, and for each "available" resource, we check if the resource is available on the slot, based on availability values. Then, we check the remaining capacity of that…
In the current code, for each slot, and for each "available" resource, we check if the resource is available on the slot, based on availability values. Then, we check the remaining capacity of that resource. Also, linked resources information is added when computing the original resource remaining capacity. If many linked resources exist, this will be done several times and is not useful. This commit makes that loop disappear. We now check all resources at once in terms of availability, and linked resources that could be selected (in the appointment resources, in the slot resources (if any restricted resource)) at the same time. Then, the total capacity is the sum of the resource remaining capacity and the ones of available linked resources. Therefore, _slot_availability_is_resource_available is renamed to _slot_available_resources, as it now takes more than one resource and returns all resources among 'resources' that are valid on the slot, based on the availability_values, slot restrictions and booking lines. A noticeable difference is mainly seen when using many resources (and linked resources). For instance, a restaurant with a lot of small tables will have their slot availability check much shorter. BENCHMARK, LOCAL (time only, as number of requests does not change) Only appointment installed For a restaurant with - 10 tables of 2 - 5 tables of 2 linked, 2 times - 10 tables of 4 - 2 table of 2 - time then auto assign On loading /appointment/id: ~ 3.1s -> ~ 1.6s On selecting any number of people (1 to 10): [2s, 2.5s] -> [0.6s, 0.8s] Task-4144524
This update resolves an issue where creating RFQ approval requests could trigger access errors when using supplier pricelists with inaccessible vendors. The fix ensures that the system correctly handles vendor access restrictions, preventing errors and improving the approval process for users with limited vendor visibility. This improves the reliability of the approval workflow.
Original PR description
**Issue** Having supplier pricelists with at least one vendor inaccessible to the current user can trigger an access error when creating an RFQ approval request. **Steps to reproduce** - Have two…
**Issue** Having supplier pricelists with at least one vendor inaccessible to the current user can trigger an access error when creating an RFQ approval request. **Steps to reproduce** - Have two companies A and B and two users u1 and u2 - user u2 only have access to company A - With user u1: - Create two vendors v1 and v2 without any company assigned - Create vendor pricelists for a product for each vendor and assign the company A to the pricelist - Add the company B for the vendor v2 - With user u2: - Open approval application - Try to create an approval for an RFQ for that product (the vendor v1 will be automatically selected) - Save it -> An access error is thrown **Cause** Saving the approval request computes `has_no_seller`, which calls `_select_seller`: https://github.com/odoo/enterprise/blob/03c737685ff6dfc95a8bc72491646774fc426b1f/approvals_purchase/views/approval_product_line_views.xml#L9 https://github.com/odoo/enterprise/blob/03c737685ff6dfc95a8bc72491646774fc426b1f/approvals_purchase/models/approval_product_line.py#L32 https://github.com/odoo/enterprise/blob/03c737685ff6dfc95a8bc72491646774fc426b1f/approvals_purchase/models/approval_product_line.py#L62-L70 Which filtered the right seller https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_product.py#L759 By preparing the sellers: https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_product.py#L721 https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_product.py#L712 Please note that `self.seller_ids` contains both sellers (even v2) By filtering the suppliers: https://github.com/odoo/odoo/blob/c37e76850d3ff790b76493bd1003d80e170bd4bf/addons/product/models/product_supplierinfo.py#L104-L105 But at that point, one of the supplier in `self`, can be accessed, thus an access error is thrown while trying to access its associated `partner_id`. opw-6203910 Forward-Port-Of: odoo/enterprise#120251
This update significantly reduces memory usage and speeds up the loading of large General Ledgers, particularly when displaying journal lines. The change optimizes how Odoo fetches display names, preventing unnecessary data loading and improving overall system performance. This results in a smoother user experience when working with extensive financial reports.
Original PR description
### Issue Loading a large General Ledger (e.g., during an "Unfold All" action) and retrieving display names for thousands of journal lines (`account.move.line`) causes excessive memory and…
### Issue Loading a large General Ledger (e.g., during an "Unfold All" action) and retrieving display names for thousands of journal lines (`account.move.line`) causes excessive memory and performance overhead. Profiling with `memray` showed that one of the main memory hotspots was located in `custom_label_builder`. **Previous behavior:** Accessing `record.display_name` in a loop without an explicit `fetch()` call triggered lazy computation of the field via `_compute_display_name()`. When the compute method accessed stored dependency fields (such as `name`, `ref`, `move_id`), each cache miss went through `_fetch_field()`, which greedily loaded **all fields sharing the same prefetch group** on the model, far beyond the dependencies of `display_name` alone. This caused the ORM cache to be filled with many unnecessary stored fields for every record in the prefetch set. --- ### Dataset Volume The performance metrics were captured using a dataset consisting of: * **455,694** Journal Items (`account.move.line`) * **19,947** Journal Entries (`account.move`) --- ### Solution Add a single `fetch(['display_name'])` call on the browsed recordset. By calling `fetch(['display_name'])` upfront, the ORM goes through `_determine_fields_to_fetch(['display_name'])`, which walks only the declared `field_depends` of `display_name` and fetches **only those specific stored fields**. nothing more. --- ### Impact & Results | Metric | Before Optimization | After Optimization | Change / Note | | :--- | :--- | :--- | :--- | | **Peak Memory** | ~856 MB | ~223 MB | ~74% reduction | | **Execution Time** | 2.48s | 2.13s | About the same time with multiple tries | OPW-6275158
This update resolves a crash that occurred when users manually corrected bank statement lines within the Odoo Enterprise system. The issue stemmed from a missing context setting, preventing the correct journal from being assigned, leading to errors and data inconsistencies. This fix ensures accurate bank statement processing.
Original PR description
When the manual correction tool was used to fill in the lines, we weren't passing the active context when creating the new records. In the case of bank statements, it could be an issue as the `default_journal_id` key is expected to be present to set the correct journal on the newly created bank statement line. Without this key in the context, it would default to the first journal with a valid type (see function `_search_default_journal`). If the journal found this way didn't match the current journal, a crash would occur when modifying the newly created lines. opw-[6294117](https://www.odoo.com/odoo/unassigned-tasks/6294117)
This update corrects a problem that occurred when the Fiskaly API key was updated. Previously, changes in the API key would cause order signing to fail due to incorrect SCU and cash register information. The fix ensures these details are properly reset and recreated for the new Fiskaly organization, allowing orders to be signed correctly.
Original PR description
When the Fiskaly API key/secret is changed, the company is bound to a new Fiskaly organization (owner). The SCU and cash registers stored on the company and POS configs were created under the previous owner and no longer exist for the new one, so signing orders fails with E_CASH_REGISTER_NOT_FOUND. Clear l10n_at_pos_company_scuid and each config's l10n_at_cash_regid together with the access token so they are recreated under the new organization on the next authentication. opw-6297695
7 changes
Resolved issues and error corrections
This update addresses a bug preventing company-to-company KSeF invoice retrieval within the same Odoo database. The fix allows invoices to be sent between companies with the same KSeF number and limits the date range for fetching bills to a maximum of three months. This ensures accurate KSeF compliance and proper invoice retrieval.
Original PR description
Issues: 1. For a db with company_1 and company_2, when company_1 sends an invoice to company_2 via KSeF (out_invoice with a ksef number), company_2 in the same database can't fetch the corresponding bill because there is a move with the same KSeF number. 2. The date difference between `from` and `to` in the `dateRange` must not exceed 3 months as explained in the documentation https://api.ksef.mf.gov.pl/docs/v2/index.html#tag/Pobieranie-faktur/paths/~1invoices~1query~1metadata/post Fixes: 1. Change the unique constraint and the domain to allow same KSeF number per different companies. 2. Minimize the `to` parameter with `from` + 2 months. task-6260645 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an issue where the partner information on purchase bills was incorrectly overridden by the PO matching process during UBL XML imports. The fix establishes the purchase order as the definitive source for partner information on bills, ensuring accurate data and improved import reliability. This prevents data discrepancies and streamlines the billing process.
Original PR description
Fix a bug where the partner of a bill is overriden by the PO matching The chosen logic here is to say that in the context of a purchase, the purchase order is the single source of truth to set the partner on a bill Steps to reproduce: - Create a partner with is_company = True - Create a contact type 'invoice' for this partner - Create a purchase order for the first partner - Import an XML (UBL) that matches this PO - You can see in the import logs that the partner was correctly found first, and then the PO matching override it to set the contact as the partner task-6289358
This update fixes an issue where payments to CFDI were being sent multiple times for the same invoice, leading to inaccurate reporting of payment totals. The change ensures the 'Update Payments' button only appears after the invoice payment is fully reconciled, preventing this duplication and maintaining accurate financial records. This improves data integrity and reporting reliability.
Original PR description
Issue: Sending payments to CFDI before its full amount is reconciled allow sending the same invoice payment several times to CFDI. So some invoices are declared as paid several times and the total…
Issue: Sending payments to CFDI before its full amount is reconciled allow sending the same invoice payment several times to CFDI. So some invoices are declared as paid several times and the total amount of the payment is seen as exceeding the real total. This fix is a back port of odoo/enterprise#108355 and aim to prevent some things the backend allow, but the front end prevents. Following steps could be used to reproduce from 18.3. Steps to reproduce: - In a Mexican company - Create an invoice A of $40 to Inmobiliaria CVA - Confirm and send to CFDI - Go to bank, create a new Bank transaction of $80 - reconcile with Invoice A - Go to invoice A => click on button "Update payments" (it doesn't appear before version 18.3) - Then sheet CFDI and Download There is the first XML sent to CFDI with payment for invoice A - Create an invoice B of $40 to Inmobiliaria CVA - Confirm and send to CFDI - reconcile the transaction with Invoice B - Go to invoice B - Click on button "Update payments" - Then sheet CFDI and Download There is the second XML sent to CFDI with payment for invoices A and B Invoice A payment was sent twice to CFDI Expected behavior: - The "Update payment" button should appear only once the invoice payment is fully reconciled. Current behavior: - The update payment button appear once the invoice is reconciled with a payment. opw-5432421
This update resolves an issue where invoices with reverse charge tax were not being correctly formatted in the XML export for ksef. Specifically, the XML fields related to reverse charge were inaccurate. This ensures invoices with reverse charge are properly transmitted and processed, preventing potential tax reporting errors.
Original PR description
**STEP TO REPRODUCE** 1. Create an invoice with a tax with reverse charge (0% EU G for example). 2. Send the invoice to ksef. 3. Open the generated xml, and notice field P_18 is 2 while it should be 1 (because there is reverse charge). Also, there is not P13_10 indicated the total value of sale to which the reverse charge applies. opw-6041836
The barcode scanner check-in process was previously inaccurate due to relying on a less precise location database. This update now uses the browser's geolocation to determine location, significantly improving accuracy and reducing location discrepancies, especially in kiosk mode.
Original PR description
**Issue** Check-in and check-out performed in kiosk mode via the barcode scanner were less accurate than those made via the manual selection. The reported inacurracy between the actual and real locations was several kilometers. **Cause** `attendance_barcode_scanned` was called without a location coming from the browser's geolocation API. In that case, the location was determined by the geoip database https://github.com/odoo/odoo/blob/51f59a293de1e86f66f30257f8fc0c419463d18c/addons/hr_attendance/controllers/main.py#L69-L70 which is generally not as accurate as the location provided by the browser. opw-5889102
This update prevents the upgrade script from altering account flags (specifically the 'reconcilable' flag) when accounts have partially reconciled transactions. This resolves a potential error that would have caused the upgrade process to fail. It ensures data integrity during account updates.
Original PR description
### Context: Clients can have some existing accounts with `reconcilable` flag set as True. Some of these accounts also have partially reconcilated transactions. In Odoo 19.0, it is not authorized to…
### Context: Clients can have some existing accounts with `reconcilable` flag set as True. Some of these accounts also have partially reconcilated transactions. In Odoo 19.0, it is not authorized to toggle the `reconcilable` flag from True to False on accounts that contain partially reconcilated transactions. When the migration script `l10n_pl/migrations/2.1/end-migrate.py` is executed and try to update the CoA by adding/updating accounts, using the accounts in the file `l10n_pl/data/template/account.account-pl.csv`. This CSV file contains a reconcilable flag per account. ### Problem: Before this modification, the upgrade script was trying to update the CoA using `_load_data`, which try to overwrite the reconcilation flag of accounts in the client DB. A traceback occurs during the upgrade if an account's `reconcilable` flag is toggled to False while it still contains partially reconciled transactions. ### Solution: I have sanitized the dict `data` using the _pre_reload_data method. ### Notes: `_pre_reload_data` method sanitizes the dict `data` by avoiding the creation of duplicated accounts, the creation of duplicated fields for a given record, the toggling of the `reconcilable` flag, etcs. Back port of: https://github.com/odoo/odoo/commit/23ed5448a13255e68ff4d3ca87884c2ca2f97ba3 Reason: the issue was originally introduced in `18.0` (see https://github.com/odoo/odoo/commit/d5109a45d610916530b4b74cf3e2fa440ee7ed63) Related to: https://github.com/odoo/upgrade/pull/10266#discussion_r3402549250 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves a crash in the Point of Sale (POS) system when processing payments with the Adyen terminal. Adyen sends multiple notifications for the same payment, leading to errors when attempting to retrieve payment information. The fix ensures that payment data is fetched only once at the beginning of the processing, preventing the crash and improving payment reliability.
Original PR description
The following error is raised in the POS when paying with an Adyen terminal: ``` TypeError: Cannot read properties of undefined (reading 'uuid') at Proxy.handleAdyenStatusResponse ``` Adyen delivers…
The following error is raised in the POS when paying with an Adyen terminal: ``` TypeError: Cannot read properties of undefined (reading 'uuid') at Proxy.handleAdyenStatusResponse ``` Adyen delivers webhook notifications at-least-once, so the ADYEN_LATEST_RESPONSE event can fire several times for a single payment, running handleAdyenStatusResponse concurrently. After the await on get_latest_adyen_status, a previous (duplicate) notification may already have resolved the payment line, so getPendingPaymentLine no longer returns it and the subsequent line.uuid dereference crashes. opw-6237987 patched the same root cause on a single line by adding an optional chaining operator in isPaymentSuccessful, which only moved the crash to the next dereference. Fetch the pending line once at the start of handleAdyenStatusResponse and bail out when it is gone, so every dereference below is safe. The same guard is added to the remaining branches of _adyen_handle_response for consistency with the existing Reject branch. opw-6237987 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
6 changes
Enhancements to existing features
This update enhances the error messages displayed when leave validity conflicts occur, particularly when creating public holidays. This change improves the user experience for both customers and our support team by providing clearer troubleshooting guidance and reducing the need for manual debugging.
Original PR description
The current message is pretty useless as of now when a lot of leaves are being written to, notably when creating a public holiday, which sets the state of all the leaves overlapping the public holiday's day to be reevaluated, and if an error occurs, you have to go through every employee's leave allocation and leaves taken to hopefully find one who might have to many days taken/not enough allocated. This extra information will be a huge QOL improvement, for the customer who will be able to troubleshoot his issue himself more easily, but also for our support team as the only way to debug those kind of issues now is to put a breakpoint there and see what employee has an issue. opw-4411999
Resolved issues and error corrections
This update resolves an issue where payslips weren't correctly generated for employees registered within branch companies of a larger organization. The fix ensures that all employees within the company hierarchy, including those in branch offices, are accurately included in payslip calculations. This improves payroll accuracy and reporting.
Original PR description
Bug: employees registered on branch companies don't appear in the
employee_id field when creating a payslip from the parent company.
Reason: the domain used ('company_id', '=', company_id) which only
matches the exact company, not its children.
Solution: replaced '=' with 'child_of' to include all descendant
companies in the hierarchy.
task - 6299634This update resolves an issue where payslips weren't generated correctly for employees registered within branch companies of a larger organization. The fix ensures that all employees within the company hierarchy are included when creating payslips, improving payroll accuracy and reporting. This change impacts the HR Payroll module.
Original PR description
Bug: employees registered on branch companies don't appear in the
employee_id field when creating a payslip from the parent company.
Reason: the domain used ('company_id', '=', company_id) which only
matches the exact company, not its children.
Solution: replaced '=' with 'child_of' to include all descendant
companies in the hierarchy.
task - 6299634This update fixes an issue where work order durations were inaccurately calculated due to overlapping time entries. By filtering and merging productive and performance time, the system now provides a more precise duration, aligning with cost valuation needs. Additionally, a fix ensures accurate timestamp handling to prevent duration discrepancies.
Original PR description
[[FIX] mrp: calculate real duration excluding non-productive intervals](https://github.com/odoo/odoo/pull/248381/changes/fac6b2540a32a015f56085c2c27ba4281eb659cf) and deduplicating overlaps * Current…
[[FIX] mrp: calculate real duration excluding non-productive intervals](https://github.com/odoo/odoo/pull/248381/changes/fac6b2540a32a015f56085c2c27ba4281eb659cf) and deduplicating overlaps * Current Situation: Currently real duration is total duration of each time tracking which is not consistent with the time that use to calculate the cost for valuation , see https://github.com/odoo/odoo/pull/205154 .The real duration of a work order was incorrectly summing all time tracking entries regardless of their loss type, and using simple addition which double-counts overlapping intervals. * Solution: - Filter time entries to only 'productive' and 'performance' loss types, excluding 'availability' and 'quality' as they represent downtime/blocking time, not actual work duration. - Pool all productive and performance entries into a single Intervals call so that overlaps across both types are merged in one pass. Note: the enterprise17 implementation groups time entries by loss_type into separate buckets before calling Intervals, which means overlaps between 'productive' and 'performance' entries are not merged and get double-counted. Pooling both types together before the Intervals call avoids this. * This also fix: - Fix _set_duration to ensure newly created time entries start after the latest existing entry's end date. Without this, calling _set_duration twice in quick succession (e.g. in tests) produces two entries with overlapping timestamps, which Intervals correctly merges into one, causing the computed duration to be half the expected value. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an issue impacting the processing of invoices with multiple related documents, particularly in cancellation scenarios. By switching to a specialized index, the system now handles a larger volume of data efficiently, preventing performance bottlenecks. This ensures smoother invoice processing and avoids potential delays.
Original PR description
The field `l10n_mx_edi_cfdi_origin` can contain a large number of associated UUIDs, especially in complex cancellation scenarios. The default B-tree index fails when this field exceeds 2704 bytes, which occurs after approximately 20 UUIDs. By switching to a trigram index, we avoid the entry size limit of PostgreSQL's B-tree nodes. This ensures that invoices with many related documents can be processed while maintaining efficient search performance for partial matches on this field. **Video before the fix:** https://youtu.be/24u0HbxwIH8 **Video after the fix:** https://youtu.be/sUelv1HZMvI
This update resolves an issue where rapid changes to product quantities in the product catalog could lead to incorrect final quantities on Sale Order Lines. The fix ensures that quantity updates are processed sequentially, preventing data inconsistencies. This improves the reliability of sales order calculations.
Original PR description
Fix a concurrency race condition in the product catalog where rapid quantity updates could result in incorrect final quantities on Sale Order Lines (SOL). Steps to produce: --- - We need a DB with…
Fix a concurrency race condition in the product catalog where rapid quantity updates could result in incorrect final quantities on Sale Order Lines (SOL). Steps to produce: --- - We need a DB with too many products. Also it might not be easy to reproduce the issue locally. Try runbot. - Open a Sale Order (SO) and open the Product Catalog. - Rapidly change or paste quantities (e.g., changing from 1 to 100) across multiple records very fast. - Return to the SO. Some lines intermittently retain an intermediate quantity (e.g., qty = 1) instead of the final entered value. Cause: --- - This is a concurrency issue. In the faulty cases, the `update_order_line_info` setting quantity to 1 takes a few seconds to resolve, while the update setting quantity to 100 resolves faster (around 200ms). This cause the SOL final quantity set to 1. Fix: --- - We can chain RPC calls to ensure that each request is completed before starting the next one. Backport of ef9554ad95d5e39ab7b550db0d39454373f99aed opw-6282877 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr