Friday, May 29, 2026
28 changes · saas-19.2
Enhancements to existing features
This update enhances the analytic reporting feature by adding a 'product category' field to the core accounting model. This allows users to group and analyze expenses by product category within their reports, providing more granular insights into spending patterns. It's an improvement to existing reporting capabilities.
Original PR description
Add the related (non-stored) 'product_category' field on the account.analytic.line model to make it available in the Analytic Reporting "Group By" task-6219418 Forward-Port-Of: odoo/odoo#266378
Resolved issues and error corrections
This update resolves a problem where the Canadian Localization module was missing essential tax group settings, preventing proper accounting configuration. The fix updates data files and runs a migration script to ensure all necessary tax and account information is correctly populated, improving tax reporting accuracy.
Original PR description
**Steps to reproduce:** * Install the *Canadian Localization* module (*l10n_ca*). * Go to *Accounting* module. * Navigate to *Configuration -> Settings*. * In the *Taxes Configuration* section, click on *Configure Tax Groups*. * Open the tax groups list view and review the available records. **Observed behavior:** * Default tax groups accounts are missing or not visible for taxes, leading to incomplete tax configuration. **Cause:** * The tax and account data files were missing required fields: * *tax_receivable_account_id* * *tax_payable_account_id* * *non_trade* (for accounts) * In *Accounts* , for some places *account_type* was missing * This resulted in improperly configured tax groups and accounts. **Fix:** * Updated CSV data files for tax groups. * Added the missing required fields for taxes and accounts. * Added a migration script to update existing records accordingly. opw-6069621
This update optimizes a key database query used to generate reconciliation reports. By correcting a wildcard issue in the query, we've significantly reduced the time it takes to process these reports, particularly when the database's data cache is not fully warmed up. This results in faster reporting and a better user experience.
Original PR description
The CTE `model_fees` is supposed to get the reconciliation models that match conditions that involves a join with the ir.model.data table. One of these conditions is filtering based on the `name`…
The CTE `model_fees` is supposed to get the reconciliation models that match conditions that involves a join with the ir.model.data table. One of these conditions is filtering based on the `name` field with an `LIKE` operator. On databases that has a GIST index on the field `name`, the planner will prefer to filter the records based using the GIST index and add the extra filters as a filtering criteria after the index condition if the index-condition wasn't possible to be switched to a range-query. The condition is supposed to be a prefix-matching, which can be evaluated directly by a B-TREE if the field had an index and the planner can convert the condition to a range-query. Apparently the `_` in `account_reco_models_fees_%%` was evaluated as a wild-card, making the condition a substring-matching rather than direct prefix-matching. In this PR, I have modified the condition to escape the '_' wildcards. The benchmark done below was on a database that has around **10^7** `ir.model.data` records and 1K `account.reconciliation.model` records. I have split the benchmark into two cases, a case where the buffer-pool of postgres warmed-up and a case where it is not. After Worst case -> https://explain.dalibo.com/plan/975geg1f1h109d5c Before Worst case -> https://explain.dalibo.com/plan/0ce9bf3g0ad8f98b After Best Case -> https://explain.dalibo.com/plan/1a77459dadb0gfc4 Definition of ir_model_data_name_idx2 -> CREATE INDEX ir_model_data_name_idx2 ON public.ir_model_data USING gist (name gist_trgm_ops) Definition of ir_model_data_module_name_uniq_index -> CREATE UNIQUE INDEX ir_model_data_module_name_uniq_index ON public.ir_model_data USING btree (module, name) | PostgreSQL Buffer Pool Status | Before | After | | :--- | :--- | :--- | | Not warmed up (Cold) | 11s | 130ms | | Warmed up (Hot) | 0.022ms | 0.097ms |
This update resolves a technical issue that prevented users from adding multiple loan lines to French company accounting records. The fix ensures that the system correctly handles date comparisons when creating and editing loan records, improving the user experience. This change is a critical fix for accurate financial reporting.
Original PR description
**Steps to reproduce:** - Install the `l10n_fr_account_loans` module and switch to a `FR Company`. - Navigate to Accounting > Accounting > Assets & Liabilities > Loans. - Create a new loan record. -…
**Steps to reproduce:** - Install the `l10n_fr_account_loans` module and switch to a `FR Company`. - Navigate to Accounting > Accounting > Assets & Liabilities > Loans. - Create a new loan record. - Click `Add a line`, set a `Date`, and `save` the record. - Click `Add a line` again. **Error:** `TypeError: '>' not supported between instances of 'datetime.date' and 'bool'` **Root Cause:** At [1], when adding a line after the record has already been saved with at least one existing line, the existing line has a valid `datetime.date` value for `l.date`, while the newly created unsaved line still has `line.date` set to `False`. This results in a comparison between a `datetime.date` object and a boolean value, causing an error. **Fix:** This commit prevents the errors when adding multiple lines after saving the record by applying a fix similar to [2]. [1]: https://github.com/odoo/enterprise/blob/54eef93f295eaebd98d24730d108b1203ca7b35a/l10n_fr_account_loans/models/account_loan_line.py#L21 [2]: https://github.com/odoo/enterprise/blob/54eef93f295eaebd98d24730d108b1203ca7b35a/account_loans/models/account_loan_line.py#L61-L63 opw-6244973
This update fixes several issues related to the Field Service module, including improved Gantt scheduling functionality, automated email reports for completed interventions, and streamlined customer access. These changes enhance the user experience and ensure timely communication for field service operations.
Original PR description
## [FIX] web_gantt,planning: apply hasGroup before compute params Before this commit, some actions like drag and drop gantt pills are blocked for planning manager instead of being allowed only for…
## [FIX] web_gantt,planning: apply hasGroup before compute params Before this commit, some actions like drag and drop gantt pills are blocked for planning manager instead of being allowed only for them. The reason is because the compute params is something made before checking if the user is a planning manager and so the system will consider the user is not a planning manager. The compute params is something made before because the methods are executed inside 2 distincts onWillStart hook and so OWL framework cannot know one hook depends on the other one. This commit creates a method `onWillStart` in the main gantt controller to be able to override it and be able to wait a rpc before processing the compute params. ## [FIX] planning_field_service_sale_timesheet: don't count unscheduled intervention This commit filters the interventions counted to display the field service stat button in the form view of Sale Order. Now the intervention unscheduled will no longer be counted and also the one linked to plannable SOL. ## [FIX] planning_field_service: send email to customer when intervention published Before this commit, the template "Field Service Scheduled" was unsused. This commit uses that template to send an email to the customer once the intervention is scheduled. ## [FIX] planning_field_service: send report when intervention completed and signed Before this commit, the customer signs the intervention completed and does not received any email with the intervention report. He has to create an account in the DB as portal user to be able to see his intervention or ask to contact person to send him the report by mail. This commit will automatically send the intervention report by mail to the customer once the intervention is completed and signed by the customer. ## [FIX] planning_field_service: fix label and record_name in email sent for Field service Before this commit, the button sent to the customer to see the intervention is `View Planning Slot` and the record name used inside the same email is the display name which is not useful for the customer. This commit changes the label of the button displayed to see `View Report` and change the record_name to show `Field Service - <intervention date>` as shown in the portal view. ## [FIX] planning_field_service: no login required to access to intervention Before this commit, the customer cannot access to the intervention without begin log in even if he has the access token. This commit changes the route access to let the user access to the intervention completed and he can also sign it. ## [FIX] planning: hide duplicated name field in kanban displayed in gantt This commit hides the duplicated name field displayed in the popover of the gantt view in the planning.slot model. ## [FIX] planning_field_service: rename module name This commit renames the module to call it `Field Service` instead of `Planning - Field Service`. ## [FIX] worksheet: only show property warning message in mobile ## [FIX] planning: define employee_public_ids field in planning.slot Before this commit, when a planning user goes to a shift he will see Assign to me button on a shift assigned to another human resource which is normally not allowed. The reason because the button is visible is because `employee_ids` field is always empty for users who are not HR user. This commit adds `employee_public_ids` field which is also a computed field non stored to get the employee for the user who is not a HR user. ## [FIX] planning_field_service: always compute break_time This commit removes the default value on break_time field to always trigger the compute of that field, the reason is because by default the allocated_hours computed when we create a shift, will not always cover the whole duration of the shift, the allocated hours of the shift is computed based on the working schedule of the shift and so the break_time field has to be computed afterwards to make sure the break time is correctly set instead of having 0 by default when we create a shift. task-6060493
This update corrects a bug where the default company scrap location was being used instead of the user-specified scrap location during scrap move confirmation. Previously, enabling location tracking in the warehouse caused the system to consistently use the company's scrap location. This fix ensures the user-selected scrap location is correctly applied, improving accuracy in scrap tracking.
Original PR description
**Issue** The scrap location provided by the user may be overridden while confirming a scrap move **Steps to reproduce** - In settings, enable the tracking of location in the warehouse - Have two…
**Issue** The scrap location provided by the user may be overridden while confirming a scrap move **Steps to reproduce** - In settings, enable the tracking of location in the warehouse - Have two location of type 'Inventory loss' - Create a scrap move and change the scrap location - confirm the move -> The scrapped move will be created using the scrap location already present before the user changes it **Cause** The regression has been introduce by this refactoring commit: https://github.com/odoo/odoo/commit/1c7d80a10b5d7db1c4163166bf52b3f3c77044ba While confirming the scrap move: https://github.com/odoo/odoo/blob/f68473898b97db55a1ef5bee1d4f7865fb6b6d8a/addons/stock/models/stock_move.py#L2726 https://github.com/odoo/odoo/blob/f68473898b97db55a1ef5bee1d4f7865fb6b6d8a/addons/stock/models/stock_move.py#L2731 It needs to access the `stock.move` record: https://github.com/odoo/odoo/blob/f68473898b97db55a1ef5bee1d4f7865fb6b6d8a/addons/stock/models/stock_move.py#L2133 Since this is the first access, it triggers the compute method of `location_dest_id`: https://github.com/odoo/odoo/blob/f68473898b97db55a1ef5bee1d4f7865fb6b6d8a/addons/stock/models/stock_move.py#L227-L228 Which sets it to the company's scrap location, regardless of the value provided by the user: https://github.com/odoo/odoo/blob/f68473898b97db55a1ef5bee1d4f7865fb6b6d8a/addons/stock/models/stock_move.py#L237-L238 This value is compute here: https://github.com/odoo/odoo/blob/f68473898b97db55a1ef5bee1d4f7865fb6b6d8a/addons/stock/models/res_company.py#L62-L65 This value is computed by taking the first scrap location found for this company opw-6125152
This update fixes an issue where the system wasn't accurately calculating the total value and average cost of stock when a warehouse location was archived. Previously, archived locations were excluded from these calculations, leading to potentially inaccurate inventory reporting. This change ensures that all stock locations, including archived ones, are properly accounted for when determining valuation figures.
Original PR description
When a receipt dest location or delivery source location get archived, the corresponding move may not be taken into account when computing the total_value / avg_cost at date. OPW-6099192 --- ### Test…
When a receipt dest location or delivery source location get archived, the corresponding move may not be taken into account when computing the total_value / avg_cost at date.
OPW-6099192
---
### Test result without fix
```
2026-04-23 06:30:34,016 10516 INFO oes_test_19 odoo.addons.stock_account.tests.test_stockvaluation: Starting TestStockValuation.test_archived_location_valuation ...
2026-04-23 06:30:34,255 10516 INFO oes_test_19 odoo.addons.stock_account.tests.test_stockvaluation: ======================================================================
2026-04-23 06:30:34,255 10516 ERROR oes_test_19 odoo.addons.stock_account.tests.test_stockvaluation: FAIL: TestStockValuation.test_archived_location_valuation
Traceback (most recent call last):
File "/home/odoo/Odoo/src/19.0/odoo/addons/stock_account/tests/test_stockvaluation.py", line 3326, in test_archived_location_valuation
self.assertEqual(self.product_avco.with_context(to_date=date_1).avg_cost, 10)
AssertionError: 20.0 != 10
```
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#263354
Forward-Port-Of: odoo/odoo#260922This update replaces the older PostgreSQL 12 version in the Windows installer with the more current and supported PostgreSQL 16. This change improves security and ensures compatibility with future Odoo releases. Additionally, the installer now uses a dedicated Odoo user for the database connection, enhancing security.
Original PR description
The Windows installer installs PostgreSQL 12. That version was chosen for its small size, but now in 2026 the size doesn't matter as much anymore. Also, version 12 is no longer supported, so it's time to bump to version 16. While at it, this commit adds an Odoo user for the PostgreSQL connection instead of using the superuser. Forward-Port-Of: odoo/odoo#266059 Forward-Port-Of: odoo/odoo#265134
This update fixes an issue where employees on flexible schedules were incorrectly flagged for overtime. The change adjusts how overtime rules calculate hours worked, now accurately considering the employee's flexible calendar hours and any scheduled leaves. This ensures accurate overtime reporting for employees with varied work arrangements.
Original PR description
**Steps to reproduce:** - Create a flexible 32h/week calendar (8h/day, 4 days) - Assign it to an employee with the Default Ruleset - Create attendances: 8h on Monday, Tuesday, Friday, and Saturday…
**Steps to reproduce:** - Create a flexible 32h/week calendar (8h/day, 4 days) - Assign it to an employee with the Default Ruleset - Create attendances: 8h on Monday, Tuesday, Friday, and Saturday (32h total, matching the weekly budget) - Select the list view and go to the month of the attendances - Employee shows 16:00 Worked Extra Hours (8h on Fri + 8h on Sat) **Cause:** `resource.calendar._attendance_intervals_batch` generates work intervals for flexible calendars by front loading the weekly hour budget onto the first days of the week (Mon 8h, Tue 8h, Wed 8h, Thu 8h for a 32h calendar), But days beyond the budget (Fri, Sat, Sun) get zero hours. The two overtime rule paths relies on these synthetic intervals: 1) The quantity rule: `_get_daterange_overtime_undertime_intervals_for_quantity_rule()` computed `expected_duration` by intersecting the synthetic schedule with each day. For Fri/Sat the intersection was empty (expected = 0) -> all worked hours counted as overtime. https://github.com/odoo/odoo/blob/b31fd6816521ff43fb3a9ec37e79e9a9d628d357/addons/hr_attendance/models/hr_attendance_overtime_rule.py#L302-L304 **update** solved by: https://github.com/odoo/odoo/pull/265120/changes/94d4bfffa053cd78ce07ff07ab14b53e8d931053 2) The timing rule: `_get_rules_intervals_by_timing_type()` derived "work_days" from the synthetic schedule and inverted them to get "non_work_days". (Fri, Sat, Sun) were classified as non-working days, therefore, any attendance on those days triggered full overtime. https://github.com/odoo/odoo/blob/b31fd6816521ff43fb3a9ec37e79e9a9d628d357/addons/hr_attendance/models/hr_attendance_overtime_rule.py#L421-L433 **Solution:** For flexible calendars in the overtime rule consumer: - Quantity rules: read expected hours directly from the calendar's `hours_per_day` / `hours_per_week` instead of the synthetic schedule intervals, subtracting any leaves in the period - Timing rules: treat the entire attendance date range (minus leaves) as potential work days, so that `non_work_days` is empty for flexible employees (they can work any day of the week) opw-6067063 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#263840
This update fixes a bug that prevented purchase matching from working correctly when vendor bills only used a description for identification, rather than a product. The change ensures that purchase matching processes vendor bills accurately, regardless of whether a product is specified, improving data consistency and reducing potential errors.
Original PR description
### Issue before this commit: Opening the Purchase Matching wizard would crash if the vendor bill contained lines with a description and a Unit of Measure (UoM), but no product selected. ### Steps to…
### Issue before this commit: Opening the Purchase Matching wizard would crash if the vendor bill contained lines with a description and a Unit of Measure (UoM), but no product selected. ### Steps to reproduce the issue: 1. Enable Units of Measure in Settings 2. Create and confirm a Vendor Bill setting a description and a UoM, but leave the Product field empty. 3. Click on "Purchase matching" smart button 4. The system throws a traceback with the error: "The unit of measure Unit defined on the order line doesn't belong to the same category as the unit of measure False defined on the product." ### Cause of the issue: In the purchase.bill.line.match model, the field product_uom_qty was computed by calling _compute_quantity using line.product_uom_id. Since product_uom_id is a related field on product_id.uom_id, it returns False when no product is set. The UoM conversion logic cannot handle a False destination category, leading to the crash. ### Reason to introduce the fix: Make purchase matching robust when imported vendor bills contain lines identified only by their description and not by a product. Note that for `purchase.bill.line.match` corresponding to an account.move.line but not related to any product, the `product_uom_qty` should match the quantity of the `aml_id` instead of attempting a UoM conversion based on a missing product UoM for the behavior to be consistent with the inverse method: https://github.com/odoo/odoo/blob/59d6232979b8499fde6cb700df1870e2e38d0d3e/addons/purchase/models/purchase_bill_line_match.py#L45-L54 opw-5911526 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#266269 Forward-Port-Of: odoo/odoo#257827
This update fixes a previous issue where payment transaction details weren't consistently saved in Odoo, particularly when payments were received via polling instead of webhooks. The fix ensures all relevant payment information, including card details, is now captured and stored correctly, improving the reliability of payment processing for Viva Wallet transactions.
Original PR description
After odoo/odoo#236454, a bug was introduced where the transaction details would only be saved if the payment was resolved via webhook, not via polling. This commit fixes the issue by using the same field names in the webhook payload as is received from the polling endpoint. In addition, the card number and card brand fields are now saved too. opw-6244960 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#266788 Forward-Port-Of: odoo/odoo#266629
This update resolves a problem where the system incorrectly identified employees when using Point of Sale (POS) with multiple companies. The issue stemmed from a change in how downpayment products were set, leading to conflicting company data. The fix ensures employees are correctly associated with the appropriate company during POS operations.
Original PR description
Step to reproduce: - install point_of_sale with demo - have two company and 1 pos in each company - install pos_hr - install pos_sale Observation: - we get a traceback ``` File…
Step to reproduce:
- install point_of_sale with demo
- have two company and 1 pos in each company
- install pos_hr
- install pos_sale
Observation:
- we get a traceback
```
File "/src/saas-19.2/odoo/orm/fields_misc.py", line 115, in __get__
raise ValueError("Expected singleton: %s" % record) from None
ValueError: Expected singleton: res.company(7, 8)
```
- and pos_sale is not installed
Cause:
- when installing `pos_sale` `_ensure_downpayment_product` is called.
- this sets downpayment product on every `pos.config` record.
- this triggers write call from pos_hr, which tries to identify users for pos
- this uses `with_company(self.company)` <----- actual issue
- here self has two config, each from different company, hence `with_company`
raises singleton error
why not in earlier verison:
- before commit [1] we only set downpayment product on only pos_config_main
- now we set it on every pos.config, so now self contain multiple records
[1] https://github.com/odoo/odoo/commit/a3f9114434c7cab8757b0283698662792e6b7946
Fix:
- compute users by first grouping them over company_id
related pr: https://github.com/odoo/odoo/pull/254026
opw-6217135
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis update fixes an issue where task defaults were lost when navigating between weeks in the planning calendar view. Now, when switching to the next week using the arrows, the previously selected task is automatically preserved, ensuring a smoother scheduling experience. This improves usability and reduces the need for manual task selection.
Original PR description
Issue: ---------------------------------------- The default values aren't kept when using the previous/next arrows in planning calendar view. Steps to reproduce:…
Issue: ---------------------------------------- The default values aren't kept when using the previous/next arrows in planning calendar view. Steps to reproduce: ---------------------------------------- - Go on a Project task - Click the "To Schedule" button - Switch to calendar view - If we create now, the new slot will have the task as default value - Click the arrow to switch to next week - If we create there will be no default values Cause: ---------------------------------------- Since 7b844902e5c3a7aeedda6cc2be61366caad2d144 the context is lost when using the arrows. When switching to calendar view `load()` is called with the context in the params: https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/web/static/src/model/model.js#L163-L164 But when using the arrows, it is called with only a date: https://github.com/odoo/odoo/blob/786c373d5ac8afdfb79eb7a7d69c5eb83b919625/addons/web/static/src/views/calendar/calendar_controller.js#L426 So `...params.context,` is empty, and the context is only `hide_planned_dates: true,`. Solution: ---------------------------------------- If no context is specified in params, we use the one in `this.meta` to allow changing the context by giving it in the params but keeping the previous context when it's not given. opw-6211055
This update corrects a bug where duplicated Manufacturing Orders created with the 'Replenish on Order' feature were incorrectly linked to the original Sales Order. The fix prevents the duplication of the Sales Order ID during Manufacturing Order creation, ensuring that duplicated orders are independent and don't show incorrect links.
Original PR description
Version: --------- - 19.0+ Steps to reproduce: -------------------- 1.Install modules `sale_management`, `purchase`, and `mrp`. 2. Go to Settings and enable the MTO (Replenish on Order) route. 3.…
Version:
---------
- 19.0+
Steps to reproduce:
--------------------
1.Install modules `sale_management`, `purchase`, and `mrp`.
2. Go to Settings and enable the MTO (Replenish on Order) route.
3. Create a product with:
i. Configure a Vendor under the Purchase tab.
ii. Set the route to MTO.
iii. Create a Bill of Materials for the product.
5. Create a Sale Order with the configured product and confirm it.
6. Open the generated Manufacturing Order.
7. Duplicate the Manufacturing Order.
Issue:
------
* The duplicated Manufacturing Order shows a smart button
linked with the Sale Order, which is incorrect.
Root Cause:
------------
This issue is coming form this [Commit](https://github.com/odoo/odoo/commit/2713876dbc70d3984e584a9037a2206dcda4e84a#diff-2b9de2e50ff5e1dc0362b825bac2b07623770fb3275b3257ef972f255f3ccb8b)
* During Sale Order confirmation, the flow
`action_confirm` → `_action_confirm` → `_action_launch_stock_rule`
→ `run` → `_run_pull` → `_action_confirm` calls
`_prepare_procurement_values`.
which gather all procurement values.
In sale_stock, the super call adds `sale_line_id` to the
generated Manufacturing Order when using MTO:
https://github.com/odoo/odoo/blob/0352c5e8543b75083cf555c3d5b4f164f949b465/addons/sale_stock/models/stock.py#L138-L140
* So, when the Sale Order is confirmed, the generated
Manufacturing Order contains sale_line_id, and when this
Manufacturing Order is duplicated, the sale_line_id is also
copied.
* In sale_mrp, the smart button uses sale_line_id to compute
the linked Sale Order count:
https://github.com/odoo/odoo/blob/0352c5e8543b75083cf555c3d5b4f164f949b465/addons/sale_mrp/models/mrp_production.py#L19
Solution:
-----------
* Prevent copying of sale_line_id when duplicating a
Manufacturing Order, ensuring duplicated records are not
linked to any Sale Order.
---
opw-6113149
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#259128This update resolves a crash that occurred when sending final invoices to ZATCA for sales orders with multiple down-payment references. The fix prevents a software error caused by attempting to process both reversed and active down-payment invoices simultaneously. It now prioritizes non-reversed down payments, ensuring accurate ZATCA reporting.
Original PR description
Sending the final invoice of a sale order to ZATCA crashed with `ValueError: Expected singleton: account.move(a, b)` when the sale order had multiple down-payment references. Steps to reproduce: 1.…
Sending the final invoice of a sale order to ZATCA crashed with `ValueError: Expected singleton: account.move(a, b)` when the sale order had multiple down-payment references. Steps to reproduce: 1. Configure a SA company and setup ZATCA 2. Create a sale order and confirm it 3. Deliver the product line. 3. From the sale order, create a down-payment invoice (fixed amount, e.g. 115) and post it (DP1). 4. On DP1, click "Credit Note" and choose "Full refund and new draft invoice"; validate. DP1 becomes `reversed` and a new draft down-payment DP2 is created. Post DP2. 5. From the sale order, create the final regular invoice and post it. 6. Send the final invoice to ZATCA (or generate its XML) -> `ValueError: Expected singleton: account.move(a, b)`. Root cause: _l10n_sa_get_line_prepayment_vals looks up the related down-payment move through the down-payment sale order line shared with the product line. The filter matched any out_invoice with _is_downpayment() == True, so the reversed DP1 and the active DP2 both ended up in the recordset, and reading .name raised the singleton error. Prefer non-reversed down-payment moves when available, but fall back to reversed ones if no alternative exists (e.g. when generating a credit note of the final invoice after the original down-payment was itself reversed). opw-6116265 Forward-Port-Of: odoo/odoo#264435 Forward-Port-Of: odoo/odoo#259384
This pull request optimizes the performance of the account report sheet by streamlining CSS styling and reducing unnecessary DOM calculations. By using CSS variables and more direct selectors, the changes minimize visual rendering impacts, particularly on large tables, leading to a smoother user experience. This resolves performance bottlenecks related to hover effects and table styling.
Original PR description
Forward-Port-Of: odoo/enterprise#118674 Forward-Port-Of: odoo/enterprise#118490
This update fixes an issue where overtime calculations were inaccurate due to overlapping rules. The fix ensures that original overtime intervals are preserved, allowing for correct overlap resolution and accurate overtime generation. This improves the reliability of overtime tracking.
Original PR description
**Issue:** When computing timing overtime rules, overlapping intervals from different rules were accidentally merged before the overlap resolution step. As a result, the overlap generation logic no longer had access to the original rule boundaries and could not correctly create the final overtime intervals. **Solution:** Keep the original intervals from each rule untouched until the final overlap resolution step so overlaps can be properly sliced and resolved when generating the final overtime intervals. Task: 6168492 Forward-Port-Of: odoo/odoo#266096
This fix addresses a situation where importing a product with a changed subscription type could bypass a necessary warning. Previously, the system processed the import without alerting the user, leading to incorrect subscription settings. Now, a warning is raised to prevent accidental changes to products that have already been sold as subscriptions.
Original PR description
__ ## Short functional explanation of the error When we have a subscription product that has already been sold. If we try to import a product with the same ID but where we change the subscription…
__ ## Short functional explanation of the error When we have a subscription product that has already been sold. If we try to import a product with the same ID but where we change the subscription type of the product, the import is executed without issue. However, this leads to undesired behavior: when we go to the product page and try to manually change the subscription type (set it back to subscription), the change is not applied as a warning is raised. ## Reproduction Steps Make sure you have debug mode enabled. 1. Create a product, and check the Subscription box. 2. Click on Orders and create a Quotation with this product, then confirm. 3. Go to Products > Products. Select the list view and search for the product you just created. Select it, and click Actions > Export. 4. Check the import compatible field. Select the fields to export: name, id and recurring_invoice. Upon exporting, a file is downloaded. 5. Access that file and change the recurring_invoice to FAUX or FALSE if your computer is in English. Save the changes. 6. Unselect the product and click on the cog, top right > Import. Click on Upload Data File and select the file that you have downloaded upon exporting, then import. ### Expected behavior A user warning is raised: we shouldn't be able to change the subscription type of the product when it has already been sold. ### Unexpected behavior The import is processed normally. Then, when we access the product page, and try to check the Subscriptions box again, a warning is raised. ## Origin of the issue Nothing prevents the import from occurring in that case. __ opw-6143789 Forward-Port-Of: odoo/enterprise#117318 Forward-Port-Of: odoo/enterprise#115046
This update fixes an issue where the delivered quantity for dropship products in field service sales orders was incorrectly displayed as '1' before order confirmation. The fix ensures that the delivered quantity accurately reflects stock pickings and is calculated correctly when dropshipping is enabled. This improves the accuracy of sales order reporting.
Original PR description
### Steps to reproduce: - In the settings enable dropshipping - Create a storable product P, enable the dropshipping and set a vendor - Create and confirm a sale order for a field service - Open the…
### Steps to reproduce: - In the settings enable dropshipping - Create a storable product P, enable the dropshipping and set a vendor - Create and confirm a sale order for a field service - Open the related task > Products > Add 1 unit of P - Go back to the sale order > an RFQ has been created #### > The delivered quantity of P is set to 1 ### Cause of the issue: Since 2361368acfe7fecbffde2ca26392eb89aecdc9e1 the `_inverse_fsm_quantity` method manually adapts the delivered quantity based on the fact that the `product.service_type` is `manual` rather than the `qty_delivered_method` of the line or future line is. In particular, because these lines: https://github.com/odoo/enterprise/blob/8f4fe902cb71c49bdb3caf9915f9a5abfe6f237f/industry_fsm_sale/models/product_product.py#L82-L83 provide a value of the `qty_delivered` to the created purchase order line and since the `qty_delivered_method` is a precomputed field: https://github.com/odoo/odoo/blob/fdfd9851393ff82a265997478886bcad6da357d0/addons/sale/models/sale_order_line.py#L225-L237 The fact that the purchase order line will be created with a `stock_move` `qty_delivered_method` and that the generated PO does not generate any move prior to confirmation will not trigger the dependency of the `qty_delivered` to retrigger a computation of the `delivered_qty` of the product which is suppose to be based on stock pickings: https://github.com/odoo/odoo/blob/fdfd9851393ff82a265997478886bcad6da357d0/addons/sale/models/sale_order_line.py#L871-L876 https://github.com/odoo/odoo/blob/fdfd9851393ff82a265997478886bcad6da357d0/addons/sale_stock/models/sale_order_line.py#L193-L198 Leaving the created sol with a delivered quantity of 1 prior to confirmation of the PO (which will generate move_ids related to the sol and trigger the compute). Fix: The changes of 2361368acfe7fecbffde2ca26392eb89aecdc9e1 regarding the `_inverse_fsm_quantity` appears unjustified with respect to the purpose of the fix. In addition, the `qty_delivered` and changes are already expected to be properly computed when the `qty_delivered_method` is not manual, particularly since the '`manual'` `service_type` is actually the default `service_type` corresponding to any 'consu' product and looks unrelated by any mean to the `delivered_qty` computation: https://github.com/odoo/odoo/blob/fdfd9851393ff82a265997478886bcad6da357d0/addons/sale/models/product_template.py#L165-L167 opw-6104326 Forward-Port-Of: odoo/enterprise#117727 Forward-Port-Of: odoo/enterprise#115760
This update corrects a bug in the generation of FA(3) XML files for Polish VAT invoices. Previously, the system incorrectly omitted a key date field (`P_6`) when the invoice delivery date matched the invoice issue date. This change ensures accurate compliance with Polish tax regulations, preventing potential errors and delays in VAT reporting.
Original PR description
**Steps to reproduce** 1. Create a customer invoice with Invoice Date `2025-05-27` and accounting Date `2026-05-04`. 2. On the *Other Info* tab, set the Delivery Date to `2026-05-04` and post the…
**Steps to reproduce** 1. Create a customer invoice with Invoice Date `2025-05-27` and accounting Date `2026-05-04`. 2. On the *Other Info* tab, set the Delivery Date to `2026-05-04` and post the invoice. 3. Generate the FA(3) XML. **Issue** `P_6` is omitted from the payload even though the delivery date differs from the invoice issue date. The FA(3) information sheet (Warsaw, September 2025, binding from 1 February 2026) defines `P_6` as *"the date of delivery [...] if such date is specified and differs from the date of issue of the invoice"*, where the date of issue is `P_1` (Art. 106e sec. 1 item 1 of the VAT Act). In Odoo `P_1` maps to `invoice_date`, but the template at https://github.com/odoo/odoo/blob/4890b8021af2a5c025944220043d295bb7bbbb9b/addons/l10n_pl_edi/data/fa3_template.xml#L132 compares `delivery_date` against `invoice.date`, the accounting/entry date. When the invoice is posted on the delivery day the accounting date equals the delivery date, the guard evaluates to false, and `P_6` is wrongly dropped. Comparing against `invoice.invoice_date` aligns the guard with `P_1` as the spec requires. Ticket [link](https://www.odoo.com/odoo/project.task/6211119) opw-6211119 Forward-Port-Of: odoo/odoo#266667
This update resolves an issue where reimbursed sales orders (paid back via credit notes) continued to incorrectly impact customer credit limits. The fix adds a 'closed invoicing' flag to sale orders, allowing them to be excluded from credit limit calculations once invoicing is finalized. This ensures more accurate credit limit tracking for customers.
Original PR description
### Issue: When a Sale Order is delivered but later reimbursed (e.g., via a credit note without a return), it is still considered as to invoice As a result, it continues to impact the partner’s…
### Issue: When a Sale Order is delivered but later reimbursed (e.g., via a credit note without a return), it is still considered as to invoice As a result, it continues to impact the partner’s credit limit ### Cause: Sale Orders remain included in the `credit_to_invoice` computation even when invoicing is manually considered finished There was no way to exclude such orders from the credit limit calculation ### Fix: Use the `invoicing_closed` field to mark Sale Orders as fully processed When set, the order is excluded from the credit limit computation ### Steps to reproduce: - Install `sale_management` - In Settings, enable Sales Credit Limit (default: 3000) - Create, confirm, and deliver a Sale Order for a new customer (any product, price: 2000) - Duplicate the Sale Order → a credit warning is displayed - Go back to the original Sale Order and use Close Invoicing from the gear menu - Return to the duplicated Sale Order The warning disappears as the closed order is no longer included in the credit computation ### Note: For a complete business scenario, refer to the steps described in the related ticket opw-6013369 Forward-Port-Of: odoo/odoo#262720
This update enhances Odoo's ability to receive Peppol invoices, addressing a previous limitation. Now, users can fully receive invoices with additional Peppol fields created in Studio, ensuring compliance with industry standards. This improves data accuracy and streamlines invoice processing.
Original PR description
Currently, Odoo allows sending invoices with additional Peppol fields, but didn't support the receiving. This limitation prevents users from receiving fully compliant invoices. After this commit, users will be able to receive these extra fields if they already created them using Studio. task-6033667 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#262065
This update corrects a bug in stock valuation reports that previously displayed incorrect unit costs and values for AVCO products with fully consumed lots. The fix ensures that inventory reports accurately reflect stock levels at a specific date, regardless of current stock levels. This improves the reliability of financial reporting.
Original PR description
When using the stock valuation report with 'inventory at date', lot valuated AVCO products whose lots had been fully consumed were showing zero unit cost and total value, despite having correct quantities at given dates.
The root cause was a ('product_qty', '!=', 0) domain filter in product.product._compute_value that evaluates product_qty at the current date, not at to_date. Lots fully consumed after were excluded from the recordset as they have no quantities left.
After this fix: adding the 'not at_date' will make sure that when fetching the inventory at date, we do so regardless of their current stock level.
OPW: 6115200
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#262111
Forward-Port-Of: odoo/odoo#262008This update ensures that when an analytic plan with mandatory 'Expense' domains is set up, users must now correctly provide an analytic distribution when posting expenses. Previously, expenses could be posted without this distribution, leading to potential accounting discrepancies. This change improves data accuracy and compliance.
Original PR description
When posting expenses, if the expense domain is set as mandatory in any of the analytic plans, users can still post expenses without entering an analytic distribution. Steps to reproduce: 1. Create an analytic plan with the "Expense" domain and set it as mandatory. 2. Create a new expense and submit it. 3. Don't enter any analytic distribution. 4. Post Journal Entries for the expense. 5. Notice how the expense is posted without any error message. Ticket [link](https://www.odoo.com/odoo/project.task/6187340) opw-6187340 Forward-Port-Of: odoo/odoo#266399
This update resolves an issue where Odoo would crash when a customer canceled a Redsys payment and returned to the system. Previously, the system didn't handle missing payment details correctly, leading to an error. Now, Odoo gracefully handles payment cancellations, ensuring a smoother customer experience.
Original PR description
Description of the issue/feature this PR addresses: Prevent an internal server error when a customer cancels a Redsys payment and returns to Odoo. Current behavior before PR: When the customer…
Description of the issue/feature this PR addresses: Prevent an internal server error when a customer cancels a Redsys payment and returns to Odoo. Current behavior before PR: When the customer cancels the payment from the Redsys checkout page, Redsys redirects back to Odoo without the `Ds_MerchantParameters` parameter. The payment flow assumes the parameter is always present and tries to decode it unconditionally, causing an internal server error. Desired behavior after PR is merged: Odoo gracefully handles payment cancellations when `Ds_MerchantParameters` is missing from the callback parameters. The customer is redirected correctly without triggering a server error. Steps to reproduce: 1. Install the Redsys payment provider. 2. Configure a test environment. 3. Create a sales order or invoice. 4. Start the payment process. 5. Cancel the payment from the Redsys checkout page. 6. Return to Odoo. 7. Observe the internal server error caused by the missing `Ds_MerchantParameters` parameter. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265655