Monday, March 30, 2026
12 changes · saas-18.4
Resolved issues and error corrections
This fixes Swiss point-of-sale invoices paid later so they can still include the needed bank information for QR payment slips. Businesses using Swiss POS invoicing should see complete invoices even when no payment journal is selected at checkout.
Original PR description
Step to reproduce: - Install l10n_ch_pos and make sure swiss company has tax id filled - Create a swiss customer with an email address and vat, add full address - Open a pos session, and make an invoice for a product with tax, - select payment method, which allows `pay_later`, i.e. payment without journal_id Observation: - the invoiced order, do not have qr for payment, because the invoice do not have `bank_partner_id` Cause: - `_get_partner_bank_id` is recently updated in commit[1], which do not considered `pay_later` option [1] https://github.com/odoo/odoo/commit/7e63991dceb6e443b950e6a1b94454a82d5668c7 Fix: - Fixed the fallback logic for `_get_partner_bank_id` opw-6023060 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#254892 Forward-Port-Of: odoo/odoo#254117
This fixes a Microsoft Calendar sync issue where a changed first occurrence of a recurring meeting could cause Odoo to recreate the series incorrectly. The change preserves Microsoft event links, preventing duplicate Outlook events and unnecessary meeting notifications.
Original PR description
When an attendee syncs a recurring event where the first occurrence (base event) was modified by the organizer, `_write_from_microsoft` falsely triggers the destructive recreation path. This happens because `_has_base_event_time_fields_changed` compares the exception's modified time against the seriesMaster's pattern time, detecting a "change" even though the master hasn't changed. This causes: - All non-base events lose their microsoft_id and ms_universal_event_id - The base event gets recreated without Microsoft IDs - A duplicate event is pushed to Outlook on the next odoo2microsoft sync - Spurious "join the meeting now" notifications are sent to attendees Add a `follow_recurrence` guard so that when the base event is an exception (follow_recurrence=False), the non-destructive else branch is taken instead, preserving all Microsoft IDs. Forward-Port-Of: odoo/odoo#256263 Forward-Port-Of: odoo/odoo#254414
Flutterwave payment requests now send customer phone numbers in the simpler format expected by the payment provider. This reduces failed payments caused by the recent “invalid billToPhone” error, helping customers complete checkout more reliably.
Original PR description
With are recently seeing an increasing number of payments that fail with an `invalid billToPhone` error. It's unclear if it's a recent change of flutterwave API or of any intermediary payment processor, but the flutterwave v4.0.0-beta API now state to send the phone number "unformatted" - even if there is no such statement for the v3.0.0 API (that we are using), based on testing, sending the phone number "unformatted" do so seems do solve the issue. So this commit, sanitize the phone number to send it unformatted. opw-6074825 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#256315
This fixes how web links are handled in Odoo messages so that special characters are encoded correctly. It also prevents cases where a link could appear differently in the interface than the address that was actually sent, improving user trust and reducing confusion.
Original PR description
Before this commit, the URL was fully encoded using encodeUrl. This commit replaces this approach with the more modern [URL api](https://developer.mozilla.org/en-US/docs/Web/API/URL), which [handles encoding](https://url.spec.whatwg.org/#dom-url-href) properly. This commit also removes decodeUrl. It was possible for a user to send a URL and have a different one displayed in the UI due to decoding. Task-6041689 Forward-Port-Of: odoo/odoo#256425 Forward-Port-Of: odoo/odoo#254383
Purchase order line descriptions now update the vendor code and vendor name correctly when the vendor changes, including dropship flows from sales orders. This helps buyers avoid confusion and reduces the risk of ordering with outdated supplier references while preserving user-customized descriptions.
Original PR description
How to reproduce : - Create a product - Create an attribute with a value set to "free text" - Add 2 different vendors to the purchase tab of the product with different Vendor Code and/or Vendor Name…
How to reproduce : - Create a product - Create an attribute with a value set to "free text" - Add 2 different vendors to the purchase tab of the product with different Vendor Code and/or Vendor Name - Put Dropship as the route for the product to create a PO on a SO confirmation - Create a SO with that product - Confirm the SO and go to the PO - Change the vendor in the SO The problem : The Vendor Code and/or Vendor Name does not change correctly in the product description Why : The way the description generation for a change in a purchase order line works as follows : Create a collection of default descriptions based on the product and the different vendors. If the collection contains the current description, it means the description was not changed by the user and it can be modified. This is done to prevent resetting a custom description made by an user. This logic is pretty broken because the code that generate the description when going from a PO to a SO and the code that generate the description when changing the PO partner are different. This makes it so the current description is almost never found in the list of default descriptions. It looks tempting to try to "resynchronize" those part of the code so the description generation is the same in both cases. This would be done by overriding the _get_product_purchase_description method in the purchase_stock module and using the product_description_variants field. Sadly, this does not work because it conflicts with the purchase_product_matrix module and its own override of that method. The fix that I implemented checks that the Vendor Code and Name are the right one every time the description is computed following a change. opw-5888233 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#255453 Forward-Port-Of: odoo/odoo#247330
This fix stops tax-inclusion settings from being changed while a Point of Sale session is still open. It prevents mismatches between POS receipts and backend invoices by enforcing the existing tax-change safeguard on the newer setting.
Original PR description
There is a safeguard in account.tax.write prevents modifying taxes as it is forbidden to modify a tax used in a POS order not posted. This guard only applies for a predefined set of fields in…
There is a safeguard in account.tax.write prevents modifying taxes as it is forbidden to modify a tax used in a POS order not posted. This guard only applies for a predefined set of fields in account_tax.py. After 18.0, the tax-included behavior is controlled through the `price_include_override` field instead of `price_include`. However, this field was not added in the forbidden fields, allowing users to modify tax inclusion while a POS session is open. This bypasses the safeguard and can lead to inconsistencies, as the POS caches tax configuration at session start. For example, changing this setting mid-session may differences between POS receipts and backend invoices. By adding `price_include_override` to the forbidden fields, the UserError can properly be raised. Additional note: test_fiscal_position_between_frontend_and_backend was updated to close the POS session before changing taxes since the safeguard now correctly blocks this. Related ticket: opw-6042367 Forward-Port-Of: odoo/odoo#255895 Forward-Port-Of: odoo/odoo#254487
The Serbian e-invoicing connection has been updated to use the government’s current submission address. This helps ensure Serbian electronic invoices can continue to be sent successfully without disruption.
Original PR description
**PROBLEM** The url to send e-invoice to the serbian government has changed. opw-6055622 Forward-Port-Of: odoo/odoo#256095
This update corrects an issue preventing the export of Profit & Loss reports with footnotes enabled in the l10n_lu_reports module. The fix addresses a dependency on an outdated model, ensuring proper XML generation and report functionality. This resolves a technical problem impacting report generation for Luxembourg accounting.
Original PR description
**Steps to reproduce:** * Install the **l10n_lu_reports** module. * Go to **Accounting → Reporting → Profit & Loss**. * Add a footnote on a report line (**⋮ → Annotate**). * Click **Export (XML)** to open the export wizard. * Enable **Import notes as references** and export. **Observed behavior:** * Export fails with `KeyError: 'account.report.manager'`. * XML file cannot be generated when references are enabled. **Cause:** * The export logic relied on the deprecated `account.report.manager` model. * This model was removed in v17([commit](https://github.com/odoo/enterprise/pull/33604/changes#diff-5fc5051f5c0211c0eec96b892e7d29e01b68d804417443502d17bccd8333d7ecL41)) and replaced by `account.report.footnote`. * The footnote retrieval code was not migrated accordingly. **Fix:** * Migrate reference retrieval to use `account.report.footnote`. opw-5890630 Forward-Port-Of: odoo/enterprise#111845 Forward-Port-Of: odoo/enterprise#107765
This update fixes an issue where tax returns for Italian companies incorrectly included pension fund taxes, leading to discrepancies between reports and the backend view. The change excludes these taxes from the tax return calculation, ensuring accurate reporting and alignment with customer data. This resolves a prior inconsistency.
Original PR description
The "amount to pay" incorrectly included the Pension Fund taxes, causing inconsistencies between the report and what the customer was able to see in the backend. Now we exclude them from the tax return domain. Steps to reproduce: - Create an Italian company with the Italian CoA - Install `l10n_it_edi_withholding` (not necessary in v19) - Create an invoice - Set the 4% INPS or 4% F.Pens taxes on a line, along with with a normal 22% VAT - Create a tax return Ticket [link](https://www.odoo.com/odoo/project.task/5909407) opw-5909407 Forward-Port-Of: odoo/enterprise#111311
This update fixes an issue where scanning a different serial number than the reserved one during batch processing didn't create a new lot. The fix ensures that the correct lot is always used when scanning a batch, preventing incorrect inventory tracking. This improves data accuracy and reliability.
Original PR description
Issue ----- When processing batches in barcode, scanning a BC with a different SN than the reserved one does not lead to creating a new lot in stock. The reserved one is still the one getting taken…
Issue
-----
When processing batches in barcode, scanning a BC with a different SN than the reserved one does not lead to creating a new lot in stock. The reserved one is still the one getting taken regardless of setting.
Steps to reproduce
-----
- Enable GS1 nomenclature, lots & batches
- Go to Inventory > Configuration > Operation Types > Delivery Orders
- Enable Lots/Serial Numbers > Create New
- Create a product
- Barcode 23456789012344
- Tracked by SN
- 1 in stock (SN 1234)
- Create a delivery for the product and add it to a batch
- Open the batch in barcode
- Scan 012345678901234410BATCHSN1
- Confirm the delviery
- Go back to the picking and see the lines' details
> The line used the reserved SN
Cause
-----
The existing line gets matched in `_findLine`
https://github.com/odoo/enterprise/blob/45d3a537c3b2eaccee425d959e89d26229e376cd/stock_barcode/static/src/models/barcode_model.js#L1085
because none of the conditions before
https://github.com/odoo/enterprise/blob/45d3a537c3b2eaccee425d959e89d26229e376cd/stock_barcode/static/src/models/barcode_model.js#L1402
get matched. This is unexpected but necessary for batches, as it ensures barcode correctly swaps to the correct picking in the batch. If the line was not matched we would be creating a new line in the same picking than the last scanned line, regardless of which picking the reservation is made in.
Because a line is matched, we have to force its' `lot_id` to `false` so that the new one gets created (`lot_name` is used for display but `lot_id` takes precedence).
-----
Ticket:
opw-5216921
Forward-Port-Of: odoo/enterprise#111956
Forward-Port-Of: odoo/enterprise#109671This update fixes an issue where users were incorrectly grouping POS orders in the l10n_pe_edi_pos module. The system now validates order groupings, preventing errors and providing clear messages to users attempting to combine invoices without the necessary shared identifiers. This ensures accurate reporting and compliance for Peruvian businesses.
Original PR description
Joining the values in the selection field with a coma, and then putting everything in another selection field was plain wrong. We now check a bit better what we're generating, and refrain the user with error messages when they try grouping on the same invoices orders that do not share the necessary key values. Forward-Port-Of: odoo/enterprise#111616
This update resolves an issue where the VAT partner listing report was not displaying all customers. The fix involves adjusting a setting to load all partners, ensuring accurate reporting for VAT compliance in Belgium. This ensures all relevant financial data is available for analysis.
Original PR description
With l10n_be company: - Create at least two invoices for two different customers (companies) for whom you will add a fake VAT number. Make sure the total on both your invoices is more than 250€ and…
With l10n_be company: - Create at least two invoices for two different customers (companies) for whom you will add a fake VAT number. Make sure the total on both your invoices is more than 250€ and set their Accounting date to last year. - Go check the VAT partner Listing report (Accounting > Reporting); make sure you see both partners in the listing. - Click on returns > Check that report return then Submit and download the XML file: both partners & amounts will appear. - Now with dev mode, go to Accounting reports, open the Partner VAT listing form > Options > set the "load more limit" to 1. Download the XML again: only the first partner appears (the only that was loaded with the load more limit. This commit is a backport of bugfix: PR odoo/enterprise#106134 commit e532750fe3dc1f2d10d995d01446b04a3a227a72 Original problem introduced in `saas-18.3`: PR odoo/enterprise#111783 commit 4c927b389252b595bcbb44d020899ae5abf0aa89 Ticket [link](https://www.odoo.com/odoo/project.task/6051120) opw-6051120 Forward-Port-Of: odoo/enterprise#111783