Wednesday, January 14, 2026
17 changes · saas-18.2
New functionality added to Odoo
This update expands Odoo's payment capabilities to include Xendit, a popular payment gateway, in Thailand, Malaysia, and Vietnam. The changes add the necessary configurations to support local payment channels through Xendit, enabling businesses to accept payments from customers in these regions.
Original PR description
Xendit has expanded to TH, MY and VN supporting the local payment channels. This commit is to add the supported pamyent channels according to what they have added. task-4334511 Forward-Port-Of: odoo/odoo#189527
This update introduces support for Peppol Self-Billing, allowing customers to create invoices on behalf of vendors for easier accounting. It enables the export of vendor bills as compliant invoices and allows receiving these invoices directly within Odoo, streamlining the billing process for Peppol transactions.
Original PR description
Self-billed invoices are invoices which are created by the customer on behalf of the vendor. These can be used in certain business flows, typically when the customer needs to create an invoice…
Self-billed invoices are invoices which are created by the customer on behalf of the vendor. These can be used in certain business flows, typically when the customer needs to create an invoice internally for accounting purposes. Peppol provides the ability for customers to send self-billed invoices to the vendor over the Peppol network. This way the vendor can verify whether the invoice is correct. See the Peppol documentation at https://docs.peppol.eu/poacc/self-billing/3.0/bis-sb/ #### This PR provides (1) the ability to export vendor bills as self-billed invoices conformant to the BIS3 standard (2) the ability to import BIS3 self-billed invoices as customer invoices (3) the ability to send vendor bills as self-billed invoices over Peppol (4) the ability to receive self-billed invoices from Peppol in a specified Sales journal. #### Configuration Purchase journals now have a `Is Self Billing` boolean field. Self-billing journals have a per-partner sequence, and can send vendor bills as self-billing invoices via Peppol if the option is activated in the Peppol configuration. We also add the self-billed invoice Peppol document type IDs in the list of documents which the user can select or deselect to allow/prevent reception of those document types. Backport of https://github.com/odoo/odoo/pull/222658 Enterprise PR: https://github.com/odoo/enterprise/pull/97803 Upgrade PR: https://github.com/odoo/upgrade/pull/8886 task-5153851 Forward-Port-Of: odoo/odoo#232548
Enhancements to existing features
This update adds two new Unit of Measure codes – Minute (MIN) and Kilowatt hour (KWH) – to Odoo, aligning with UNECE Recommendation No.20 for Peppol. Previously, Odoo defaulted to a generic 'Units' code, which wasn't suitable for UBL/CII electronic invoices. This change ensures proper support for these key units, particularly benefiting localization modules like those for Chile and Turkey.
Original PR description
**Issue:** 2 UoM that is in the UNECE Recommendation No.20 for Peppol don't exist in Odoo: - MIN: Minute - KWH: Kilowatt hour Even if they are created manually, they are not used in the UBL/CII electronic invoices. Instead, the default code (i.e. "C62" for "Units" is used). Some localization modules create the "Kilowatt hour" UoM as they need it. (l10n_cl and l10n_tr_nilvera) So it's better to have a "generic" one available for every module. opw-5269119 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#243333 Forward-Port-Of: odoo/odoo#238342
Resolved issues and error corrections
This update resolves an issue preventing users in the l10n_it_pos module from printing receipts when multiple payment methods were used. The change backports a fix from another Odoo project, ensuring accurate receipt generation for Italian Point of Sale transactions. This improves the user experience and compliance with fiscal requirements.
Original PR description
Backports of https://github.com/odoo/enterprise/pull/96353. References: See page 36 in the [official docs](https://download4.epson.biz/sec_pubs/bs/pdf/ePOS%20Fiscal%20Print%20Solution%20Development%20Guide%20Rev%20T.pdf). Ticket [link](https://www.odoo.com/odoo/project.task/5376242) opw-5376242 Forward-Port-Of: odoo/enterprise#103710
This update enables public users to register for document sharing without needing a traditional Odoo user account. Previously, a public user invited via link would be forced to create a user, which wasn't ideal. Now, the system intelligently creates a linked user for the partner, streamlining the document sharing process.
Original PR description
Purpose ======= We can share a document to a partner without a user, and with `access_via_link == 'none'`. In that situation, the partner is forced to create a user, but if he clicks on signup, then the new user won't be linked to the partner set on the `documents.access` (a new partner will be created). Now, when inviting a member, if he doesn't have a user, we invite him to create a user. If the partner has a user, then we just redirect him to the login page. Task-5242208 Forward-Port-Of: odoo/enterprise#100628
This update corrects a critical issue with the Odoo Enterprise system's testing environment for Shopee integration. Shopee recently altered their API paths, rendering the previous testing configurations invalid. This fix ensures the testing environment accurately reflects the current Shopee API, maintaining reliable testing and development.
Original PR description
Shopee has changed the API path and the original testing API paths are no longer valid. Forward-Port-Of: odoo/enterprise#103939
This update resolves an issue where the location of merged manufacturing orders wasn't correctly linked to subsequent transfer orders. The fix ensures that the final location of merged MOs is accurately propagated, preventing incorrect stock movements and improving the reliability of multi-location workflows. This primarily impacts complex manufacturing processes.
Original PR description
Situation ----- When applying a push rule after manufacturing a merged MO, there is an odd case where the link between the merged MO's transfer and the demand move breaks in…
Situation ----- When applying a push rule after manufacturing a merged MO, there is an odd case where the link between the merged MO's transfer and the demand move breaks in https://github.com/odoo/odoo/blob/182a387d0ec6ad28d7d052d7100b2184372514be/addons/stock/models/stock_move.py#L1054 because of the `m.location_id == move.location_final_id` part being false in https://github.com/odoo/odoo/blob/182a387d0ec6ad28d7d052d7100b2184372514be/addons/stock/models/stock_move.py#L1090-L1097 This is because, during the merge, `location_final_id` is not propagated to the new MO https://github.com/odoo/odoo/blob/5f8336c7d8ab891103a3035a9ebb5242cfa46ce6/addons/mrp/models/mrp_production.py#L2416-L2424 so when the new MO's `move_finished_id` gets computed https://github.com/odoo/odoo/blob/5f8336c7d8ab891103a3035a9ebb5242cfa46ce6/addons/mrp/models/mrp_production.py#L822 it gets the MO's `location_final_id` https://github.com/odoo/odoo/blob/5f8336c7d8ab891103a3035a9ebb5242cfa46ce6/addons/mrp/models/mrp_production.py#L1202 which is false. This leads to to the move getting the warehouse's default stock location thanks to https://github.com/odoo/odoo/blob/182a387d0ec6ad28d7d052d7100b2184372514be/addons/mrp/models/stock_move.py#L456-L457 This is problematic for complex use cases with multi-locations and custom routes. It should be safe to propagate the `location_final_id` of the merged MOs if they all share the same one. Use case example ----- <details> <summary>Full use case</summary> - Enable multi-step routes - Create location "WH/Stock/L1" - Create location "WH/Stock/L2" - Create Operation Type "MO child" - Type of Operation: Manufacturing - Sequence Prefix: MOCHILD - Source Location: L1 - Destination Location: L2 - Create Operation Type "Push Transfer" - Type of Operation: Internal Transfer - Sequence Prefix: L2L1 - Source Location: L2 - Destination Location: L1 - Create Route "MO child" - Create Rule "Manufacture" - Action: Manufacture - Operation Type: MO child - Source Location: False - Destination Location: Stock - Create Route "2-step" - Warehouse: Main WH - Create Rule "L1 -> Virtual/Production" - Action: Pull from - Operation Type: MO child - Source Location: L1 - Destination Location: Virtual/Production - Create Rule "Push: L2 -> L1" - Action: Push To - Operation Type: Push Transfer - Source Location: L2 - Destination Location: L1 - Unarchive MTO - Edit MTO route - Create Rule "L1 -> Virtual/production (MTO)" - Action: Pull - Operation Type: "My Company: Manufacturing" - Source Location: L1 - Destination Location: Virtual/Production - Supply Method: Trigger another rule - Create product "Main product" - Create product "Child product" - Routes: "MO child" & MTO - Create product "Material" (consumable) - Create BOM - Product: "Main product" - Component: "Child product" - Create BOM - Product: "Child product" - Component: "Material" - Create MO for "Main product" - Misc/Component Location set to L1 - Duplicate the MO - Merge child MOs & produce - Validate merged MO transfer to L1 - Go back to one of the "Main product" MO > Component quantity is 0 </details> ----- Ticket: opw-5144196 Forward-Port-Of: odoo/odoo#240695
This update resolves an issue where manually changed currency rates on invoices weren't correctly applied, leading to data loss. The fix now only recalculates rates if the user hasn't modified them, ensuring accurate invoice calculations and preventing data overwrites. This improves the reliability of financial reporting.
Original PR description
in case the user would enter manually a different rate than the default one, but does not fill the invoice date; odoo was setting today as the invoice date, which was changing the rate and recomputing all the lines... Effectively losing everything the user just encoded. So now, we only recompute the rate and the lines if the user didn't change it. Fix: https://github.com/odoo/odoo/pull/226124/changes/1b48d141d7260a262075555c4ab9cedc691d3551 Issue with Fix: Invoices posted on dates different from their creation date do not update their currency rates, even though they should. Comparing `invoice_currency_rate` to the expected rate at creation is a better guess. task-5477481 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#242800
This update resolves an issue where users were blocked from settling customer balances in Point of Sale when ZATCA integration was active. The fix removes the forced invoice requirement for settlement orders, allowing users to complete payments without generating unnecessary e-invoices to ZATCA.
Original PR description
## Dependent PR https://github.com/odoo/enterprise/pull/98463 ## Description of the issue/feature this PR addresses: Users are blocked when trying to use the **Settle Due** feature in Point of Sale…
## Dependent PR https://github.com/odoo/enterprise/pull/98463 ## Description of the issue/feature this PR addresses: Users are blocked when trying to use the **Settle Due** feature in Point of Sale if the ZATCA (l10n_sa_edi_pos) integration is enabled. ## Current behavior before PR: When a PoS order is created using a "Pay Later" payment method, an invoice is correctly generated and sent to ZATCA. However, when the user later tries to settle that customer's due balance (using the **Settle Due** option), the l10n_sa_edi_pos module incorrectly forces the Invoice option to be enabled and makes the field read-only. This blocks the user because: - Settlement orders do not contain any lines, so a new invoice cannot be generated. - The original invoice was already sent to ZATCA, and the settlement payment should not be sent as a new e-invoice. Thus, the user cannot proceed with the settlement. ## Desired behavior after PR is merged: After this fix, the **Invoice** checkbox will no longer be forced or marked as read-only during **Settle Due** operations. The field will default to False, aligning with standard Odoo behavior for settlements and allowing the user to complete the payment. task-5144679 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#233769
This update resolves an issue where the 'is_settling_account' flag remained true after a Point of Sale user cancelled a 'Settle Due' payment. This prevented normal sales from being processed correctly, potentially causing errors and bypassing important accounting rules. The fix now ensures the flag is reset to false, allowing for proper order processing.
Original PR description
## Description of the issue/feature this PR addresses: The `is_settling_account` flag on a Point of Sale order is not reset to False if the user cancels a **Settle Due** operation. ## Current…
## Description of the issue/feature this PR addresses: The `is_settling_account` flag on a Point of Sale order is not reset to False if the user cancels a **Settle Due** operation. ## Current behavior before PR: When a user initiates a **Settle Due** payment for a customer, Odoo creates a new order and sets the `is_settling_account` flag to True. If the user proceeds to the payment screen but then navigates back (to the product screen) instead of completing the payment, the flag remains True. This is problematic because the user can then add regular products to this same order and check out. The order is processed as a normal sale, but it is incorrectly flagged as a settlement, which can lead to error on codes depending on this. ## Desired behavior after PR is merged: After this fix, if a user leaves the payment screen during a **Settle Due** operation, the `is_settling_account` flag on the order will be correctly reset to False. task-id - 5144679 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/enterprise#98463
This update fixes an issue where loyalty programs with pricelist restrictions weren't properly considered during POS transactions. Previously, if a POS session's pricelist didn't match a loyalty program's restrictions, the loyalty program would still be applied. Now, the system correctly checks pricelist compatibility, ensuring loyalty programs are only applied when the session's pricing aligns with the program's rules.
Original PR description
Before this commit, if a loyalty program had pricelist restrictions, the POS would not consider them when loading the applicable loyalty programs. This could lead to scenarios where a loyalty program was applied in a POS session even if the session's pricelist was not allowed by the program. This happened when the pricelist was also not available in the POS configuration and program.pricelist_ids was empty. opw-5467990 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#242279
This update fixes an issue where the system was incorrectly using outdated number ranges when syncing data with DIAN. Previously, the system didn't properly check for the latest available ranges, leading to errors when clients requested new ranges. This ensures accurate DIAN data synchronization for our Colombian clients.
Original PR description
**PROBLEM** When a client has exhausted a number range for a prefix, if he request a new one, when trying to sync the DIAN data the old range will be use instead of the new one. **STEP TO REPRODUCE**…
**PROBLEM** When a client has exhausted a number range for a prefix, if he request a new one, when trying to sync the DIAN data the old range will be use instead of the new one. **STEP TO REPRODUCE** According to the DIAN documentation, the GetNumberRange service is only available in the production environment. So i'm not sure if we can safely test this. The repro steps would be something like: 1. Request a range. 2. Exhaust all number from this range by sending invoices to DIAN. 3. Request a new range. 4. sync with DIAN. (notice the range selected is still the old one). 5. Try sending a new invoice to DIAN and notice there is an error. **CAUSE** In `l10n_co_dian/models/account_journal.py` the function `_l10n_co_dian_get_journal_values()` loops on all the xml `NumberRangeResponse` node and store the last range values encountered for each prefix. We don't check if the this last range is still valid, if it's the newest created (could be checked with the xml field `ResolutionDate`, but the date could be the same if the range were created the same day), if it's the latest in term of number range (DIAN start with range 1-100, then 101-something etc.). Forward-Port-Of: odoo/enterprise#103943
This update resolves an issue where users could incorrectly save attendance records after attempting to change the associated employee. The fix ensures that only authorized users can update attendance records, improving data integrity and preventing potential errors. Test coverage has been added to confirm this change.
Original PR description
Closes [odoo/odoo#226007](https://github.com/odoo/odoo/issues/226007). Description of the issue/feature this PR addresses: Prevents a user from updating their attendance record by changing the employee to the one whose attendance is not managed by the current user. Current behavior before PR: - Assign the Officer Group of Attendance group to a user. - Assign the user as the attendance manager of itself. - Login with that user. - Create an attendance record for the employee and save it. - Try to change the employee and save; an error will be thrown as expected. - Go to the Attendance menu; the record will still be saved. Desired behavior after PR is merged: This commit ensures that un-allowed write does not take place + test coverage added. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#243573 Forward-Port-Of: odoo/odoo#226335
This update corrects a potential issue with the transmission of Swiss payroll data (ELM) by ensuring the correct reference date is used when locking payroll periods. This improves the accuracy of data sent to tax authorities, reducing the risk of errors and potential delays in processing. The change is a technical fix focused on data integrity.
Original PR description
Forward-Port-Of: odoo/enterprise#104269
This update resolves an issue where the 'Source Document' field was missing when reversing invoices. This meant critical information about the original invoice wasn't accurately reflected in the reversed transaction. The fix ensures that the 'Source Document' field correctly displays the original invoice details during reverse moves, improving data accuracy and reporting.
Original PR description
### Issue: Reverse moves miss `invoice_origin` field. #### To reproduce: 1- Create a SO. 2- Create an invoice and confirm. 3- In invoice list view make the `Source Document` visible. 4- Create a credit note and reverse the move. From invoice list view, you can observe that `Source Document` is empty for reverse move. ### Cause: This is a regression introduced by #236656. opw-5362055 Forward-Port-Of: odoo/odoo#240439
This update corrects a bug where customer statements incorrectly showed no outstanding amounts after partial invoice payments. The fix ensures the system accurately considers both reconciled and unreconciled balances when determining follow-up actions for invoices. This improves the accuracy of customer statements and reporting.
Original PR description
**Steps to Reproduce:** 1. Create an invoice with a due date 20 days prior and an amount of $100 2. Create a payment of 120$ 3. Create an invoice of 100$ 4. Reconcile the second invoice with the…
**Steps to Reproduce:** 1. Create an invoice with a due date 20 days prior and an amount of $100 2. Create a payment of 120$ 3. Create an invoice of 100$ 4. Reconcile the second invoice with the payment 5. Go to the customer record. 6. The Customer Statement smart button shows an amount due, but the followup status in the Accounting tab shows "No action needed". [Video (with different values, same result)](https://drive.google.com/file/d/1MFg-tUos-oGbk7SKn92OE8w0-PnObae7/view?usp=sharing) **Cause:** - The query in `_get_followup_data_query` checks an account.move.line's `balance`, ignoring amounts partially reconciled. [1](https://github.com/odoo/enterprise/blob/da8a0fb49861a5cfb366c85da459876ad1556924/account_followup/models/res_partner.py#L404) - In the example above, the sum of unreconciled balances is 100 - 120 = -20 due, where the amount_residual shows 100 -20 = 80 due. **Solution:** Use `amount_residual` instead of `balance` in `_get_followup_data_query`. This fix was applied last year to 17.0, but was never forward-ported to master. [2](https://github.com/odoo/enterprise/pull/77679) [opw-5216007](https://www.odoo.com/odoo/project.task/5216007) Forward-Port-Of: odoo/enterprise#101874
This update fixes an error in how price differences are calculated for subcontracted products. Previously, the system incorrectly compared costs in different currencies, leading to inaccurate price difference invoices. Now, the system automatically converts component costs to the invoice currency, ensuring accurate price difference calculations and preventing erroneous invoice lines.
Original PR description
Problem: When computing the price difference on a vendor bill for a subcontracted product, the component cost is considered in the company's currency regardless of the currency of the invoice. This…
Problem: When computing the price difference on a vendor bill for a subcontracted product, the component cost is considered in the company's currency regardless of the currency of the invoice. This means the price difference calculation directly compares two different currencies without converting them, resulting in some incorrect values for the price difference invoice lines. Solution: We will convert the component cost to the invoice currency when computing price difference. Steps to reproduce (runbot 18): - Product with - Standard price auto - BoM: sbc, one component with nonzero value (e.g. $1) - Nonzero value (e.g. $5) - Another currency 1. Create a PO for the subcontracted product 2. Set the Invoice currency to something other than the company default 3. Confirm the PO and validate the sbc and receipt 4. Create the vendor bill, and bill for the correct value (Whatever $4 is in the invoice currency) A price difference line will be erroneously generated for some nonsense value, when we expect 0 price difference. opw-5232917 Forward-Port-Of: odoo/odoo#238428