Thursday, January 8, 2026
12 changes · saas-18.3
Enhancements to existing features
This update adds crucial data attributes to Odoo's tax calculations and NFS-e submissions when the Brazilian fiscal reform is active. Specifically, the system now includes 'name', 'businessName', 'federalTaxId', and 'type' fields, ensuring accurate tax reporting and compliance with new regulations. This change is necessary to meet updated Brazilian tax requirements.
Original PR description
Purpose: Additional attributes are required to be sent in the rendered node for tax calculation and NFS-e submission when the fiscal reform is enabled. The additional required attributes are: - name - businessName - federalTaxId - type task-5450129 Forward-Port-Of: odoo/enterprise#103438
Resolved issues and error corrections
This update corrects a technical issue preventing credit notes with allowances issued more than 6 days after the original invoice from being processed by ECpay. The fix removes the incorrect date parameter and ensures consistent data transmission, eliminating errors and improving compliance. This change ensures seamless e-invoice generation and submission to ECpay.
Original PR description
**AllowanceDate**: l10n_tw_edi_ecpay has an issue on Credit Notes (Allowances). When we `_l10n_tw_edi_generate_issue_allowance_json()`, we send the `l10n_tw_edi_invoice_create_date` which is was set…
**AllowanceDate**:
l10n_tw_edi_ecpay has an issue on Credit Notes (Allowances).
When we `_l10n_tw_edi_generate_issue_allowance_json()`, we send the
`l10n_tw_edi_invoice_create_date` which is was set to the associated
invoices creation date, and not the Allowance's creation date.
This creates a potential issue where allowances issued more than 6 days
after the original invoice would bounce back from ECpay with errors.
To be consistent with invoices send to ECPay, we do not send the
`AllowanceDate` parameter at all
Manual Testing/Verification:
1. Create an invoice that has a `l10n_tw_edi_invoice_create_date`,
visible in the Invoice's ECPay tab more than 6 days ago. (Requires
sending to ECPay via the custom wizard via the "Send" button)
2. Create a credit note from the invoice and send to ECPay.
3a. Before this, see that an error would appear.
3b. Now, there would be no error
*InvoiceRemark*:
When Customer Reference `ref` is not set, the code sets the parameter
value as `False`, displaying it's string on the e-invoice and official
printout. We only set the parameter if there exists the `ref` now,
eliminating the issue.
Tests:
1. (both cases) undo the `account_move.py` changes and run the tests.
task-[5455847](https://www.odoo.com/odoo/project/967/tasks/5455847)
---
# New test failed output
<img width="1458" height="353" alt="image" src="https://github.com/user-attachments/assets/77df8e51-5005-4d99-985c-71757c0f62a6" />
```bash
07:47:53,055 ERROR l10n_tw_edi_ecpay-demo-vy2vd3s0 odoo.addons.l10n_tw_edi_ecpay.tests.test_edi: FAIL: L10nTWITestEdi.test_01_can_generate_file
Traceback (most recent call last):
File "/home/odoo/odev/worktrees/18.0-l10n_tw_edi_ecpay-fix-allowance-date-erle/odoo/addons/l10n_tw_edi_ecpay/tests/test_edi.py", line 61, in test_01_can_generate_file
self.assertIsInstance(json_data["InvoiceRemark"], str)
~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: False is not an instance of <class 'str'>
07:48:02,516 ERROR l10n_tw_edi_ecpay-demo-vy2vd3s0 odoo.addons.l10n_tw_edi_ecpay.tests.test_edi: FAIL: L10nTWITestEdi.test_13_b2b_refund_upload_deadline_restriction
Traceback (most recent call last):
File "/home/odoo/odev/virtualenvs/18.0/lib/python3.13/site-packages/freezegun/api.py", line 885, in wrapper
result = func(*args, **kwargs)
File "/home/odoo/odev/worktrees/18.0-l10n_tw_edi_ecpay-fix-allowance-date-erle/odoo/addons/l10n_tw_edi_ecpay/tests/test_edi.py", line 430, in test_13_b2b_refund_upload_deadline_restriction
self.assertNotIn("AllowanceDate", json_data,
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^
"B2B Allowances should not include AllowanceDate to avoid >6 day limit errors."
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
AssertionError: 'AllowanceDate' unexpectedly found in {'MerchantID': '1234', 'Details': [{'OriginalInvoiceNumber': 'AB11100099', 'OriginalInvoiceDate': '2025-01-06', 'OriginalSequenceNumber': 0, 'ItemName':
'product_a', 'ItemCount': 1.0, 'ItemPrice': 1000.0, 'ItemAmount': 1000.0}], 'TotalAmount': 1000.0, 'TaxAmount': 50.0, 'CustomerEmail': 'partner_b@tsointsoin', 'AllowanceDate': '2025-01-06 15:00:00'} : B2B
Allowances should not include AllowanceDate to avoid >6 day limit errors.
```
---
Things to think about:
- FWP
- [ ] 19.0
- [ ] master
Forward-Port-Of: odoo/odoo#241973This update prevents the loss of Starshipit delivery orders when label creation fails. Previously, a failed label attempt would delete the order, requiring users to restart. Now, users can retry validation and fix issues in Starshipit without losing existing orders, streamlining the delivery process.
Original PR description
## Current behaviour: When validating a delivery, Odoo sends data to Starshipit. If label creation fails, the module deletes the created order. ## Expected behaviour: If label creation fails, the…
## Current behaviour: When validating a delivery, Odoo sends data to Starshipit. If label creation fails, the module deletes the created order. ## Expected behaviour: If label creation fails, the Starshipit order should remain. Users should be able to fix data in Starshipit and retry validation in Odoo without losing the existing order. ## Steps to reproduce: 1. Validate a delivery order integrated with Starshipit. 2. Trigger a label generation failure (e.g., bad address). 3. Observe that the created Starshipit order is deleted. ## Cause of the issue: The integration treats label creation failure as a fatal step and cleans up the previously created Starshipit order. ## Fix: Do not delete the Starshipit order on label failure. When the user retries validation, first check Starshipit for an order matching the unique reference. If found, reuse it and continue with label creation and manifest. If not found, create a new Starshipit order as usual. ## Additional note: The _() wrapper in the error line was removed because the Starshipit service has no env or language context. Since translations cannot be resolved there, Odoo raised a warning. Removing _() avoids this warning and keeps the error clean. opw-5306979 Forward-Port-Of: odoo/enterprise#103354 Forward-Port-Of: odoo/enterprise#101174
This update ensures that the correct warehouse location is linked to merged manufacturing orders. Previously, the location information wasn't properly carried over, causing issues with multi-location workflows. This fix resolves a potential disruption in order fulfillment processes, particularly for complex manufacturing scenarios.
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 ensures that inventory tracking changes are properly enforced when a product's type is altered, preventing incorrect stock calculations. Previously, a change in product type could be saved without triggering the necessary checks, leading to potential inventory discrepancies. This fix restores the expected behavior of raising an error when attempting to change a product's inventory tracking.
Original PR description
## Description of the issue/feature this PR addresses: `compute_is_storable` is called when the `type` value is modified but the `write` function is never called when the value is set using the…
## Description of the issue/feature this PR addresses: `compute_is_storable` is called when the `type` value is modified but the `write` function is never called when the value is set using the `is_storable` attribute. Updating `is_storable` using a `write` ensure that an exception is raised when move line exists. But this fix addresses the symptom, not the underlying issue. So why ? Is it related to the cache or unit test environment ? ## Current behavior before PR: In a Unit test, If you convert a consumable and storable product to a service, no exception is raised, even with existing stock moves. Unlike the previous version of Odoo (<15.0), where an exception was raised when the product type was changed and stock movements existed, detection now occurs if the ‘is_storable’ status is changed. However, this detection is not triggered if the value of ‘is_storable’ is defined by its attribute. ## Desired behavior after PR is merged: An exception must be raised (like Odoo 14.0) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#242514 Forward-Port-Of: odoo/odoo#239284
This update resolves an issue where placing items into a package via the SML view incorrectly locates the new package. The fix addresses a technical problem within the Odoo stock management system, ensuring packages are correctly identified and tracked after this action. This improves the reliability of the 'Put in Pack' functionality.
Original PR description
Putting in pack from the SML view leads to package incorrectly located To reproduce the issue: 1. In Settings, enable "Package" 2. Confirm a delivery with 2 available products 3. Open the SML thanks…
Putting in pack from the SML view leads to package incorrectly located To reproduce the issue: 1. In Settings, enable "Package" 2. Confirm a delivery with 2 available products 3. Open the SML thanks to the smart button 4. Tick a line > Put in pack 5. On the second line, in "Destination Package", look for the package Error: it is impossible to find it When opening the SML thanks to the smart button, we also load a lot of default values: https://github.com/odoo/odoo/blob/1492abd8c6bcfdbc48f730f6767b177aeff54bf7/addons/stock/models/stock_picking.py#L1203-L1221 Those are (obviously) SML specific. However, this context is used when putting in pack. This is a problem since `location_id` is also the field name of a package. As a result, the ORM defines the location of the new package with the default value, i.e. the source location of the SML. This is incorrect. One consequence of this bug is the step 5 of the above use case. When looking for a package, a domain checks its location: https://github.com/odoo/odoo/blob/35feed47622b279abf8e593d8190ea36b64d32fd/addons/stock/models/stock_move_line.py#L51-L55 It must be either `False` or equal to the dest loc, which is not the case with the created package. Now... About the solution. It's probably difficult to do something more hacky. However, it's not too invasive in the code and all user will take benefit from it once the commit is deployed. On master, we will discuss with both frameworks to negotiate/find something more elegant. OPW-5215243 Forward-Port-Of: odoo/odoo#242328
This update corrects an issue where bank statements were incorrectly flagged as invalid, even when they were accurate. The fix adjusts how statement validity is calculated, ensuring that all statements are properly recognized as valid based on their balances. This improves the reliability of bank reconciliation within the accounting module.
Original PR description
Some bank account statements are computed as not valid, although they are valid. Statement 1 and 3 appear, and statement 3 is shown as invalid, while both statements should be shown as valid. Statement validity is computed depending on previous statement end balance and current statement start balance. The SQL query uses a window function to retrieve the previous statement. However, the function is applied after the WHERE clause. Therefore, it uses the end_balance of the previously selected statement instead of the previous statement. #### Step to reproduce: - In the bank dashboard of the accounting app - Create journal entry 1 - Create statement 1 - Create journal entry 2 - Create statement 2 - Validate the journal entry 2 - Create journal entry 3 - Create statement 3 - filter statement per "Not Matched" Ticket [link](https://www.odoo.com/odoo/project.task/5341433) opw-5341433 Forward-Port-Of: odoo/odoo#238381
This update fixes a problem where customers on one website could access payment providers enabled only for a different website. The change ensures that payment providers are correctly filtered based on the customer's website, preventing incorrect payment options from appearing in the sales portal. This improves the customer experience and ensures accurate payment processing.
Original PR description
[FIX] website_sale, adding website_id in portal controller Version: 17.0+e Steps to reproduce ------------------ The database has two different websites. A payment provider is enabled for just one of…
[FIX] website_sale, adding website_id in portal controller Version: 17.0+e Steps to reproduce ------------------ The database has two different websites. A payment provider is enabled for just one of them (website1). When a sale order is created on the sales app and the customer accesses it in its portal on the website2, he is able to pay with the payment provider which is only enabled on website1. The problem also occurs when previewing the customer’s portal view. Why it's happening ------------------ When accessing an order via “/my/orders/<int:order\_id>”, the portal_order_page method calls _get_compatible_providers without passing the website_id. The overriding logic in website_payment then defaults to considering all activated payment methods as compatible, regardless of website restrictions. As no website_id is provided, the overriding method from the payment_provider extension in website_payment module considers every activated payment methods as compatible. The Fix ------- We now add the current website's id to the method if none has been added before. opw-5172444, “Payment provider visible on sales order portal" --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#242380 Forward-Port-Of: odoo/odoo#235954
This update fixes an issue where invoices could incorrectly retain accounts from the original company after changing the invoice's company and journal. Previously, this meant accounts weren't properly associated with the new company, preventing accurate financial reporting. This change ensures invoices correctly reflect the associated company and journal, improving data accuracy.
Original PR description
This issue was already fixed in this PR: https://github.com/odoo/odoo/pull/234357 But that was revert because there was a bug with company branches ### Steps to reproduce: - Create Company A and Company B - Create an invoice on Company A with one line having an account in Company A - On the same invoice, change the company to Company B and change the journal to a journal of Company B - Save, then confirm the invoice. ### Issue: The invoice, now belonging to Company B, still has the same account from company A, and we are able to post it on the journal from company B opw-5167958 Forward-Port-Of: odoo/odoo#242239
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 updated when the rental period is adjusted. 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#102437 Forward-Port-Of: odoo/enterprise#101334
This update resolves an issue where the automated PDF generation for multiple paychecks wasn't functioning correctly. The fix ensures that PDF documents are generated reliably, regardless of the number of paychecks being processed. This improves the accuracy and efficiency of payroll reporting.
Original PR description
### Issue: When running the scheduled action "Payroll: Generate pdfs" for several payslips, nothing is generated and a traceback can be seen in the logs. ### Steps to reproduce: - Disable scheduled…
### Issue: When running the scheduled action "Payroll: Generate pdfs" for several payslips, nothing is generated and a traceback can be seen in the logs. ### Steps to reproduce: - Disable scheduled action: "Payroll: Generate pdfs" (to avoid side effect in next step) - Refuse all time off for "Anita Oliver" (to avoid side effect in next step) - Create a user for the employee "Anita Oliver" - Link the employee and the user - Create 2 payslips - 1 for "Mitchell Admin" - 1 for "Anita Oliver" - Compute sheet and confirm both payslips - Run scheduled action: "Payroll: Generate pdfs" - Nothing happens ### Cause: The traceback is raised on the line `self._get_document_partner().id` because `_get_document_partner()` can return a recordset. ### Solution: Call `ids` instead of `id`. ### Note: Calling `_get_document_partner()` on a recordset [here](https://github.com/odoo/enterprise/blob/a0729c8d42ca93016b23e331d8f38c1f4fa88f12/hr_payroll/models/hr_payslip.py#L444) seems unexpected as, if only one payslip in the recordset has `self.employee_id.user_id.partner_id` evaluating to `True`, then it will return only this partner, completely ignoring the other part checking `self.employee_id.work_contact_id`. The final code works fine as `_check_create_documents()` is called again individually [here](https://github.com/odoo/enterprise/blob/a0729c8d42ca93016b23e331d8f38c1f4fa88f12/documents/models/ir_attachment.py#L86). opw-5213979 Forward-Port-Of: odoo/enterprise#101911
This update resolves two issues impacting the website editing experience. Firstly, it fixes blurry countdown canvases and text when zooming, ensuring sharp visuals at any scale. Secondly, it prevents text overlap with icons, particularly when using the search bar or selecting media options, improving usability and design clarity.
Original PR description
## [FIX] website: prevent blurry countdown canvas and text on zoom [Commit 1] Steps to reproduce: - Go to Website -> Edit Mode - Add a Countdown snippet (size: "Small") - Save and zoom in/out, the…
## [FIX] website: prevent blurry countdown canvas and text on zoom [Commit 1] Steps to reproduce: - Go to Website -> Edit Mode - Add a Countdown snippet (size: "Small") - Save and zoom in/out, the countdown canvas and text appears blurry The countdown was rendered at a low resolution, which caused it to blur when zooming. This fix updates the canvas to draw at the proper resolution so the countdown remains sharp at any zoom level. ## [FIX] web_editor: prevent text overlap with icon [Commit 2] Steps to reproduce: - Go to Website -> Edit Mode - Add a Image snippet - Enter a long text in search bar: Issue: 1. Text overlaps with search icon. 2. Selecting the "Photos (via Unsplash)" option causes the text to overlap the dropdown icon. The fix adjusts the end padding to provide sufficient spacing between the text and the icons. task-[4771268](https://www.odoo.com/odoo/project/974/tasks/4771268) Forward-Port-Of: odoo/odoo#242706 Forward-Port-Of: odoo/odoo#213373