Thursday, May 28, 2026
7 changes · saas-18.3
Resolved issues and error corrections
This update resolves an issue where partner names with '&' characters were incorrectly formatted during SEPA export, leading to bank rejections. The fix ensures '&' is preserved in human-readable fields like partner names and addresses, aligning with banking standards and preventing export failures.
Original PR description
Problem: The previous fix (replacing '&' with '+' in _replace_characters_SEPA) was applied globally, affecting both reference/identifier fields and human-readable fields such as <Nm> (partner name)…
Problem:
The previous fix (replacing '&' with '+' in _replace_characters_SEPA) was applied globally, affecting both reference/identifier fields and human-readable fields such as <Nm> (partner name) and address lines.
As a result, a partner named "test & test GMBH" was exported as:
<Nm>test + test GMBH</Nm>
instead of the expected:
<Nm>test & test GMBH</Nm>
This caused bank file rejections because '&' is the correct XML encoding of '&' and is accepted by banks in human-readable fields.
Root cause:
ISO 20022 / EPC217-08 distinguishes two categories of data elements:
- Reference/identifier fields (InstrId, Ustrd, etc.): must use the restricted basic Latin character set — '&' is not allowed and must be replaced with '+'.
- Human-readable fields (Nm, AdrLine, etc.): may contain the extended Latin character set — '&' is valid and must be preserved so lxml can XML-escape it to '&' in the output.
Fix:
Revert the global '&' → '+' replacement in _replace_characters_SEPA so that '&' is preserved for name/address fields. The replacement of '&' with '+' for reference/identifier fields is already handled explicitly at the call sites in _get_CdtTrfTxInf (InstrId, Ustrd) via .replace('&', '+') before sanitize_communication is called.
ref commit : https://github.com/odoo/enterprise/pull/110809/changes/9e698e4ac9fdf66189ff6712f90a144560a1b484
documentation https://www.europeanpaymentscouncil.eu/sites/default/files/KB/files/EPC217-08%20Draft%20Best%20Practices%20SEPA%20Requirements%20for%20Character%20Set%20v1.1.pdf:
Forward-Port-Of: odoo/enterprise#118511
Forward-Port-Of: odoo/enterprise#115409This update resolves a previous issue where transaction details weren't consistently saved for Viva Wallet payments, regardless of whether they were processed via webhook or polling. The fix ensures that all relevant payment information, including card details, is now accurately recorded, improving the reliability of our point-of-sale reporting.
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#266629
This update fixes an issue where the expected hours displayed in the Attendances Gantt view didn't accurately reflect flexible work schedules, particularly when users' browsers were set to non-UTC timezones. The change ensures accurate hour calculations based on the user's local timezone, improving the reliability of attendance tracking.
Original PR description
Steps to reproduce: 1. Ensure your browser is in a non-UTC timezone (e.g. Europe/Zurich) 2. Set an employee to have a flexible working schedule 3. Enter the Attendances app 4. When hovering over the employee in the gantt view, the expected hours do not match their working schedule When we calculate the expected hours for the Gantt view in attendances, we calculate this based on an incorrect number of attendance intervals given from _attendance_intervals_batch(). To ensure that we recieve accurate intervals, we need to ensure that we calculate intervals based on the correct date range with respect to the browsers timezone, instead of the UTC date range. [opw-6175441](https://www.odoo.com/odoo/my-tasks/6175441?debug=assets) Forward-Port-Of: odoo/enterprise#116807
This update resolves a technical issue preventing Viva payments in the POS kiosk. The Viva payment system requires a unique identifier for the cash register, which was previously missing. This fix ensures the correct 'cashRegisterId' is sent, allowing Viva payments to process successfully and avoiding errors.
Original PR description
When validating a payment in POS Kiosk with Viva payment method we get a Viva.com error Viva’s card-terminal API validates the JSON body with Pydantic and requires a non-empty ``cashRegisterId``. Steps to reproduce: ------------------- * Open POS in kiosk * Make an order and pay with Viva > Observation: Viva returns a validation error: ``cashRegisterId`` is missing or required in the request body (Pydantic ``missing`` on ``body.cashRegisterId``). Why the fix: ------------ Compute ``cashRegisterId`` in the POS client as cashier name, then ``pos.config.name`` so the value is always a non-empty string sent to ``viva_wallet_send_payment_request``. opw-6091223 Forward-Port-Of: odoo/odoo#265817 Forward-Port-Of: odoo/odoo#258605
This update fixes an issue where the import process wasn't correctly reading invoice due dates from FatturaPA invoices. Now, the system accurately captures the due date for issued invoices, ensuring proper payment tracking. This resolves a previous error that defaulted due dates to today's date.
Original PR description
The import procedure stopped reading DataScadenzaPagamento (invoice date due) on `out_invoice`s and `in_refund`. As a side effect, invoice_date_due fell back to today() on those documents. This commit restores reading the invoice date due, and keeps the condiitonal logic only for the bank account and payment_reference logic incoming-only as it was before. Forward-Port-Of: odoo/odoo#264762 Forward-Port-Of: odoo/odoo#264573
This update ensures that the project associated with a sales order is automatically included in the generated Manufacturing Order, even with multi-step delivery routes (Pick + Deliver). Previously, this wasn't happening, causing issues with tracking projects in complex order flows. This change improves order management and reporting accuracy.
Original PR description
### Issue before this commit: When confirming a Sale Order with multi-step delivery routes (Pick + Deliver), the generated Manufacturing Order did not inherit the project_id from the Sale Order, even…
### Issue before this commit: When confirming a Sale Order with multi-step delivery routes (Pick + Deliver), the generated Manufacturing Order did not inherit the project_id from the Sale Order, even though the project was correctly set on the SO. ### Steps to reproduce the issue: 1. Download Inventory, Sales, PLM, Project 2. Enable multi-step routes in settings and unarchive MTO from routes 3. Go to Products and modify 1. Furniture Assembly inserting Project in "Create on Order" attribute and a test project template 2. Drawer selecting MTO and Manifacture in Inventory tab 4. Create a new quotation inserting 2 products: Furniture Assembly and Drawer and confirm it 5. Go to "Manufacturing" smart button 6. See in Miscellaneous tab the Project is setted as default 7. Go to warehouses, select the WH of your company and select Pick then Deliver (2 steps) as Outgoing Shipments 8. Go to Routes, select Deliver in two steps (pick + ship) and change "Destination location" of "Pull From" from Parteners/Customers into WH/output 9. Go to Rules: 1. "Pull From" (the one with Partener/Customers as destination location and MTO as route): change "Destination location" of from Parteners/Customers into WH/output 2. "Push To" (the one with Partener/Customers as destination location and with the deliver in 2 steps as route): change action from "Push To" to "Pull from" 10. Create a new quotation inserting 2 products: Furniture Assembly and Drawer and confirm it 5. Go to "Manufacturing" smart button 6. See in Miscellaneous tab the Project is not setted ### Cause of the issue: https://github.com/odoo/odoo/blob/d1955028bb95eff8d33c1c2b1c211d8520bb33a2/addons/sale_project_stock/models/stock_move.py#L71-L76 This function retrieves the project only based on the sale_line_id, which is correctly populated in a one-step delivery because the procurement is directly linked to the Sales Order (SO). However, the sale_line_id is not propagated to procurements that are not directly linked to the SO. In this scenario, with a two-step delivery, there are two stock moves: from Stock to WH/Output, and from WH/Output to the Customer. Only the second move (WH/Output > Customer) is linked to the SO, while this information is not propagated to the first move. As a result, the project_id information is lost. ### Reason to introduce the fix: Be sure that the project is automatically setted in the MO when a SO is confirmed whatever the intial delivery configuration is. opw-5913988 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#266808 Forward-Port-Of: odoo/odoo#261565
This update fixes an issue where the calculation of the gross total on invoices with both line and global discounts was incorrect. The change ensures that discounts are applied in the correct order, resulting in accurate gross total calculations for invoices, particularly when global discounts are involved. This improves the reliability of invoice totals.
Original PR description
Problem: When both line discounts and global discounts are applied on a product in an invoice, the method `_add_and_round_raw_gross_total_excluded_and_discount` does not return the exact…
Problem: When both line discounts and global discounts are applied on a product in an invoice, the method `_add_and_round_raw_gross_total_excluded_and_discount` does not return the exact raw_gross_total_excluded before the modification done by other AccountTax helper methods, such as dispatching and squashing global discount lines. Current Behavior: The calculation is done in the wrong order of operations. For example, there is an invoice for Product A valued at $100 with a discount of 10% and a global discount of $10. The raw_total_excluded will be $80 after the both discounts. The discount_factor is based on only the line discount of 10%. The formula of the current calculation for raw_gross_total_excluded is: (raw_total_excluded / (1 - (line_discount / 100))) - global_discount = (80 / 0.90) - (-10) = 98.889 This does not equal the expected outcome of $100. Expected Behavior: Based on the previous example, the formula for the calculation should be: (raw_total_excluded - global_discount) / (1 - (line_discount/100)) = (80 - (-10)) / 0.9 = 100 The global discount needs to be added back to the raw_total_excluded to get the line discounted amount in order to divide by the discount_factor to gain the expected raw_gross_total_excluded before taxes and discounts. Steps to reproduce the issue: - Bug was encountered when implementing a global discount solution for l10n_co_dian. - Create an invoice with a product line and in-line discount and another line for global discount - Setup the base lines for the invoice and attempt the following: - _dispatch_global_discount_lines - _squash_global_discount_lines - _add_and_round_raw_gross_total_excluded_and_discount opw-5412446 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#262137