Daily updates from Odoo
Monday, July 6, 2026
27 changes · saas-18.3
Resolved issues and error corrections
Sales commission plans now prevent adding a salesperson whose start date falls after the plan's end date. This helps avoid invalid commission setup and reduces downstream errors in commission tracking.
Original PR description
Version: 18.0 Steps to reproduce: - open sale commission plans and create a new plan with an effective period - go to the salesperson tab and add a salesperson - set the salesperson from date after the plan end date issue: salesperson period start date was accepted even if it was set after the plan end date fix: added validation to raise an error when the salesperson start date falls outside the plan effective period task id: 6241188 Forward-Port-Of: odoo/enterprise#118289
Task progress bars in the Gantt view now show the correct completion level based on logged timesheets and allocated hours. This prevents under-reporting progress visually, helping teams quickly understand task status in planning views.
Original PR description
Steps to reproduce: ------------------------------------------- 1. Install the Timesheet module with demo data 2. Go to any FSM task > set allocated hours to 20h 3. Fill the timesheet for the same…
Steps to reproduce: ------------------------------------------- 1. Install the Timesheet module with demo data 2. Go to any FSM task > set allocated hours to 20h 3. Fill the timesheet for the same task for 10h 4. Navigate to FSM > My Tasks > Gantt view Observation: ------------------------------------------- Look at the task on the Gantt chart. The shading is barely visible because it covers only 0.5% of the bar, not 50% Issue: ------------------------------------------- In the commit https://github.com/odoo/odoo/pull/137570/changes/4a93d9aee957dd3feb3db0cb69eb3b8f0f4a4683 The progress field computation was changed from storing percentage values (0-100) to storing decimal values (0-1). Specifically, the `_compute_progress_hours` method was modified. This change was made to standardize the progress field storage format, with the understanding that the UI layer would multiply by 100 when displaying the value. While most views (form, list, kanban, etc.) were updated to multiply the progress by 100 for display purposes, the Gantt view's pill progress bar was missed. Solution: ------------------------------------------- Overrides the `enrichPill` method to multiply the `_progress` value by 100 before it's passed to the template. This ensures the Gantt pill progress bars display correctly without modifying the core web_gantt module. Before --------------------------- <img width="268" height="368" alt="image" src="https://github.com/user-attachments/assets/6d35927f-bd3f-47fc-9101-e2e188d419b8" /> After: -------------------------- <img width="250" height="371" alt="image" src="https://github.com/user-attachments/assets/fe7133e0-26d1-4c5f-b903-48826fda9488" /> opw-6038983 Forward-Port-Of: odoo/enterprise#111270
This fixes an error that could occur when updating quantities on confirmed Field Service sales orders while an incoming-message automation rule is active. The change keeps background message handling compatible with automation, so users can adjust catalog quantities without being blocked by a crash.
Original PR description
Steps to reproduce: ---------------------------------------- 1. Install `industry_fsm_sale` and `base_automation` modules 2. Create a product with: * Type: Service * Create on order: Task * Project:…
Steps to reproduce:
----------------------------------------
1. Install `industry_fsm_sale` and `base_automation` modules
2. Create a product with:
* Type: Service
* Create on order: Task
* Project: Field Service
3. Create an automation rule with:
* Model: Sales order
* Trigger: Incoming message
4. Create and confirm a sale order with this product
5. Add another product to the SO via the catalog view:
* Change the quantity to 2 or more
Observation:
----------------------------------------
Traceback occurs:
```
File '/home/odoo/src/odoo/addons/base_automation/models/base_automation.py', line 871, in _message_post
message_sudo = message.sudo().with_context(active_test=False)
AttributeError: 'bool' object has no attribute 'sudo'
```
Root Cause:
----------------------------------------
* Catalog qty change calls `set_fsm_quantity()` method
* Setting `fsm_quantity` triggers its inverse `_inverse_fsm_quantity()`, which writes the new qty to the SOL, but passes `fsm_no_message_post=True` in context to suppress chatter noise
https://github.com/odoo/enterprise/blob/ac5d670832a5e0db714c0bd056e1406b50bb4c17/industry_fsm_sale/models/product_product.py#L72-L83
* `sale.order.line.write()` detects a qty change on a confirmed order and calls `_update_line_quantity()`, which posts a message on the parent sale order
* FSM's `message_post` override sees the context flag and returns `False`
* When `base_automation` has an `on_message_received` rule on `sale.order`, it wraps `message_post` at registry load time. That wrapper calls `sudo()` on whatever `message_post` returns, Which was `False`
Solution:
----------------------------------------
Return `self.env['mail.message']` (empty recordset) instead of False, it's still falsy, but it's a proper ORM object that `sudo()` can be called on
opw-6276916
Forward-Port-Of: odoo/enterprise#119542This fix prevents an internal payment test from running in a setup where its assumptions do not apply. It helps keep automated validation reliable without changing customer-facing payment behavior.
Original PR description
`test_payment_state_after_invoice_edition_without_journal_entry` test fails when `accountant` module is not installed. The test is specific to a case where there is no journal entry linked to a payment. However, when `accountant` module is not installed, a journal entry is always linked to the payment. runbot-941263
This fixes DHL delivery validation when shipments are processed from a company other than the main one. Commercial invoice numbers are now generated correctly, preventing DHL rejection errors for eligible international deliveries.
Original PR description
Issue ----- When validating a delivery in a different company from the main one, the commercial invoice's number field is incorrect, which raises an error on DHL end.…
Issue ----- When validating a delivery in a different company from the main one, the commercial invoice's number field is incorrect, which raises an error on DHL end. `content/exportDeclaration/invoice/number: expected type: String, found: Boolean` Steps to reproduce ----- - Create a Belgian company - Setup DHL - DHL Product D - Express Worldwide - Dutiable Material enabled - Create an amrican customer - Deliver a product to the american customer > Validation Error Cause ----- The field is populated in https://github.com/odoo/enterprise/blob/cf3c2fce8a6b7b2d7547d44a0e4423f887986d52/delivery_dhl_rest/models/dhl_request.py#L204 The problem is that `next_by_code` uses the company found in the env, whereas the sequence's company is the main one, so it is not found when doing https://github.com/odoo/odoo/blob/e3b0ca11d99b2ef819cdad68b169112cd73668b6/odoo/addons/base/models/ir_sequence.py#L287 ----- Ticket: opw-6171886 Forward-Port-Of: odoo/enterprise#118379
The barcode app now better identifies the existing owner of consigned stock when scanning delivery items, including products without lot tracking. This prevents duplicate stock records and helps deliveries use the correct available inventory.
Original PR description
### Steps to reproduce: - In the settings enable: "Storage Locations" and "Consignment" - Create a storable product and put 1 unit in stock with a set owner - Go to the barcode app > Operations >…
### Steps to reproduce: - In the settings enable: "Storage Locations" and "Consignment" - Create a storable product and put 1 unit in stock with a set owner - Go to the barcode app > Operations > Delivery Orders > New - Scan your product and validate #### > The owner was not set on the stock move line so that a new quant was created and updated in stock rather than using the available unit. ### Cause of the issue: The mechanism of prefilling an owner or a package in the barcode app is currently gate-kept behind the existence of a lot name: https://github.com/odoo/enterprise/blob/0be4f71de3420fb9b72fd4e70d48c6cbbbc0ecb4/stock_barcode/static/src/models/barcode_model.js#L1382-L1407 However, the option also make sense for none tracked products. ### Note: Performing the flow form the backend and adding quantity will generate the move line by setting the owner if possible since the quantity of a move is set via the back end, move lines are generated by looking at the existing quant data's: https://github.com/odoo/odoo/blob/5d61c03b33c9a915684dd59656f8be7612956dd1/addons/stock/models/stock_move.py#L2364 https://github.com/odoo/odoo/blob/5d61c03b33c9a915684dd59656f8be7612956dd1/addons/stock/models/stock_move.py#L2328-L2330 Setting the same owner on the new move line as on the quant we are going to reserve: https://github.com/odoo/odoo/blob/5d61c03b33c9a915684dd59656f8be7612956dd1/addons/stock/models/stock_move.py#L2337 https://github.com/odoo/odoo/blob/5d61c03b33c9a915684dd59656f8be7612956dd1/addons/stock/models/stock_move.py#L1715 Additional subtelties appearing when prefilling for non tracked product: 1. Currently the available quantity is not taken into account to determine if the the value provided to the prefilled is actually relevant, in particular if there is a quant with an available quantity of 0, it will be used as a valid value to prefill and it will parasit the prefill that could be done by other quants. 2. The location source used to determine the quants taken into account is not set on the first scan since the scan is performed without any existing line: https://github.com/odoo/enterprise/blob/4f0d25f9fe4ca8ff1b0ecd7900899a2a246ba888/stock_barcode/static/src/models/barcode_model.js#L1387 > This was not problematic with respect to tracked product since the product needs to be scanned prior to the lot, hence there is always a current line when the the lot is scanned. opw-6050657 Forward-Port-Of: odoo/enterprise#121996 Forward-Port-Of: odoo/enterprise#115021
A test for duplicating field service subtasks was updated so it no longer depends on an internal ordering that can vary. This helps keep automated checks stable and reduces false failures during development and releases.
Original PR description
Steps to Reproduce --- 1. Install industry_fsm_report. 2. Run the test test_subtasks_worksheet_template_id_duplicate Issue --- The test fails because it relies on positional index assertions (child_ids[0] and child_ids[1]). Since child_ids is now returned with the ordering (id desc), the subtasks are processed in a different order during copy, causing the assertions to no longer match the expected records. Fix --- Sort both the original and duplicated subtask recordsets by name. task-5966684
Hong Kong payroll now calculates payment in lieu of notice based on the employee's actual contract start date instead of assuming a full prior 12 months. This improves payroll accuracy for employees with shorter service periods and adds test coverage for related edge cases.
Original PR description
Currently, the calculation of the payment in lieu of notice is assuming the employee worked a whole 12 months prior to it being paid. This is of course not always going the be case, and when it happens our calculation is often incorrect. We update the salary rule to calculate a more accurate total days (which is no longer based on a fixed 12-month period but takes into account the contract's start date). We also now calculate the number of months more accurately by taking, once again, the contract's start date into account. Also adding a few test cases to test a bit more some special case we didn't yet test correctly. task-6348903 Forward-Port-Of: odoo/enterprise#122580
This update fixes an error that occurred when clearing the date field in the WIP Accounting Entry wizard. Previously, the wizard would crash. Now, users can temporarily empty the date field while editing the wizard without causing an error, ensuring smoother workflow.
Original PR description
Issue Before This PR: When clearing the Date field in the WIP Accounting Entry wizard, an error was raised during the re-computation of dependent fields. This prevented from temporarily emptying the…
Issue Before This PR: When clearing the Date field in the WIP Accounting Entry wizard, an error was raised during the re-computation of dependent fields. This prevented from temporarily emptying the date field while editing the wizard. Steps to Reproduce: - Open the list view of Manufacturing Orders. - Open the Post WIP Accounting Entry wizard by either: - Selecting one or more Manufacturing Orders and choosing Actions ,click Post WIP Accounting Entry - Or, opening a Manufacturing Order form and selecting Post WIP Accounting Entry from the Actions & Reports menu. - Clear the Date field. - Observe that an error is raised. Cause of the Issue: The compute methods _compute_reversal_date() and _compute_line_ids() assumed that wizard.date was always set. When the Date field was cleared, its value became False, but the compute logic still attempted to compare or use the date, resulting in an error. With This PR: The compute methods now verify that wizard.date is set before performing date-dependent computations. This prevents errors when the Date field is temporarily cleared, allowing the wizard to behave correctly during user input. Issue reference: https://github.com/odoo/odoo/issues/246547 Forward-Port-Of: odoo/odoo#273002
This update resolves a recurring issue that caused the HTML editor to sometimes fail during testing. The fix addresses a timing problem related to how the browser handles updates, ensuring the editor's toolbar functions reliably. This improves the overall stability and user experience of the HTML editor.
Original PR description
### Description of the issue/feature this PR addresses: - Resolve non-deterministic failures in the 'toolbar should not open between double and triple click' Hoot test. - Because browser-level selectionchange events are dispatched asynchronously in the event loop, asserting on the presence of `.o-we-toolbar` in the DOM leads to timing race conditions. ### Solution: - Resolves the flakiness by introducing a wrapper method `triggerDebouncedUpdateToolbar` in `ToolbarPlugin` and refactoring the test to track method call sequences instead of asserting on DOM elements. This verifies the scheduled debounced updates in a deterministic sequence. task: https://runbot.odoo.com/odoo/error/243145 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273648 Forward-Port-Of: odoo/odoo#273303
This update fixes a potential issue where Point of Sale records weren't being fully initialized before setup processes. By ensuring all records are created first, this change improves the stability and reliability of the Point of Sale module, preventing errors during initial configuration or data loading. This resolves a previously reported problem impacting data consistency.
Original PR description
This commit change the behavior of loadData to ensure that all records are linked & created before calling setup method of each of them. related task: 4922193 Forward-Port-Of: odoo/odoo#229128 Forward-Port-Of: odoo/odoo#228820
This update fixes an unexpected accrual of holiday days that occurred when carryover balances were applied at the beginning of the year. The fix ensures accruals only happen at the standard period boundaries (start/end of month or level transitions), resolving a confusing and inaccurate calculation. This improves the reliability of holiday balance tracking.
Original PR description
## Issue Currently, an extra accrual happens on carryover date, but it shouldn't. Indeed, accrual only happened at the start - end of a period, or on level transition. ## Reproducing steps Let's take an accrual plan with a level that adds 2 days/month on the 15th of the month. The carryover takes place at the beginning of the year. So we will have this: - 2025-11-01 -> creation of the allowance, 0 days available - 2025-11-15 -> 1 day (only 15 days are counted, so only half of the days are added) - 2025-12-15 -> 3 days (1 full month elapsed) - 2026-01-01 -> 4 days (as the carryover triggers an accrual) -> this event causes confusion as the accrual seems to “come out of nowhere” - 2026-01-15 -> 5 days - 2026-02-15 -> 7 days task-5432188 Forward-Port-Of: odoo/odoo#245201
This update resolves an issue where importing vendor bills from KSeF would fail if custom taxes were used. Now, the system automatically detects and processes FA(3) XML files, dynamically matching KSeF tax codes to the correct purchase tax rates. This ensures smoother and more accurate bill imports for users with customized tax configurations.
Original PR description
…oder signature When importing a vendor bill from KSeF, the system strictly relied on official Odoo tax XML IDs (e.g., `vz_kraj_23`). If a user had custom taxes (e.g., from a third-party localization), the import would crash with a UserError indicating the tax was not found. Allow manually uploading a FA(3) XML file to vendor bills, and it is detected automatically by the system This commit fixes these issues by: 1. Implementing a smart fallback tax search. If the official XML ID is not found, it dynamically searches for a matching purchase tax based on the KSeF tax code (e.g., '23' -> 23% purchase tax, 'zw' -> 0%). 2. Adding an adapter method that matches the expected EDI decoder signature, processes the file data, and writes the parsed values to the draft invoice. task-6067168 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#256818
This update resolves an issue where the live chat system would crash when a chatbot attempted to forward a conversation to an operator, and no operators were configured for that channel. The fix prevents the system from attempting to process an empty operator list, eliminating the error and ensuring smooth chatbot operation.
Original PR description
When a live chat channel has no operators configured and the chatbot script ends with a Forward to operator step, triggering that step causes a traceback. Steps to reproduce the error: - Install…
When a live chat channel has no operators configured and the chatbot script ends with a Forward to operator step, triggering that step causes a traceback. Steps to reproduce the error: - Install ``im_livechat`` module with demo data - Go to Live Chat > Configuration > Chatbots > Create a new chatbot > Add script > Step Type: Question > Set answers > Save > Add script > Step Type: Forward to operator > Only If: Set one of the above answers > Save - Go to Live chat > Channel > Click the configure channel on YourWebsite.com > Remove the operators > Save - Go to the chatbot > test > select the configured answer Traceback: ```py StopIteration ``` https://github.com/odoo/odoo/blob/8791cdcd89ea3cb56b1fac63b3e2ffbd2956a912/addons/im_livechat/controllers/chatbot.py#L65-L70 When the chatbot script reaches a Forward to operator step while no operator is configured in the live chat channel, no chatbot message is created. As a result, the generator iterates over an empty iterator, and the ``next()`` call raises a ``StopIteration`` exception, causing a traceback during the conversation. sentry-7435424405 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#261726
This update allows invoices in Italy to include both the 0% DoI tax and other applicable taxes on a single line. Previously, the system incorrectly excluded DoI tax amounts, leading to incorrect plafond calculations. This change ensures accurate tax calculations and reporting for Italian customers.
Original PR description
- Create a declaration of intent in the customer's contact - Issue an invoice that includes both the 0% E (DoI tax) and any other tax - You will see how the plafond is not updated and the amount of this invoice is not deducted from it The method _compute_l10n_it_edi_doi_amount specifically exclude from the doi amount lines with the doi tax and another tax. However it should be possible to use both on a single line. We can use the amount subtotal because the doi is always 0%. opw-6253475 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#267669
This update resolves an issue where batch payment sequences were incorrectly created when a new company was initially set up. The change ensures sequences are properly associated with the correct company, preventing errors during payment processing. This improves the reliability of our payment system.
Original PR description
Previously, batch payment sequence will be created by simply select to create new company due to having lambda in default. Hence, the created sequence does not have a correct company_id set as company hasn't yet created. Switch to creating sequence in ``create`` function to avoid this issue. Also use ``range_year`` for payment prefix because it was set to use date range. 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#273487 Forward-Port-Of: odoo/odoo#268689
This update fixes an issue where invoices weren't accurately reflecting timesheet hours after a partial refund was issued on a sales order. The change ensures that previously invoiced hours are properly deducted when generating new invoices, preventing over-invoicing and ensuring accurate reporting. This improves the reliability of sales order billing.
Original PR description
### Steps to reproduce: - Download 'Sales' and 'Timesheets' apps - Create a service product invoiced on delivered quantities with timesheet tracking - Create and confirm a SO for quantity 1 - Log 20h…
### Steps to reproduce: - Download 'Sales' and 'Timesheets' apps - Create a service product invoiced on delivered quantities with timesheet tracking - Create and confirm a SO for quantity 1 - Log 20h on timesheets - Invoice the SO - Create a credit note for 11 hours => only 9 hours are invoiced - Log 5h more on timesheets - Back to the SO > create invoice again > All the 25hrs are to invoiced, although 9 of them were invoiced before ### Cause of Issue: When generating the new invoice, `_recompute_qty_to_invoice` calls `_get_delivered_quantity_by_analytic` which retrieves the analytic values for the SO line. The values retrieved are later used to determine the delivered quantity, which is later assigned to be `line.qty_to_invoice` without taking into account the already invoiced hours. https://github.com/odoo/odoo/blob/7a6518e39d34575a3977e7c4a0053a45223e203c/addons/sale_timesheet/models/sale_order_line.py#L176-L186 ### Fix: Ensures that hours that have already been completely invoiced are deducted from the quantity to invoice. opw-6253650 Forward-Port-Of: odoo/odoo#273156 Forward-Port-Of: odoo/odoo#268025
This update corrects a bug where unreserving a production order would prevent byproducts from being created. The fix ensures that byproducts are properly adjusted when an order is unreserved, maintaining accurate inventory levels. This resolves an issue impacting production planning and material availability.
Original PR description
On a mo that has byproducts, if you unreserve, it will also set the quantity of byproducts to 0 Steps to reproduce: ------------------- * Create a Products main, component and byproduct * Create a…
On a mo that has byproducts, if you unreserve, it will also set the quantity of byproducts to 0 Steps to reproduce: ------------------- * Create a Products main, component and byproduct * Create a bom for main with component as component and byproduct as byproduct * Create and confirm a mo for main * Set qty_producing to quantity ot produce * click on "Unreserve" (do_unreserve) * click on "Check availability" (action_assign) * Produce All -> the byproducts will not be produced. Observation: ------------- When updating the qty_producing value it will also update the quantity of the byproducts moves: https://github.com/odoo/odoo/blob/77b180e8251fb8019e0034e1c2f485fd2c34ea4e/addons/mrp/models/mrp_production.py#L892-L893 https://github.com/odoo/odoo/blob/77b180e8251fb8019e0034e1c2f485fd2c34ea4e/addons/mrp/models/mrp_production.py#L1350 https://github.com/odoo/odoo/blob/77b180e8251fb8019e0034e1c2f485fd2c34ea4e/addons/stock/models/stock_move.py#L2382 The quantity on the byproducts move has been updated. When clicking on Unreserve it will call do_unreserve, https://github.com/odoo/odoo/blob/aca2e226143487b421f79194d677bb48d5da1358/addons/mrp/models/mrp_production.py#L2297-L2298 It will filters the moves that do not need to be unreserved and select the others: https://github.com/odoo/odoo/blob/aca2e226143487b421f79194d677bb48d5da1358/addons/stock/models/stock_move.py#L900 and it will unlink all the sml from the moves: https://github.com/odoo/odoo/blob/aca2e226143487b421f79194d677bb48d5da1358/addons/stock/models/stock_move.py#L919 Which will set the quantity on the byproduct moves to 0. When Producing all (button_mark_done) since the qty_producing has already been set, it will simply mark the byproduct move has picked. https://github.com/odoo/odoo/blob/aca2e226143487b421f79194d677bb48d5da1358/addons/mrp/models/mrp_production.py#L1323-L1324 In our case, this means that the no byproducts will be created since, the quantity was previously set to 0 opw-6296562 Forward-Port-Of: odoo/odoo#272216
This update clarifies the descriptions for both User and Administrator groups within the Project module. The changes improve clarity regarding user access to projects and reporting capabilities, ensuring accurate understanding of permissions.
Original PR description
This commit improves the grammar of the Project user group description. ### **For User:** **Before -** `User can user the your employees' schedule` **After -** `User: Can manage tasks in projects shared with them.` ### **For Admin:** **Before -** `Administrator can manage the employees' schedule` **After -** `Administrator: Can manage projects and stages, with access to reporting and configuration.` **opw-6340390** Forward-Port-Of: odoo/odoo#273061
This update resolves an issue where invoices were displaying an incorrect final amount due due to a misinterpretation of loyalty program discounts. The fix ensures that tax calculations are accurate, particularly when loyalty discounts are applied, preventing a small discrepancy in the invoice total. This improves the reliability of the POS order process.
Original PR description
When computing taxes for the order, we group the base lines based on a grouping key. One of the components of this key is `is_refund`, and reward lines where considered as refund lines, which caused…
When computing taxes for the order, we group the base lines based on a grouping key. One of the components of this key is `is_refund`, and reward lines where considered as refund lines, which caused them to be grouped separately. This caused a discrepency between the tax amount computed in the frontend and the one computed in the backend. Steps to reproduce: ------------------- * Change the rounding method to globally * Create a 21% tax not included in price * Create a product with a price of 76.01 and the tax created above * Create a loyalty program with a 10% discount * Create a POS order with the product above and apply the loyalty program * Validate the order and generate the invoice > Observation: The invoice states that 0.01$ is still due Why the fix: ------------ In `round_tax_details_tax_amounts`, we try to detect any delta with the expeced tax amount. To do that we group the base lines based on a grouping key. The grouping key `is_refund` was incorrectly set to `true` for reward lines, which caused them to not be grouped. The delta was then not detected and tax amounts were not adjusted. We now make sure not to consider reward lines as refund. opw-6052112 Forward-Port-Of: odoo/odoo#273397 Forward-Port-Of: odoo/odoo#271577
This update strengthens the website's security by preventing unauthorized users from subscribing to stock notifications for unavailable products or using existing customer email addresses. The change adds validation to ensure subscriptions are legitimate and prevents potential misuse of user accounts, enhancing overall system security.
Original PR description
Description of the issue/feature this PR addresses: Currently, in the website_sale_stock module, there is no backend validation when subscribing to notifications for products without stock. This…
Description of the issue/feature this PR addresses: Currently, in the website_sale_stock module, there is no backend validation when subscribing to notifications for products without stock. This allows public users to potentially use emails that belong to registered accounts. Current behavior before PR: Users could subscribe to stock notifications for products that don’t exist or cannot be added (no stock). Public users could use emails already associated with registered accounts, allowing them to subscribe on behalf of another user. No validation is enforced, leading to potential security issues. Desired behavior after PR is merged: Adding a subscription for a non-existent or unavailable product raises a ValidationError. Public users trying to subscribe with an email that belongs to a registered user receive an AccessError prompting them to sign in first. Backend validation prevents misuse of registered user emails and improves security. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273691 Forward-Port-Of: odoo/odoo#271880
This update resolves an issue where reverting inventory adjustments with packages resulted in negative quantities appearing within those packages. The fix ensures that quantities are accurately restored after a revert, preventing inconsistencies in package inventory levels. This improves data accuracy and reliability for stock management.
Original PR description
Currently when the user reverts an inventory adjustment move line with a package the package contains extra line showing negative quantity of the product. ## Steps to produce: - Install Inventory…
Currently when the user reverts an inventory adjustment move line with a package the package contains extra line showing negative quantity of the product.
## Steps to produce:
- Install Inventory without demo data
- Settings Enable 'Packages'
- Create a product:
- Cheese burger
- On hand > Create a new quant
- Package: 'Burgerbox' and 'On Hand Quantity`: 1 and save
- Set the On Hand quantity to zero and save
- History > Revert the Inventory adjustment line from WH/stock to Inventory adjustment by selecting it and reverting via actions.
- Products > Packages > BurgerBox
## Observed Behaviour:
After reverting an inventory adjustment that set the product's physical quantity to 0, the package contains two lines for the same product with quantities 1 and -1.
This is inconsistent because a package should not contain a product with a negative quantity.
The package should be restored to its original state and contain only the expected positive quantity.
## Root cause:
When the user reverts the move line, `action_revert_inventory` is called. This method creates the revert move and then marks that move as done at [1].
Marking the move as done subsequently marks all related move lines as done at [2]. During this process, the system first unreserves the quantity from the virtual location / inventory adjustment and then removes the quantity from that location (resulting in a -1 quantity move line at that location). This is performed through `_synchronize_quant`, which is responsible for synchronizing the physical inventory with the move line at [3].
The `_synchronize_quant` method uses the move line's `package_id` when updating the corresponding quant at [4]. As a result, `_update_available_quantity` creates a new quant with the following values at [5]:
```
{
'product_id': 1,
'location_id': 14,
'lot_id': stock.lot(),
'package_id': 1,
'owner_id': res.partner(),
'in_date': datetime.datetime(2026, 6, 22, 12, 42, 11),
'quantity': -1.0,
}
```
This creates a quant with a negative quantity that is linked to the package because `package_id` is set on the newly created quant. Consequently, the move line with the negative quantity becomes associated with the package.
[1]-
https://github.com/odoo/odoo/blob/333c279be7cba9fda17d2818be36f4d96d8cd0f6/addons/stock/models/stock_move_line.py#L1016-L1035
[2]-
https://github.com/odoo/odoo/blob/333c279be7cba9fda17d2818be36f4d96d8cd0f6/addons/stock/models/stock_move.py#L1956 [3]-
https://github.com/odoo/odoo/blob/333c279be7cba9fda17d2818be36f4d96d8cd0f6/addons/stock/models/stock_move_line.py#L662-L666
[4]-
https://github.com/odoo/odoo/blob/333c279be7cba9fda17d2818be36f4d96d8cd0f6/addons/stock/models/stock_move_line.py#L678-L687
[5]-
https://github.com/odoo/odoo/blob/333c279be7cba9fda17d2818be36f4d96d8cd0f6/addons/stock/models/stock_quant.py#L1130-L1143
## Solution:
Remove the source `package_id` when creating revert moves for inventory adjustment locations.
When an inventory adjustment sets a product's quantity to 0, the adjustment is completed without a destination package, meaning the product is effectively removed from the package. Therefore, the corresponding revert move should not retain the package as its source. Keeping the package as the source is inconsistent because package information should not exist on a virtual inventory adjustment location, and the original inventory adjustment removes the product from the package (there is no destination package).
By removing the source `package_id` from the revert move, the system avoids creating negative quants associated with the package during quant synchronization. This also ensures that, after the inventory adjustment is reverted, the quantities of products inside the package are restored correctly and match their state prior to the adjustment.
opw-6285739
Forward-Port-Of: odoo/odoo#273632
Forward-Port-Of: odoo/odoo#271440This update corrects a visual issue where the background color of the account type selection dropdown remained in light mode when dark mode was enabled. The change ensures the dropdown's background color matches the overall dark mode theme, improving the user experience and visual consistency. This fix was implemented to maintain a polished and professional appearance across all Odoo environments.
Original PR description
Steps to reproduce: - Install `account` module - Enable dark mode - Open `view_account_form` to create a record - On the Accounting page, open type dropdown - The dropdown background remains in light mode This commit applies $dropdown-bg on `o_field_account_type_selection` as in odoo/odoo@0cd148eb389078c896aaa719af5733d05377fd1c Forward-Port-Of: odoo/odoo#274098 Forward-Port-Of: odoo/odoo#271352
This update fixes an issue where template tasks were incorrectly counted in task views and notebooks. The change ensures that task counts accurately reflect only real subtasks, improving the clarity and usability of project management within the Odoo system. This ensures accurate reporting and task management.
Original PR description
Steps to Reproduce --- - Create a normal parent task with one normal sub-task and one template sub-task. - Open the parent task form view and observe the Sub-tasks stat button count and notebook tab,…
Steps to Reproduce --- - Create a normal parent task with one normal sub-task and one template sub-task. - Open the parent task form view and observe the Sub-tasks stat button count and notebook tab, check the subtask view as well. - Create a template parent task with one normal sub-task and one template sub-task, then repeat the same checks. Issue --- - Task templates are handled like regular subtasks in the subtask count, notebook, and subtask view, without taking the parent task type into account. Current Behaviour --- - For a normal parent task, both the normal sub-task and the template sub-task are counted and shown in the opened subtask view and notebook. - For a template parent task, the same filtering is applied, even though template subtasks should remain accessible in that context. Expected Behaviour --- - For a normal parent task, only real sub-tasks should be counted and shown in the subtask view and notebook, and on the project kanban card. - For a template parent task, template subtasks should remain available in the subtask view and notebook according to the parent template context. - In the project kanban card, tasks must not be counted when their parent task is a template, even if the child task itself is not a template. Fix --- - Apply template-aware filtering to subtask counting,project kanban task count and subtask view behavior, depending on whether the parent task is a normal task or a template task. task-5966684
This update fixes an issue where expense accounts weren't being correctly applied during Point of Sale transactions. Now, when a sale is made without invoicing, the system accurately maps expense accounts based on the fiscal position or product category, ensuring accurate financial reporting. This improves the reliability of financial data generated from Point of Sale.
Original PR description
**Steps to reproduce:** - Make a product with a category - In the category, make the inventory valuation to automated - Set the income and expense account - Set a cost for the product - Make a fiscal…
**Steps to reproduce:** - Make a product with a category - In the category, make the inventory valuation to automated - Set the income and expense account - Set a cost for the product - Make a fiscal position and set it as default for the PoS - In the Account Mapping tab, map the income and expense to two other accounts - Go to the PoS - Make a sale for that product, without invoice - Close the session and in the backend check the session - Check the journal entries - The income account has been mapped to the fiscal position's - The outcome account stayed the same as in the category's **Why the fix:** When we invoice an order, the income and expense accounts are immediately updated, in a different place than if it has not been invoiced. At the session's closure, we update the accounts for every order that hasn't been invoiced. In this flow, the account mapping defined on the fiscal position was not applied, so we took the one defined on the product's category. The income account was already mapped as we need to do it earlier than the session closure, so it had already been set as the right one before our flow. For the expense account, we only need it at this specific time, so we can map it as the session's closure. We now map the account depending on the fiscal position if we are able to find one, otherwise, we use the category's default as we did before. opw-6171677 Forward-Port-Of: odoo/odoo#266700
This update corrects a previous error that triggered a user error message when generating invoices for Co-Contractant tax situations. The fix ensures that a note is only added to the invoice when the Co-Contractant tax amount is zero, aligning with standard fiscal practices. This improves invoice accuracy and user experience.
Original PR description
We were raising a UserError because we were putting the note even if the tax amount was different from 0. But in fact, it can be normal to have 0% cocontractant tax and normal rate at the same time on an invoice, which would have the fiscal position Co-Contractant. So remove these UserError, but only apply the note when the tax amount is 0 opw-6302806 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#274117 Forward-Port-Of: odoo/odoo#268899
This update ensures that taxes and order totals are accurately displayed when customers select in-store pickup for international orders. Previously, the system incorrectly applied VAT, leading to inaccurate checkout summaries. This fix automatically recalculates taxes and updates the checkout summary to match the selected pickup location.
Original PR description
Backport of : https://github.com/odoo/odoo/pull/269057 to V18 When an international customer selects an in-store pickup location, the order's fiscal position changes to the fiscal position matching…
Backport of : https://github.com/odoo/odoo/pull/269057 to V18 When an international customer selects an in-store pickup location, the order's fiscal position changes to the fiscal position matching the pickup warehouse. However, the order-line taxes and checkout summary are not recomputed immediately. **Steps to reproduce:** 1. Configure a French company and website. 2. Configure a product priced at 100 ( just an example , any price will do ) EUR excluding 20% French VAT. 3. Configure an export fiscal position removing VAT for Japan. 4. Configure an international delivery method. 5. Configure an in-store pickup method with a warehouse located in France. 6. Checkout using a Japanese delivery address. 7. Select the international delivery method. 8. Switch to pickup in store. **Current behavior:** - The order fiscal position changes to the French fiscal position. - Product-line taxes and the checkout summary remain based on the export fiscal position. - French VAT only appears later on the payment step. - Switching back to international delivery can similarly leave stale totals. **Expected behavior:** - Selecting the French pickup location immediately applies French VAT. - Switching back to international delivery immediately removes French VAT. - Totals displayed during delivery selection match the payment-step totals. **Cause:** The Click & Collect flow explicitly recomputes `fiscal_position_id` when selecting or leaving an in-store pickup location, but it does not recompute the order-line taxes and prices. Additionally, the pickup-location route does not return updated order-summary values, so the checkout page cannot refresh its displayed totals. **Solution:** - Recompute taxes and prices when the in-store fiscal position changes. - Restrict the recomputation to draft website orders. - Return the updated order summary after selecting a pickup location. - Refresh the checkout summary using the returned values. **Tests cover:** - Japanese delivery with export fiscal position and no VAT. - Switching to a French pickup location immediately applying 20% VAT. - Switching back to international delivery removing VAT. - Delivery-step totals matching payment-step recomputation. - Pickup-location route returning updated summary values. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269086