Thursday, June 18, 2026
23 changes · saas-19.2
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
This update resolves issues preventing users from accessing payslip lists within the employee departure workflow. Specifically, the code was adjusted to correctly identify departure IDs and prevent unintended modifications to payslip selections. Moving currency data to the list view also resolves a related error.
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 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` readonly so they can't be modified in the UI without being saved 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 task-id: 6265648
This update enhances the Timesheet Assistant by streamlining suggestions, improving usability with shortcuts and hotkeys, and correcting a bug where leave time was incorrectly included in total hours. It also removes irrelevant task suggestions, ensuring a more accurate and efficient timesheet experience.
Original PR description
## Expected Behavior After Commit - Remove the green highlight when selecting a suggestion. - Add shortcuts for timesheet creation buttons. - Allow calendar events to be considered side activities - Exclude leave time from total hours, as leave time is already counted in the timesheet. - Do not show to‑do tasks (tasks without a project) in suggestions. - Restore previous suggestions for to‑do tasks when they later become linked to a project. - Add a default name for suggestions that do not have one. - Add hotkeys to Timesheet Assistant task-[6191451](https://www.odoo.com/odoo/project/4105/tasks/6191451)
This update corrects a bug in the calculation of DPV (disabled period verification) for employees with extended absences. Specifically, it ensures accurate tracking of sick leave assimilation periods, particularly when transitioning between long and partial incapacities. This improves the accuracy of payroll calculations and reporting.
This update fixes an issue where the system incorrectly canceled down payments when sending CFDI cancellation requests. The change ensures that only invoices with a '04' origin type are used for CFDI cancellations, aligning with Mexican regulations and preventing unintended down payment cancellations. This improves data accuracy 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 the l10n_sa_edi E-invoicing module would fail to install correctly if certain taxes were missing from the system configuration. The fix filters out missing taxes during installation, ensuring a smoother and more reliable module setup process.
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 Forward-Port-Of: odoo/odoo#270336
This update resolves an issue where creating approval requests could trigger access errors when using supplier pricelists with inaccessible vendors. The fix ensures that the system correctly handles situations where a user lacks access to certain suppliers, preventing errors during the approval process. 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/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 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/enterprise#120251
This update fixes inaccurate COGS calculations for kit products in Odoo. The change ensures correct COGS are applied when creating sales orders for kits, addressing issues with multiple steps, multiple kit components, and FIFO inventory valuation. The fix unskips tests and improves the accuracy of sales order pricing.
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 fixes an issue where the appointment calendar incorrectly displayed 'no slots available' when navigating to future months. The change accounts for appointment lead times, ensuring the calendar accurately reflects available slots regardless of appointment start times. 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