Monday, July 6, 2026
29 changes · saas-19.4
New functionality added to Odoo
This update introduces a new 'Profitability' field to account analytic lines, enabling a clearer breakdown of revenue and loss within the Analytic Report. This enhancement provides better visibility into the financial performance of transactions, allowing for more informed decision-making.
Original PR description
[IMP] account: group analytic items by profitability This commit add a new field 'Profitability' on the account analytic line model, this will allow to visually split analytic line items in 2 categories: 'Revenue' and 'Loss' in the Analytic Report task-4959636 Forward-Port-Of: odoo/odoo#272369 Forward-Port-Of: odoo/odoo#262962
This update adds PayU as a new payment option for our customers. This expands payment choices and supports a growing market, streamlining the checkout process for users who prefer PayU.
Original PR description
Add new payment provider PayU. See README.md for more details. task-6219530 Forward-Port-Of: odoo/odoo#267962
Enhancements to existing features
The timesheet timer now opens with the project the employee has most recently and consistently used, making repeat time entry faster. If the user is already viewing a specific active project or task, that context still takes priority, while archived or template records are no longer suggested.
Original PR description
When opening the timesheet systray, the timer is now prefilled with the project to which the employee's three most recent timesheets are all linked, since they are most likely to keep logging time on it. The currently viewed project or task takes precedence over the favorite project, and viewing a project form now prefills the timer as well, just like task views already do. task-6290859 Forward-Port-Of: odoo/enterprise#120028
Resolved issues and error corrections
This fix prevents small rounding differences in attendance overtime calculations from creating overlapping work entries. It helps keep employee work entry records accurate, especially for overnight shifts, reducing payroll or attendance inconsistencies.
Original PR description
__Issue:__ `duration` is rounded to 3 decimals (~1.8s drift) while `time_stop` is exact, so the back-projected start could land before midnight on overnight overtime or middle of the day causing overlaps with the previous line Example: - time_start = 03/05 00:00:00 - time_stop = 03/05 07:07:14 actual duration 7h07m14s gets stored as `duration = 7.121` (= 7h07m15.6s) after `round(_, 3)`. Back-projection yields `datetime_start = 07:07:14 - 7.121h = 02/05 23:59:58`, overlapping by ~2s with the prior line ending at `02/05 23:59:59.999`. __Fix:__ Sort lines by `time_stop` within each date and clamp `datetime_start` to the previously emitted interval's stop when the two intervals genuinely intersect. opw-6170828 Forward-Port-Of: odoo/enterprise#121564 Forward-Port-Of: odoo/enterprise#116565
The payroll data update process is now configured for the Philippines payroll module. This helps keep standard, non-customized salary rules automatically up to date, reducing manual maintenance and improving reliability for payroll users.
Original PR description
Currently, the "Payroll: Update data" cron doesn't work for HK payroll as we never set up the _get_data_files_to_update. We can set up the list of data files to keep up to date to better support our users by automatically keeping non-edited salary rules up to date. task-6360470
Budget reports now use the same profitability basis as analytic profitability views when selecting analytic accounting entries. This helps finance teams see more consistent budget figures across reports and profitability analysis.
Original PR description
Use the new field analytic_profitability in the conditions of the query to get the account analytic lines of the budget report task-4959636 Forward-Port-Of: odoo/enterprise#121898 Forward-Port-Of: odoo/enterprise#121760
Refunded point of sale orders that fully cancel out matching customer-account payments are now hidden from the Settle Orders list. This keeps the list focused on amounts that still need action and avoids asking users to manually settle orders and refunds that already balance each other.
Original PR description
Currently, if you refund an order made on the customer account with the customer account as well, you can still see the order in the list of orders to settle. Steps to reproduce: -------------------…
Currently, if you refund an order made on the customer account with the customer account as well, you can still see the order in the list of orders to settle. Steps to reproduce: ------------------- * Open shop * Make an order using the customer account for a customer, don't invoice it * Refund one of the order using the customer account, don't invoice it * Make a new order using the customer account * In the customer list, find the customer used and select "Settle Orders" > The 2 orders are present in the list Why the fix: ------------ Originally the list would only show the orders for chich the customers have due (>0). https://github.com/odoo/enterprise/commit/bf4b6043b999b4a081b1afa73fc4113bf4db28f8 But recently the code we also see the refunds in the list as well. https://github.com/odoo/enterprise/commit/12af23d5382e972facfaa999e4c5ab30c97e8d1f However this new behavior is not visible if, with the refund, the customer account temporarily falls to 0. So currently we have some refunds that impact the amount to settle and some that don't. Originally we were thinking that either we should show all refunds in that list (given they use the customer account) or we shouldn't show any as it was previously. Both solutions are not ideal. * Showing them all would get the list bigger than it is and would require the customer to select the order and its refund(s) and settle them together. Since refunds are not usually done right after the order they would not be close it that list. However this solution would enable the option to remove the orders from the list requiring a few step from the customer. * Showing none isn't idea either with this use case as it means that we still see orders that were cancelled out by their refunds. To remove to order the customer has two options. Either going backend and searching the order and its refund(s) and invoice them, either settling the order but that means that now there's money deposited on the customer account. Any of the two option isn't perfect a it still requires manual intervention from the customer and wouldn't work on previous data. Creating a server action to correct those data wouldn't have been feasible either. Instead, the approach we're taking is the following: When loading the list of order to settle we want to remove the orders and the potential refunds were the customer account is evened out. We only need to look at the orders of the partners that contains refunds for which the customer account was used. If the sum of the transactions made on the customer account is 0 we can say that the order and its refunds have cancelled out each other (in terms of customer account) and we don't show them if the list of orders remaining to settle. opw-6170830 Forward-Port-Of: odoo/enterprise#117725
The Timesheets app now correctly marks days as unavailable in an employee's own timesheet when their working schedule changes. This helps users avoid entering time on days they are not scheduled to work.
Original PR description
To reproduce: ============= - modify Mitchel Admin's working schedule and remove a day of work - open timesheet app as Mitchel Admin - the removed day is not grayed out as unavailable Porblem: ======== the method `get_unavailabily` was handling only the case when calling it with `groupby=employee_id` otherwise it returns the company's unvailability Solution: ========= when the "My Timesheet" action is opened, the method `get_unavailabily` is now called with a specific context key, allowing to return the current user's unavailability instead of the company's one. opw-5949236 Forward-Port-Of: odoo/enterprise#122936 Forward-Port-Of: odoo/enterprise#113984
This fix prevents Belgian payroll processing from failing when an employee has multiple contract or employment versions within the same month. Payroll teams can complete pay runs for affected employees without manual intervention or blocked payslip generation.
Original PR description
Currently, there is an error while running payrun step with employee who has multiple version in 1 month. ``` number_of_hours = (work100_wds - worked_day).number_of_hours ValueError: Expected singleton: hr.payslip.worked_days(233, 234) ``` Step to reproduce: 1. Create Employee with multiple version in 1 month 2. Create New PayRun during that month 3. Run the PayRun until Payslip step 4. Expected error on payslip steps reason: substraction of work100_wds and worked_day generate more than 1 value, if we have multiple version in 1 month task-6296276 Forward-Port-Of: odoo/enterprise#122483
Scanning a package during barcode picking now correctly assigns it as the destination package, even if that package already contains other products elsewhere. This prevents an unnecessary error when extra products are not allowed, helping warehouse teams complete two-step delivery workflows without interruption.
Original PR description
### Steps to reproduce: - In the settings Enable: Multi-steps Routes, Packages - Put your warehouse in delivery in 2-steps - On the Pick operation type in the barcode tab disable: "Allow extra…
### Steps to reproduce: - In the settings Enable: Multi-steps Routes, Packages - Put your warehouse in delivery in 2-steps - On the Pick operation type in the barcode tab disable: "Allow extra products" - Create two storable products P1 and P2 - On P2 > On hand > Update Quantity > New - Create a new line in WH/Output with a package POOK for 1 unit - Create a new internal transfer for 1 unit of P1 using the pick operation type so that the picking goes WH/Stock -> WH/Output - Set the quantity of the move to 1 unit and go to the barcode app - Open the Pick > Scan WH-STOCK > Scan P1 > Scan POOK #### > An error is raised: This package contains extra products and extra products are not allowed on this operation. #### Expected behavior: The package should be set as result package. ### Cause of the issue: In the `_processPackage`, a check that is done to ensure that the package scan will not add extraproduct to the picking if this operation is not allowed: https://github.com/odoo/enterprise/blob/5e4c8ecb0c644e21755570ed59cd8f6e9f618c8a/stock_barcode/static/src/models/barcode_picking_model.js#L2024-L2035 Unfortunately, this check is done just before a possible usage of the package as package dest. And, in that case, since we do not try to add any product to the picking the check is irrelevant anyway. opw-6303969 Forward-Port-Of: odoo/enterprise#122782 Forward-Port-Of: odoo/enterprise#121789
Users who choose to handle notifications inside Odoo will now be notified in their inbox when a signature request they sent is completed. This prevents missed updates and helps teams track completed signing tasks without relying on email notifications.
Original PR description
## Issue When a user sets their notification to "Handle in Odoo" (`inbox`) and a sign requested is completed, they do not receive the expected notification. ## Steps to reproduce 1. Install *Sign*…
## Issue When a user sets their notification to "Handle in Odoo" (`inbox`) and a sign requested is completed, they do not receive the expected notification. ## Steps to reproduce 1. Install *Sign* (`sign`) 2. Sets the current user's notification preference to "Handle in Odoo" (`inbox`) 3. Create a sign request and send it to Marc Demo 4. As Marc Demo, sign the request 5. **The user who sent the sign request did not receive a notification to notify them that the request was signed.** ## Fix This is a partial backport of both https://github.com/odoo/enterprise/commit/463d6a2aae536356e6dee6b902f2e881dbc4fbda (saas-18.2) and a related fix https://github.com/odoo/enterprise/commit/41395dba4fd31222f5fd9fc94a84c977cf9334f9 (19.0). Before the first commit, users would not receive inbox notification when sign requests would be completed. ## Note to reviewer The issue only occurs in 18.0, as it is fixed by https://github.com/odoo/enterprise/commit/463d6a2aae536356e6dee6b902f2e881dbc4fbda in 18.2, but we can backport the fix from https://github.com/odoo/enterprise/commit/41395dba4fd31222f5fd9fc94a84c977cf9334f9 from 18.2 to 18.4 if desired. opw-6251702 Forward-Port-Of: odoo/enterprise#122740 Forward-Port-Of: odoo/enterprise#120740
Fixes an error that could occur when shortening the deadline of a standalone task in the Project Gantt chart. Users can now adjust task deadlines normally, even when the task has no dependent follow-up tasks.
Original PR description
## Current behavior: In the Project's app, switch to Gantt chart's view, when changing the deadline of a single task by shrinking its right edge, the server throws `ValueError: max() iterable…
## Current behavior: In the Project's app, switch to Gantt chart's view, when changing the deadline of a single task by shrinking its right edge, the server throws `ValueError: max() iterable argument`` is empty when calling end_date = max(candidates.mapped(stop_date_field_name)). ## Steps to reproduce: 1. In version 19.0 and above, install Project app 2. Create a project and only 1 single task 3. Switch to Gantt chart view 4. Try changing the deadline of a task by dragging its right edge 5. Observe that extending the task's deadline by dragging to the right works fine, but shrinking the deadline by dragging to the left will cause server to throw RPC_ERROR: Odoo Server Error and ValueError: max() iterable argument is empty. ## Cause of the issue: - A task with NO successors will cause candidates gathered via dependency_inverted_field_name to be empty. - The empty candidates recordset then get called by max(candidates.mapped(stop_date_field_name)), which is the reason causing error message ValueError: max() iterable argument is empty. opw-6283566 Forward-Port-Of: odoo/enterprise#121517 Forward-Port-Of: odoo/enterprise#120375
The Timesheet Assistant now gives cleaner, more relevant suggestions by excluding leave time and hiding to-do items that are not tied to a project. Users also get smoother entry with clearer default suggestion names and keyboard shortcuts for creating timesheets.
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) Forward-Port-Of: odoo/enterprise#121085 Forward-Port-Of: odoo/enterprise#120057
Auto Plan now only assigns resources that match the role selected on a project planning slot. This prevents employees or resources from being scheduled for roles they are not assigned to, improving planning accuracy.
Original PR description
## Issue When using the *Auto Plan* feature on a planning slot with a Role and a Project set, a resource which operated on the same project will be chosen if available, without taking into account…
## Issue
When using the *Auto Plan* feature on a planning slot with a Role and a Project set, a resource which operated on the same project will be chosen if available, without taking into account the Role set on the slot.
## Steps to reproduce
1. Install Project Planning (`project_forecast`)
2. In Planning > Configuration > Roles, create two planning roles A and B
- Role A: Assign a resource R
- Role B: No resource
3. Open Planning (Schedule by Resource), and go back a few weeks (to prevent overlaps with potential demo data)
4. Create two new slots:
1. Set Role B and a random Project P, then click Auto Plan: there should be no available resource (because we didn't set any resource for Role B)
2. Set Role A and the same Project P, then click Auto Plan: it should assign the resource R assigned to Role A
5. After assigning a resource to the slot for Role A, edit the Open Shift for Role B again and click Auto Plan: **it assigns the same resource R, even though that resource is not assigned to Role B.**
## Cause
The `_get_open_shifts_resources` override in `project_forecast` looks for resources that were assigned to slots related to the same project. It does not filter resources based on the requested role.
https://github.com/odoo/enterprise/blob/885edbc270a86ab76e0a6eff4acb5767c0fe29d1/project_forecast/models/planning_slot.py#L104-L116
This means that resources that are not part of the requested role can be assigned to the slot, as long as the resource operated on another slot for the same project.
opw-6325744
Forward-Port-Of: odoo/enterprise#122742
Forward-Port-Of: odoo/enterprise#122035USPS package type forms now show the unit of measure for dimensions, reducing confusion when entering package sizes. Shipping rate calculations now use the selected USPS service type, so businesses receive the correct rate when changing package or service options.
Original PR description
Issue ----- There are 2 issues with USPS rest: 1. USPS packagings do not have their size UOM displayed. This leads to confusion as users input in inches but the dimensions are treated as feet. 2.…
Issue ----- There are 2 issues with USPS rest: 1. USPS packagings do not have their size UOM displayed. This leads to confusion as users input in inches but the dimensions are treated as feet. 2. USPS returns the same rate regardless of the package type. Steps to reproduce ----- - Set USPS up - Open the Package Type form > go to its' Dimensions tab > Issue 1 - Set USPS up (domestic) - Select a `Domestic Rating Indicator` (eg LF - Flat Rate Box) - Create a SO with some product - Open the delivery widget and add a rate with USPS - Discard the changes - Go to the delivery method and change the rating (eg SP - Single Piece) - Go back to the SO - Open the delivery widget and add a rate with USPS > Issue 2, rate is the same as before Issue 1 ----- By default, there is no displayed UOM on the form because of https://github.com/odoo/odoo/blob/38c737c2a4cc29b48235a100cfa9d6152af73826/addons/stock_delivery/models/stock_package_type.py#L20-L33 We can change this behaviour for USPS specifically as done in Envia https://github.com/odoo/enterprise/blob/20cc61e69aa3f6a59de1e962b25ce11fa402bf22/delivery_envia/models/stock_package_type.py#L37-L46 Issue 2 ----- In `usps_rest_rate_shipment`, we request rates for every package of the delivery, which we receive as lists. We then iterate over the list to find the rate matching the `mail_class`. The problem is that this only filters over whether the delivery is domestic or international. We don't filter based on the actual service selected on the carrier (`usps_domestic_rating_indicator` for domestic and `usps_international_rating_indicator` for international). https://github.com/odoo/enterprise/blob/20cc61e69aa3f6a59de1e962b25ce11fa402bf22/delivery_usps_rest/models/delivery_usps.py#L224-L236 ----- Ticket: opw-6224918 Forward-Port-Of: odoo/enterprise#120789 Forward-Port-Of: odoo/enterprise#120594
Fixed an issue where reconciling multiple discounted invoices together from a bank statement could overstate the discount base in tax reports. This keeps tax return figures accurate when invoices share the same VAT tax and are paid in one batch.
Original PR description
Steps to reproduce 1. Create two customer invoices that share the same VAT tax, with a payment term granting an early payment discount. 2. Create one bank statement line whose amount equals the sum…
Steps to reproduce 1. Create two customer invoices that share the same VAT tax, with a payment term granting an early payment discount. 2. Create one bank statement line whose amount equals the sum of both invoices' discounted totals. 3. From the bank reconciliation widget, select both invoices and validate in a single batch reconciliation. 4. Open Accounting > Reporting > Tax Return, switch the variant to "Group by: Account > Tax". Issue The cash-discount expense row shows a Net base column equal to twice the real discount base. The Tax column is correct. The bank-statement reconciliation paths (set_line_bank_statement_line, set_batch_payment_bank_statement_line, _reconcile_payments) loop over each invoice and call _apply_early_payment_discount one invoice at a time. Each call writes one discount base line and one discount tax line on the resulting bank entry, so when two invoices share the same tax the bank entry ends up with two pairs carrying the same (account, partner, currency, tax_repartition_line_id, tax_ids). The SQL that feeds the tax report at https://github.com/odoo/odoo/blob/d7d0efd39a65bfb6fee307b661cd2523a6b8231d/addons/account/models/account_move_line_tax_details.py#L100 matches every base line of a tax with every tax line of that tax inside the same move. With two pairs sharing one tax that turns two rows into four, and SUM(base_amount) doubles. The Tax column does not double because the same SQL redistributes each tax line's recorded amount across its matched rows so the totals still add back to the original tax. The payment register flow does not have this problem because it calls _get_invoice_counterpart_amls_for_early_payment_discount once with every invoice, and that helper already collapses duplicates with the merge key at https://github.com/odoo/odoo/blob/f3b317310b84edb073009f7d15d7fec002f3ccf0/addons/account/models/account_move.py#L5082-L5093 opw-6199906 Forward-Port-Of: odoo/enterprise#122747 Forward-Port-Of: odoo/enterprise#117743
Restaurant preparation displays now update correctly when staff split combo meals back into individual items, without creating duplicate kitchen tickets or unnecessary alerts. The fix also improves course labels for floating orders and ensures displays only receive preparation lines for their configured product categories.
Original PR description
Issue: Breaking a combo back into individual lines was not notifying the preparation display. Fix: breakCombo now go through sendOrderInPreparation (with byPassPrint) the preparation display is updated and no ticket is printed. To avoid triggering a sound and a kitchen ticket for a reorganization the kitchen already knows about, thread a `silent` context flag through sendOrderInPreparation down to _send_load_orders_message.
Preparation displays are now notified when an order is changed, so kitchen or prep teams see the latest information without missing updates. This helps avoid confusion and keeps order preparation aligned with point-of-sale changes.
Original PR description
Before this commit, when an order change was updated, the pdis were not notified of the change. This commit adds a call to the `_send_load_orders_message` method of the pdis to notify them of the change.
This update corrects a bug that caused currency conversion rates to be incorrectly calculated through branch companies instead of their root company. Previously, multi-branch setups would trigger errors. Now, all currency rates are consistently managed on the root company, ensuring accurate financial reconciliation and stability across the system.
Original PR description
**Description of the issue/feature this PR addresses:** When branch companies are involved, currency conversion goes through the branch instead of its root company. Because currency rates in Odoo…
**Description of the issue/feature this PR addresses:** When branch companies are involved, currency conversion goes through the branch instead of its root company. Because currency rates in Odoo only ever live on the root company, resolving a rate through a branch is incorrect. Furthermore, when two sibling branches are active at the same time, it makes the computed company a multi-record set, breaking the reconciliation process with an "Expected singleton" error. This is grounded in how the rest of res.currency already behaves by design: res.currency._get_rates() looks up rates with company_id in (False, company.root_id.id). res.currency.rate._check_company_id() forbids setting a rate on a company that has a parent_id. Therefore, rates are, by design, only ever meant to live on the root company. The only place that still passed the raw company (branch included) into with_company() was res.currency._get_conversion_rate(). **Current behavior before PR:** _get_conversion_rate() forwarded the received company untouched to from_currency.with_company(company). As a result, Odoo looked up the conversion rate through the branch rather than its parent. When more than one branch of the same parent is active at the same time (resulting in a recordset of 2+ branches), company.currency_id inside _compute_current_rate() was no longer a singleton, causing the code to crash with ValueError: Expected singleton: res.company(...) — even though every branch shares the exact same currency and rate defined on their common root company. **Steps to reproduce:** 1) Enable multi-company and branches. 2) Create a parent company P (e.g., using ARS as main currency). 3) Create two branches under P: B1 and B2 (branches inherit P's currency). 4) On the parent company P, define a currency rate for a foreign currency, e.g., USD (Accounting > Configuration > Currencies > USD > Rates). 5) Log in with a user that has P, B1, and B2 all selected as active companies (all three checked in the top-right company switcher). 6) In branch B1, create a customer invoice in USD. 7) In branch B2, register a customer payment in USD. 8) Open the Auto-reconcile tool or try to reconcile the journal items directly. Result: A ValueError: Expected singleton is raised during the reconciliation because the conversion rate is resolved against the multi-company recordset B1 + B2 instead of P. **Desired behavior after PR is merged:** _get_conversion_rate() now resolves the company to its root_id before computing the rate. Branches will correctly fallback to their parent company, and multiple active sibling branches will collapse to a single root company, ensuring that company.currency_id remains a singleton. With the same steps described above, the invoice and the payment now reconcile normally, safely using the single USD rate defined on the parent root company. Non-branch (standalone) companies remain unaffected since a root company's root_id is itself. **video** https://drive.google.com/file/d/14NGTTzP28CgSiYFQdFZ6juHSsib_MDd9/view --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273758
This update fixes an issue where dialogs opened from Kanban quick creates would unexpectedly close when switching tabs. Now, dialogs remain open and functional, allowing users to seamlessly navigate between views and complete their tasks. This enhancement ensures a smoother user experience when creating records from Kanban.
Original PR description
similar fix: https://github.com/odoo/odoo/pull/181220 - On a kanban view, click "New" to open a quick create record; - On a many2one field, type a value and click "Create and edit..."; - A dialog…
similar fix: https://github.com/odoo/odoo/pull/181220 - On a kanban view, click "New" to open a quick create record; - On a many2one field, type a value and click "Create and edit..."; - A dialog opens to create the related record; - From that dialog, open another many2one field the same way, so a second dialog opens on top of the first one; - Change tab in the browser. Before this commit, the quick create's `beforeVisibilityChange` handler unconditionally validated and closed itself as soon as the tab became hidden, with no regard for what was happening around it. Since the "Create and edit" dialogs are owned by the field widgets living inside the quick create (`useOwnedDialogs`), closing the quick create also close those dialogs, with no action from the user. This reuses the `formInDialog` counter already relied on by `FormController` for the same kind of issue: the quick create now listens to the same `FORM-CONTROLLER:FORM-IN-DIALOG` bus events, and only validates/closes itself on visibility change once every dialog opened from it has been closed. opw-6357255 Forward-Port-Of: odoo/odoo#274054
This update resolves an issue where importing vendor bills from KSeF would fail if custom taxes were used. Now, the system automatically detects and applies the correct tax based on the KSeF tax code, even with non-standard tax configurations. This ensures smoother and more accurate bill imports for users with diverse tax requirements.
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
The Viva.com POS tour was occasionally failing due to a delay in processing payment confirmations. This update ensures the tour correctly waits for payment responses before sending mock webhook data, preventing interruptions and improving the overall tour experience. This resolves a frustrating issue for users of the Viva.com POS system.
Original PR description
The Viva.com POS tour was failing intermittentely due to the mocked webhook response not waiting for the payment/refund request to finish. This would cause the tour to hang as it missed the webhook confirmation. We fix the issue by changing the `waitingCard` status to only be set after the payment request returns, and wait for this status before sending the fake webhook response. runbot-243758 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#273393 Forward-Port-Of: odoo/odoo#273111
This update fixes a bug where holiday accruals were incorrectly applied when carryover allowances were activated at the beginning of the year. The fix ensures accruals only occur at the standard period boundaries (start/end of month or level transitions), preventing unexpected accruals and improving the accuracy of holiday balances. This change impacts how holiday allowances are calculated.
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 corrects a discrepancy in the manufacturing order forecast report. Previously, the forecast incorrectly showed incoming quantities for finished products destined for a different warehouse. The fix ensures that the forecast accurately reflects the actual movement of materials, resolving inconsistencies between the forecast header and detail lines.
Original PR description
Version: ---------- - 18.0+ Steps to reproduce: ---------------------- 1. Install `mrp`, create two warehouses A and B. 2. Create a storable product with Track Inventory True. 3. Create a…
Version: ---------- - 18.0+ Steps to reproduce: ---------------------- 1. Install `mrp`, create two warehouses A and B. 2. Create a storable product with Track Inventory True. 3. Create a Manufacturing Order for 10 qty with(Miscellaneous tab): - Components location = Warehouse A (raw materials) - Finished product Location = Warehouse B 4. Confirm the MO. 5. Open the Forecast report for the product. Issue: ------- - Warehouse B forecast shows the MO under the replenishment detail lines (correctly, via `location_dest_id`) but the header displays "0 Incoming", "0 Outgoing", "0 Forecasted". - Warehouse A forecast incorrectly shows "10 Incoming" in the header, even though no finished product is going there. Cause: ------- - When we create MO for finished Product move is created if there no `location_final_id` then it set mo.warehouse_id.lot_stock_id` as the `location_final_id`. https://github.com/odoo/odoo/blob/f958a323fd652af9251215b1b5a2fadc3bccba42/addons/mrp/models/stock_move.py#L466-L467 which is introduce in this [commit](https://github.com/odoo-dev/odoo/commit/95ce0ed97a160e3465c313ed6b9bef938d61586b) - The problem is that `mo.warehouse_id` is a related field computed from `mo.location_src_id.warehouse_id` https://github.com/odoo/odoo/blob/f958a323fd652af9251215b1b5a2fadc3bccba42/addons/mrp/models/mrp_production.py#L110 - this warehouse that supplies the **raw materials** (Warehouse A). When the user sets `location_dest_id` to Warehouse B's stock, `mo.warehouse_id` is still Warehouse A, so `location_final_id` is stamped with Warehouse A's stock location. - `product.incoming_qty` (used by the forecast header) evaluates non-done moves using `location_final_id` first (if set), falling back to `location_dest_id` only when `location_final_id` is False: https://github.com/odoo/odoo/blob/f958a323fd652af9251215b1b5a2fadc3bccba42/addons/stock/models/product.py#L331-L335 - Because `location_final_id` is set (to WH-A) and non-False, the second clause (which would pick up `location_dest_id` = WH-B) is never evaluated. The result: the move is counted as incoming in Warehouse A and ignored in Warehouse B. - The forecast detail *lines* use only `location_dest_id` to classify moves, so they correctly show the MO as incoming for Warehouse B — producing the inconsistency the user observes. https://github.com/odoo/odoo/blob/f958a323fd652af9251215b1b5a2fadc3bccba42/addons/stock/report/stock_forecasted.py#L42-L46 Fix: ---- - Replace `mo.warehouse_id.lot_stock_id.id` with `mo.location_dest_id.id`: - `location_final_id` is meant to track where the product ultimately ends up when the immediate destination is intermediate. The correct "final" location for a finished-product move is exactly what the user chose as `location_dest_id` on the MO — not the stock location of the warehouse that happens to supply the raw materials. - For the standard single-warehouse case, `mo.location_dest_id` equals `mo.warehouse_id.lot_stock_id`, so the behaviour is unchanged. For cross-warehouse MOs (destination = WH-B), `location_final_id` is now stamped with WH-B's stock, making `product.incoming_qty` and the forecast header consistent with the detail lines. ---- opw-6294479 Forward-Port-Of: odoo/odoo#270089
This update fixes an issue where splitting a restaurant order didn't correctly apply the original order's fiscal position and pricelist to the new order. Now, when splitting, the new order inherits the correct tax settings and pricing rules, ensuring accurate financial reporting and order fulfillment. This improves the reliability of order splitting functionality.
Original PR description
When splitting an order, the new order was created without the original's fiscal position and pricelist, so its lines fell back to the default taxes Steps to reproduce: 1. Create a fiscal position with some tax mapping 2. Create a pricelist with some price rules 3. Add the fiscal position and pricelist to the delivery preset 4. Create a restaurant order as delivery 5. Split the order 6. Pay both of them 7. First order will have the default taxes and prices list instead of preset's ones Part of: https://github.com/odoo/odoo/pull/268862 -opw-6246434 Forward-Port-Of: odoo/odoo#273452 Forward-Port-Of: odoo/odoo#272837
This update fixes an issue where payment redirection wasn't correctly updating after processing. Previously, the landing route was set earlier, causing inconsistencies. Now, the updated landing route from the transaction is passed through, ensuring correct redirection to the cart payment page.
Original PR description
In commit 2cb589169fb77f98900997b9266ad309dcf602f9, a feature was introduced to redirect to cart payment when transaction was canceled or if an error occurred. Since commit 4588e939e3619949473f26223ada82c642c4bede, processing was triggered after we reach the payment_status page. At this point the landing route was already set in 'el.dataset.landingRoute' so any changes done to the landing_route by the processing won't be reflected in this js handling of redirection. As a solution, we return the updated landing route of the transaction in the post_processing api call. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes a potential issue where users could still register payments against invoices that were marked as blocked. Now, blocked invoices are correctly displayed in lists and payments cannot be registered through standard flows. This ensures accurate financial reporting and prevents incorrect payment processing.
Original PR description
When an invoice is blocked for payment, the form view hides the Pay button, but users could still register a payment from list/payment-item flows. Prevent payment registration for blocked invoices in both the invoice action path and the payment register wizard path. Also make blocked invoices display as Blocked in invoice lists instead of Posted or Sent. task-6310234 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270830
This update fixes an issue where changing the start date of a work order incorrectly calculated its duration. The fix ensures that the duration remains accurate when only the start date is adjusted, aligning with previous behavior and preventing incorrect end date calculations. This improves the reliability of work order planning.
Original PR description
**Problem:** On a planned work order, changing only the start date (e.g. in the planning gantt edit dialog) corrupts the expected duration instead of just shifting the end date. The duration drifts…
**Problem:** On a planned work order, changing only the start date (e.g. in the planning gantt edit dialog) corrupts the expected duration instead of just shifting the end date. The duration drifts to a wrong value, and in some cases (e.g. dependent work orders) collapses to 0. **Steps to reproduce:** 1. Plan a work order on a workcenter (start, end, expected duration). 2. Open it and change only the start date to a time that is not on a working-hours boundary. 3. The end date updates, but the expected duration is now wrong. **Expected behavior:** Changing the start date replans the work order: the duration is kept and the end date is recomputed from it. This is how 19.0 behaves and how dragging the pill in the gantt already behaves. **Cause of the issue:** Changing date_start triggers _onchange_date_start, which recomputes date_finished from start + duration via plan_hours. That cascades into _onchange_date_finished, which recomputes duration_expected from the dates via get_work_duration_data. Since the resource calendar refactor in 19.2, plan_hours and get_work_duration_data are no longer exact inverses around the work order's own planned slot, so the round trip drifts the duration. **Fix:** Only recompute the duration when the end date was edited on its own. When date_finished already matches the planned end for the current duration, it was merely derived from the start change, so the duration is kept. This keeps the duration authoritative when moving the work order while still recomputing it on a genuine end-date resize. opw-6231569 Forward-Port-Of: odoo/odoo#271508
This update fixes an issue where breaking a combo in the Point of Sale system didn't properly update the preparation display. The fix ensures that the preparation display is now notified when a combo is reorganized, preventing unnecessary kitchen tickets and streamlining the order preparation process. This improves efficiency and reduces potential errors.
Original PR description
Issue: Breaking a combo back into individual lines was not notifying the preparation display. Fix: breakCombo now go through sendOrderInPreparation (with byPassPrint) the preparation display is updated and no ticket is printed. To avoid triggering a sound and a kitchen ticket for a reorganization the kitchen already knows about, thread a `silent` context flag through sendOrderInPreparation down to _send_load_orders_message. 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