Wednesday, January 21, 2026
18 changes · saas-19.1
Resolved issues and error corrections
This update fixes an error in the Point of Sale order report that incorrectly calculated margins for refunded orders. The fix ensures that refunds are properly accounted for, resulting in accurate margin figures displayed in the report. An app update is required to implement this change.
Original PR description
Step To Reproduce: - have a product with cost price - settle a order in pos with that product and refund it - go to reporting > orders > pivot view - check margin for that refund order Observation: -…
Step To Reproduce: - have a product with cost price - settle a order in pos with that product and refund it - go to reporting > orders > pivot view - check margin for that refund order Observation: - the margin is calculated wrong, as we do not consider order sign - as `margin = price_subtotal - total_cost` - so with price_subtotal `200` and total_cost `-100` margin becomes 300 Fix: - consider order sign i.e. -ve for refund order else +ve for `price_subtotal` - so with price_subtotal `-200` and total_cost `-100` margin becomes -100 **Before** <img width="317" alt="image" src="https://github.com/user-attachments/assets/9e23bc1c-363a-44dd-83c0-da478d9c73d0" /> **After:** <img width="343" alt="image" src="https://github.com/user-attachments/assets/56027cb4-a6c2-4b73-8db8-393e5af0b057" /> Note: for this to be applied, app update is needed opw-5418964 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#241870
This update resolves an issue where the POS system in Ecuador would crash when a customer was removed from the partner list after selecting 'Consumidor Final'. The fix ensures a customer is always selected, either a specific customer or 'Consumidor Final', improving stability and compliance with Ecuadorian tax regulations.
Original PR description
Step to reproduce: - install `l10n_ec_edi_pos` - open pos - ensure "Consumidor Final" is selected as partner - open partner list and deselect the partner Observation: - we get a traceback Cause: - we try to set a partner, without proper checks - Also, in the Ecuadorian localization there should always be a customer selected Fix: - rewrote `selectPartner` function to allow following things for EC localization 1. ensure a customer is always selected, a specific one or "consumidor final" 2. when refunding with "consumidor final" customer, changing partner is allowed opw-5350570 Forward-Port-Of: odoo/enterprise#104049 Forward-Port-Of: odoo/enterprise#102221
This update ensures that eWaybill invoices for Indian exports accurately reflect reverse charge GST amounts. Previously, these amounts were missing, causing discrepancies between Odoo and the government's eWaybill system. This fix aligns the eWaybill data with the correct values, simplifying compliance and avoiding potential issues with tax authorities.
Original PR description
For export invoices, the total invoice value in the eWaybill JSON did not include reverse charge amounts for GST, leading to a mismatch with the value shown in Odoo and the eWaybill generated by the Indian government system. This commit adjusts the JSON computation to include the reverse charge amounts in the total invoice value for exports, aligning it with the government-generated eWaybill, while preserving the existing reverse charge flow. task-5068199 Forward-Port-Of: odoo/odoo#243802 Forward-Port-Of: odoo/odoo#241852
This update ensures that vendor bills with slightly different VAT number formats (with or without dots) are correctly linked to the same contact in Odoo. Previously, variations in VAT number formatting caused duplicate contact creation, leading to data inconsistencies. This change improves data accuracy and simplifies vendor management.
Original PR description
Description of the issue/feature this PR addresses: Odoo can create two contacts for the same VAT number Current behavior before PR: If you have two incoming vendor bills (over a period of time)…
Description of the issue/feature this PR addresses: Odoo can create two contacts for the same VAT number Current behavior before PR: If you have two incoming vendor bills (over a period of time) where the first bill has these details: - VAT number: `BE0477472701` - Name: `Odoo` And the second bill (e.g three months later) has these details: - VAT number: `BE0477.472.701` - Name: `Odoo S.A` Odoo will do something interesting and will create a second new contact. The reason is because the fallback on `name` from `res.partner` fails (since "Odoo S.A" is not equal to "Odoo". However, the `vat` number matching also fails! Since the VAT number "BE0477.472.701" is not identical to "BE0477472701". Throughout Odoo however VAT numbers are parsed and stored without dots in it. The function `_retrieve_partner_with_vat` however is an exception because the `vat` number here is sanitized for spaces but not for dots. Because of the combination of no exact match on neither `name` nor `vat` it now creates a second contact although the VAT number is technically the same. Desired behavior after PR is merged: Both an incoming vendor bill with `0477.472.701` and `0477472701` match to the same contact even if there are dots in it and if the name of the company is different. P.S: please find two sample XML's here: [sample_odoo_sa_bill.xml](https://github.com/user-attachments/files/24718225/sample_odoo_sa_bill.xml) [sample_odoo_bill.xml](https://github.com/user-attachments/files/24718226/sample_odoo_bill.xml) If you upload both back to back on a default V19 you will see two contacts. After this code change you will only see one contact where both bills are mapped to the same contacts. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#244572
This update resolves an issue where government entities using TAN instead of PAN for their GSTINs were incorrectly flagged with a validation error. The fix adjusts the system to properly handle GSTINs based on TAN, ensuring accurate partner data creation for these important customers. This improves the usability of the system for government clients.
Original PR description
### Issue: When using a GSTIN belonging to a government institution, saving the partner raises a ValidationError This happens because these entities often use a TAN (Tax Deduction and Collection…
### Issue: When using a GSTIN belonging to a government institution, saving the partner raises a ValidationError This happens because these entities often use a TAN (Tax Deduction and Collection Account Number) instead of a PAN as the base for their GSTIN ### Cause: In 19.0, PAN handling was refactored using the new `pan_entity` mechanism With this change, PAN values are validated through `_check_pan_name()`, which incorrectly raises a `ValidationError` for GSTINs that rely on a TAN instead of a PAN: `The entered PAN seems invalid. Please enter a valid PAN.` The PAN entity shouldn't be created for non PAN number ### Steps to reproduce: - Install `l10n_in` and `contacts`, then switch to IN Company - Create a new contact with GSTIN: `07DELN10357E1DH` - Save and the Error is raised ### Notes: At the same time, we'll set the TAN if the GSTIN is based on it The documentation for the TAN structure: https://incometaxindia.gov.in/tutorials/23.%20tan.pdf opw-5461356 Forward-Port-Of: odoo/odoo#243737
This update resolves a bug where changing an inactive currency on invoices and bills caused display errors and crashes in the invoice/bill list views. The fix ensures the front-end correctly receives and uses currency data, preventing these issues and improving the user experience when working with multiple currencies.
Original PR description
In the form view of invoices and bills, if the currency is changed to an inactive one, an option to activate it from the form view was available, but when the button is pressed the front-end doesn't receive the new data related to the currency which resulted in unexpected errors when trying to view the invoice/bill or the list of invoices/bills task-5412003
This update resolves an issue where the partner ID wasn't correctly passed through stock move processes, particularly in multi-step delivery scenarios. The fix harmonizes how partner information is set within procurement records, ensuring accurate customer association for shipments. This prevents incorrect customer assignments during order fulfillment.
Original PR description
*mrp{,_subcontracting_dropshipping}, point_of_sale, sale_purchase, {purchase_,sale_,}stock ### Issue: The partner_id (contact field) of stock move is no longer propagated in pull chain since the…
*mrp{,_subcontracting_dropshipping}, point_of_sale, sale_purchase, {purchase_,sale_,}stock
### Issue:
The partner_id (contact field) of stock move is no longer propagated in pull chain since the procurement/reference refactoring of 19.0 see 2713876dbc70d3984e584a9037a2206dcda4e84a
#### Steps to reproduce:
- In the settings enable Multi-Steps routes
- Inventory > Configuration > Warehouse Management > Warehouses
- Set your warehouse in two step deliveries
- Modify the routes to have two pull rules: Stock -> Out -> Customer
- Create and confirm an SO, 1 unit of a storable product for a customer
#### > While the customer is set on the ship move and picking it is not on the pick move and picking.
### Cause of the issue:
Due to the configuration, the ship move is created by the `action_launch_stock_rule` and linked to the customer via the procurement created from the sale order line:
https://github.com/odoo/odoo/blob/4466a2684fd36ef3c9e1e7f7437ae48ff51f1941/addons/sale_stock/models/sale_order_line.py#L295 Then, the confirmation of the ship move generates a second procurement for the pick move creation. Prior to 19.0, the partner_id of this second procurement was set to the customer via the procurement group: https://github.com/odoo/odoo/blob/712cd806c38e193acdb966e4d3b339ab780f158e/addons/stock/models/stock_rule.py#L333 However, since procurement groups have been removed by the reference refactor 2713876dbc70d3984e584a9037a2206dcda4e84a, the partner id is now expected to be set from the procurement values:
https://github.com/odoo/odoo/blob/4466a2684fd36ef3c9e1e7f7437ae48ff51f1941/addons/stock/models/stock_rule.py#L332 As it is not set by any mean in this procurement values it will therefore not be propagated.
### Additional changes:
1. The `partner_id` of the procurement values needs to be harmonized are some methods set a recordset and others a record id:
https://github.com/odoo/odoo/blob/4466a2684fd36ef3c9e1e7f7437ae48ff51f1941/addons/point_of_sale/models/pos_order.py#L1707
https://github.com/odoo/odoo/blob/4466a2684fd36ef3c9e1e7f7437ae48ff51f1941/addons/mrp_subcontracting_dropshipping/models/stock_orderpoint.py#L10-L13
https://github.com/odoo/odoo/blob/4466a2684fd36ef3c9e1e7f7437ae48ff51f1941/addons/sale_stock/models/sale_order_line.py#L295
The correct behavior is to set an id since the `partner_id` value of the procurement group is used in the `_get_stock_move_values` and written in its "raw state" as the `partner_id` values for the stock move for creation (when sale_stock is installed):
https://github.com/odoo/odoo/blob/4466a2684fd36ef3c9e1e7f7437ae48ff51f1941/addons/sale_stock/models/stock.py#L171-L174
https://github.com/odoo/odoo/blob/4466a2684fd36ef3c9e1e7f7437ae48ff51f1941/addons/stock/models/stock_rule.py#L378-L381
2. The `partner` key of the procurement values is set by to `partner_id` in every overrides but since 2713876dbc70d3984e584a9037a2206dcda4e84 was incorrectly cahnged to `partner`:
https://github.com/odoo/odoo/blob/4466a2684fd36ef3c9e1e7f7437ae48ff51f1941/addons/stock/models/stock_rule.py#L332
We change back this key to the expected `partner_id` and revert the associated pos fix 203f807a2b764821ec4673515dd29f392ec37b3a using the changed `_get_partner_id` method.
3. In certain use cases, such as inter-warehouse transfer the the `partner_id` should not be propagated by the pull chain as it is expected to be set by the `_get_stock_move_values`:
https://github.com/odoo/odoo/blob/df01277bc053218dda6157f2f0657432e91e1d58/addons/stock/models/stock_rule.py#L339-L346
4. Since the `partner_id` is used to set the `dest_address_id` here:
https://github.com/odoo/odoo/blob/92486bab9b73f4370629452c454c25371d5063ac/addons/purchase_stock/models/stock_rule.py#L350
But is suppose to be reset for non dropshipping use case:
https://github.com/odoo/odoo/blob/df01277bc053218dda6157f2f0657432e91e1d58/addons/purchase_stock/models/purchase_order.py#L80-L82
We need to modify the fix of 3fb81df557553d471ff72998200097b3a0ea666f in order for the value set by th epartner_id to be reset in case we are not in a dropshipping use case.
Similarly, we should only add the `partner_id` of the procurement value as a possible `dest_address_id` in the dropship use case:
https://github.com/odoo/odoo/blob/2c0c26e6cc61f70c91617617ef77f23cfaa1dde6/addons/mrp_subcontracting_dropshipping/models/stock_rule.py#L19-L23
5. Since we are setting a default falsy 'partner_id' values in the `_prepare_procurement_values` of stock moves (e.g.`self.partner_id.id`) we needed to slightly alter the `_prepare_purchase_order` of the `mrp_subcontracting_dropshipping` module so that it sets the partner of the subcontractor when the move sets it to `False` rather than unset:
https://github.com/odoo/odoo/blob/1ac7834a9b9d07760700f6d7c73dfe270a247752/addons/mrp_subcontracting_dropshipping/models/stock_rule.py#L10-L11
opw-5428063
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#243028This update fixes a problem where canceled orders and their items persisted in the system, leading to incorrect order displays. Now, when an order is canceled and a new one is created, the system accurately reflects the changes, ensuring correct quantities and totals are shown. This improves the user experience for self-order functionality.
Original PR description
`point_of_sale`, `pos_self_order` ### step to reproduce: - Configure self order with online payment. - Open POS Self Order. - Add some products to the cart. - Cancel the order. - Create a new order and pay it via an "online payment" method. - Click on "Order Now". ### issue: - Previously cancelled products reappear as selected in the new order. ### reason: - Cancelled orders and orderlines were not removed from IndexedDB. - With Pay after Meal, a second order on the same table reused the existing one, causing the product card, order widget, and cart to show quantity and total from the old order instead of the new changes. ### fix: - Ensure both the order and its orderlines are removed from indexeddb when cancelling an order. - Product/cart page must show changed quantity and amount. task: 5005174 Forward-Port-Of: odoo/odoo#243971 Forward-Port-Of: odoo/odoo#224918
This update adds a 'Reload Data' button to error dialogs in the Point of Sale system, providing users with a simple way to resolve common issues. Previously, users only had an 'Ok' button, making it difficult to recover from errors. This change reduces downtime and improves the overall user experience for restaurant and online payment operations.
Original PR description
Purpose: ------------ - On Error dialogs, users only had "Ok" or could close the dialog, with no guidance on what to do next. - Many blocking issues are resolved simply by reloading POS data. Before this commit: ----------- - Error dialogs only had an "Ok" button. After this commit: ------------------ - Added a "Reload Data" button for quick recovery of common blocking issues. - Added a warning message in the reload data popup - For POS Restaurant, orders will attempt to sync before reloading data, reducing the risk of data loss. Task-5353590 Forward-Port-Of: odoo/odoo#243863 Forward-Port-Of: odoo/odoo#238112
This update resolves a bug where combo choices weren't displaying correctly in the self-order kiosk and online ordering systems. Previously, users had to reconfigure combo choices after selection. This fix ensures combo choices are displayed correctly without requiring manual reconfigurations, improving the user experience.
Original PR description
Before the fix, when we set a product variant as combo choice. In self/kiosk, we'll see the product template instead of the product itself. And we need to configure it again. It occured because for all of the products in the kiosk/self, we display the product template. The expected behavior if we set a product variant as combo choice is to have the product variant in the combo directly without having to reconfigure it. The bug occurs only since 19.0 because a fix was already done from 18.3 to 18.4 in this pr : #219908 but the fwport for 19.0 has never been merged. task: 5493798 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#244055
This update corrects a bug where the 'Import Bank Statement' action incorrectly selected a journal in multi-company Odoo setups. The fix ensures the action filters by the currently chosen company, preventing errors and ensuring accurate bank statement encoding. A new test confirms the fix's reliability under sudo rights.
Original PR description
Issue: when using the server action 'Import Bank Statement' the code would not filter on the currently selected company for choosing the journal on which to encode the bank statement and simply take the first result. Because the server action is running with sudo rights, in a multi-company environment more then one journals are found and the selected one is often wrong. Solution: filter on company during the selection of the journal. Note: a test was added in which we run the function with sudo rights to ensure an error is raised when the journal does not exist on the currently selected company, even if it is present on another company. Task-5494685 Forward-Port-Of: odoo/enterprise#104970 Forward-Port-Of: odoo/enterprise#104326
This update fixes an issue where employees on leave were incorrectly flagged for overtime. Now, when an employee is on a full day of leave, all hours worked are treated as overtime, without considering breaks. This ensures accurate overtime calculations for all employees.
Original PR description
This PR aims to fix how the overtime is being calculated with quantity based rules : - The expected _hours didn't take into account the leaves of the day , so if the user was on a leave, it would considered him absent ( give him negative overtime) , because he has no attendances that day. - if the employee took a whole day off, and decided to work on it, all the hours should be considered as overtime, the brake shouldn't be included (ex : his normal work sched is morning (9h-12h) , break(12h-13h), afternoon(13-17h) , he's already getting paid for that time , so every single hour worked that day from 12am to 12 pm is added time , and there is no break in added time) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#244048
This update resolves a bug where the column layout within the HTML editor would break after performing undo operations. Specifically, changing the number of columns using Powerbox would corrupt the column structure. This change ensures the column layout remains consistent and functional after undoing changes.
Original PR description
**Current behavior before PR:** Steps to reproduce: - Create 3 columns using powerbox - Convert it into 4 columns - Press ctrl + z to make it 3 columns - Convert it into 4 columns again using powerbox Notice that column structure is broken. This happens because after undo operation, in `changeColumnsNumber` the regex replaces column div className incorrectly leading to invalid colund structure. **Desired behavior after PR is merged:** This PR ensures that column structure doesn't break. task-5468578 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#242500
This update fixes an issue where changing the rental period of an order didn't automatically update the associated rental transfers. The fix mimics the rescheduling behavior of purchase orders, ensuring that rental transfers are accurately reflected after a rental period adjustment. This improves the reliability of rental order management.
Original PR description
### Steps to reproduce: - In the settings enable "Rental Transfers" - Create a storable and rentable product P - Create and confirm a rental order for 1 unit of P - Change the rental period to 10 days in the future #### > The rental tranfers were not updated accordingly ### Cause of the issue: Nothing is currently implemented to reschedule the rental transfers. ### Fix: We somewhat mimic the reschedule purchase behavior: https://github.com/odoo/odoo/blob/6ca34a0f5347e0611cde95453119dda8b40fa589/addons/purchase_stock/models/purchase_order_line.py#L98-L101 But we rely on the order itself rather than its order lines since the `start_date` and the `return_date` are related fields so that no `write` is triggered when the order is rescheduled: https://github.com/odoo/enterprise/blob/96a80f583a0ca502ff06bc05d03775c76c6a7537/sale_renting/models/sale_order_line.py#L18-L19 opw-5158508 Forward-Port-Of: odoo/enterprise#103602 Forward-Port-Of: odoo/enterprise#101334
This update removes unnecessary integer rounding from monthly Italian VAT reports. Previously, rounding was incorrectly applied, causing discrepancies in reporting. This change ensures accurate and consistent monthly VAT reporting for Italian businesses using Odoo.
Original PR description
**Description of the issue/feature this PR addresses**: Integer rounding is only required on annual l10n_it VAT reports. It appears that it was incorrectly added to the monthly report when the two were split in #193662. **Current behavior before PR**: Integer rounding on monthly l10n_it tax reports. **Desired behavior after PR is merged**: No more integer rounding on monthly l10n_it tax reports. [opw-5292310](https://www.odoo.com/odoo/project.task/project.task/5292310) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#244389 Forward-Port-Of: odoo/odoo#243100
This update fixes a critical issue with how strings are processed in Odoo's web framework, ensuring accurate template rendering and test results. The changes also streamline translation management and improve code clarity, leading to more reliable and maintainable applications.
Original PR description
### [[FIX] web: cleanup string-related utils](https://github.com/odoo/odoo/pull/241068/changes) This commit cleans up several utility files relating to string-parsing and translations. Main changes…
### [[FIX] web: cleanup string-related utils](https://github.com/odoo/odoo/pull/241068/changes) This commit cleans up several utility files relating to string-parsing and translations. Main changes are: - fixed `sprintf` and related functions: before this commmit, string substitutions were incorrectly inserted in the template string, and it was actually reflected in a test (template : `"<p>%s</p>%s"` => test incorrectly asserted that both strings were inserted in the first "%s" and "undefined" was inserted in the second); - to replicate the Python homonymous behaviour: "%s" characters can now be escaped in "sprintf-ed" strings by adding an additional "%" sign before the expression; - unification of translations via a TranslatedString class (which will also simplify external overrides); - unified API for some utility functions sharing the same purpose (typically: accepting an iterable instead of a list, etc.); - filling missing docstring, re-ordering functions and constants for clarity; - added "headless" tag to some utility functions' tests, when UI is not needed. Enterprise: https://github.com/odoo/enterprise/pull/104939 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#241068
This update fixes an issue where product standard prices weren't correctly converted to the Point of Sale currency, leading to incorrect pricing calculations when using pricelists. The fix ensures all product prices are consistently converted, guaranteeing accurate pricing in the PoS system and preventing pricing discrepancies.
Original PR description
The standard price of the products were not converted to the currency of the PoS journal, which could lead to issues when creating pricelist items based on the standard price. Steps to reproduce: ------------------- * Change the currency of any PoS journal to a different currency than the company currency. * Create a product with a standard price > 0. * Create a pricelist that uses the standard price as a base price. (e.g. price = standard price * 2) * Add this product to a PoS order > Observation: The price is not correctly computed according to the pricelist, because the standard price was not converted to the PoS currency. Why the fix: ------------ We just make sure to convert the standard price of the products when loading the products in the PoS session the same way as we do it for the list price. opw-5124388 Forward-Port-Of: odoo/odoo#244147 Forward-Port-Of: odoo/odoo#241168
This update fixes an issue where the VAT summary report for Argentinian invoices was incorrectly calculating totals when multiple IIBB taxes were applied. The fix ensures that VAT amounts are counted accurately, matching the totals displayed in the accounting form, resolving an inflated total calculation.
Original PR description
**Issue** When using a VAT tax marked as price included, together with multiple IIBB taxes on the same invoice, the VAT summary report displays an incorrect total. Specifically, the VAT amount is…
**Issue** When using a VAT tax marked as price included, together with multiple IIBB taxes on the same invoice, the VAT summary report displays an incorrect total. Specifically, the VAT amount is counted multiple times, once for each IIBB tax, leading to an inflated total. **Steps to Reproduce** 1. Install the Accounting app and the Argentinian localization (l10n_ar) 2. Set the 21% VAT Purchase tax as Included in Price 3. Create a vendor bill applying the 21% VAT tax and at least two IIBB taxes 4. Open the VAT summary report for that bill Expected Behaviour: The total in the VAT summary should match the total shown in the accounting form view, with each tax counted only once. **Root Cause** The VAT summary report in the Argentinian localization relies on an SQL query to aggregate tax information for each `account.move`. The query joins `account_move_line` with `account_tax`, `account_tax_group`, and the many-to-many relation table `account_move_line_account_tax_rel`. Each `account_move_line` related to a VAT tax line (via `tax_line_id`) is joined with the `account_move_line_account_tax_rel` table. If that base line is related to multiple IIBB taxes, the join multiplies the VAT line once per IIBB tax since multiple matching rows exist. **Fix** The solution separates the logic for computing tax lines and base lines into two distinct subqueries. Each is aggregated independently to prevent duplication caused by one-to-many and many-to-many joins. The results are then joined using the unique `account_move_line.id`, ensuring each tax amount is counted exactly once in the final totals. opw-4776861 Forward-Port-Of: odoo/enterprise#98933 Forward-Port-Of: odoo/enterprise#85873