Monday, May 18, 2026
13 changes · saas-19.1
Resolved issues and error corrections
This update fixes an inconsistency in how rental prices are calculated when dealing with time-zoned dates. Previously, using relativedelta on UTC dates resulted in incorrect price calculations. Now, the system accurately calculates rental durations based on the original time zones of the start and end dates, ensuring consistent pricing across different time zones.
Original PR description
Relativedelta on UTC dates or time-zoned dates doesn't return the same result. In order to calculate consistent prices (price for 1 month in December = price for 1 month in January), we need to work…
Relativedelta on UTC dates or time-zoned dates doesn't return the same result. In order to calculate consistent prices (price for 1 month in December = price for 1 month in January), we need to work on time-zoned dates. Example: Consider a website in UTC+1 (Brussels timezone DST off). And a rental from the 01/12/2025 to the 31/12/2025 = by design, from the 01/01/2025 00h00 (start_date) to the 31/12/2025 23h59 (end_date). Converted in UTC for the back-end, we have: from the 30/11/2025 23h00 to the 31/12/2025 22h59. relativedelta(end_date, start_date) = time between the 2 dates is calculated as follow: 30/11/2025 23h00 + 1 month = 30/12/2025 23h00 +23h59 = 31/12/2025 22h59. Time difference = 1 month, 23 hours, 59 minutes. Price = 2 months. Consider a second rental from the 01/01/2026 to the 31/01/2026. 31/12/2025 23h00 + 30 days = 30/01/2026 23h + 23h59 = 31/01/2026 22h59. Time difference = 30 days, 23 hours, 59 minutes. Price = 1 month. opw-5130762 Forward-Port-Of: odoo/enterprise#114212 Forward-Port-Of: odoo/enterprise#98571
This update resolves a bug that caused incorrect redirects to the receipt screen when using eWallet with automatic receipt printing and skipping the preview screen in Point of Sale. The removal of a redundant property ensures the correct feedback screen is displayed, improving the user experience for eWallet transactions.
Original PR description
- Remove unused `paymentMethodId` prop from FeedbackScreen which caused incorrect redirect to receipt screen instead of feedback screen when using eWallet with "Automatic Receipt Printing" and "Skip Preview Screen" enabled. - The prop `paymentMethodId` is already removed in versions > `19.0`. task-id: 6008245 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#252176
This update addresses an issue where customers could have orders automatically confirmed when a gift card fully covered a shopping cart. Now, Odoo will require the standard checkout step to be completed, even if a gift card brings the total to zero, ensuring accurate order processing and preventing potential errors.
Original PR description
**Before this commit** If a gift card balance fully covers a shopping cart containing multiple events, Odoo auto-confirms the order as soon as the last event is added, skipping the final checkout step. **After this commit** Sale orders will no longer be automatically confirmed when a customer registers for a paid event, even if an applied gift card brings the total balance to zero. opw-5896626 Forward-Port-Of: odoo/odoo#264599 Forward-Port-Of: odoo/odoo#246629
This update corrects a technical issue in the French Intrastat export process. Previously, crucial quantity data related to supplementary units wasn't being included in the DEBWEB2 XML file, leading to incomplete reporting. This fix ensures accurate Intrastat reporting for products with supplementary units, improving data integrity.
Original PR description
Steps to reproduce 1. In a French company with Intrastat enabled, set up a product whose commodity code has a CN supplementary unit (e.g. 8802 30 00, "p/st") and set…
Steps to reproduce
1. In a French company with Intrastat enabled, set up a product whose commodity code has a CN supplementary unit (e.g. 8802 30 00, "p/st") and set `intrastat_supplementary_unit_amount` on it.
2. Post EU customer invoices for that product.
3. Export the DEBWEB2 XML from the Intrastat report.
Issue
The FR export collapses engine rows a second time in `_group_items`, because the DEBWEB2 format groups more aggressively than the SQL. The aggregator only declares `value` and `weight`: https://github.com/odoo/enterprise/blob/6ae5d3df6e9305416e4d6f74259cd01753025f42/l10n_fr_intrastat/models/account_intrastat_report.py#L308-L313 Items are then rebuilt as `dict(zip(grouping_key, key_tuple)) | grouped_item_values`. `SU_code` survives (it is in the grouping key), but the numeric `supplementary_units` is in neither side and is silently dropped as soon as two engine rows merge. The template then skips the element because of its `t-if="item.get('supplementary_units')"` guard: https://github.com/odoo/enterprise/blob/6ae5d3df6e9305416e4d6f74259cd01753025f42/l10n_fr_intrastat/data/intrastat_export.xml#L61
opw-6139657
Forward-Port-Of: odoo/enterprise#117357
Forward-Port-Of: odoo/enterprise#117033This update resolves a crash that occurred when users switched to edit mode while an event registration modal was open. The fix ensures the modal is properly cleaned up after the transition, preventing errors related to accessing the modal's style properties. This improves stability and prevents unexpected application behavior.
Original PR description
Steps to reproduce: =================== 1. Go to Event, open an event page 2. Click "Register" & Select a ticket and confirm 3. Switch to edit mode => crash. Cause: ====== The cleanup callback called…
Steps to reproduce: =================== 1. Go to Event, open an event page 2. Click "Register" & Select a ticket and confirm 3. Switch to edit mode => crash. Cause: ====== The cleanup callback called `hide()` followed immediately by `dispose()`. Bootstrap's `hide()` is asynchronous — it registers a `transitionend` callback that fires `_hideModal()` after the CSS transition. `dispose()` nullifies `this._element` synchronously via `BaseComponent`, so when the `transitionend` fires and `_hideModal()` tries to access `this._element.style`, it crashes with: TypeError: Cannot read properties of null (reading 'style') This happened when switching to edit mode while the event registration modal was open: the `public.interactions` service stopped the interaction, triggering the cleanup. Solution: ========= Listen for `hidden.bs.modal` (fired at the end of `_hideModal`) and only `dispose()` inside that handler, ensuring `_element` is still valid throughout the transition. task-6133395 Forward-Port-Of: odoo/odoo#264365
This update ensures Odoo correctly sets the `toStateCode` field for SEZ transactions when generating e-waybills. Previously, this was a source of API errors, particularly for export and supply transactions. By enforcing the required `toStateCode` of 99, this fix ensures compliance with e-waybill regulations and prevents disruptions to shipping.
Original PR description
For SEZ transactions, the e-waybill API requires `toStateCode` to be set to 99. Previously, this value was not enforced, leading to API errors: - 373 for export transactions - 641 for supply and CKD/SKD/lots supply This fix updates the logic to derive `toStateCode` based on the invoice's GST treatment. When the transaction is identified as SEZ, `toStateCode` is correctly set to 99, ensuring compliance with e-waybill requirements and preventing API failures. task-6117694 Forward-Port-Of: odoo/odoo#259327
This update resolves an issue where multi-company orders were incorrectly assigning fiscal positions, leading to 'incompatible companies' errors. The fix ensures the sale order's company is used when calculating the fiscal position, guaranteeing accurate accounting and order confirmation. This improves order processing reliability in our multi-company setup.
Original PR description
Issue: --- Due to this issue, in multi-company environment, wrong fiscal position might be assigned to the order, leading to `incompatible companies` error. Steps to reproduce: 1- On multi-company…
Issue: --- Due to this issue, in multi-company environment, wrong fiscal position might be assigned to the order, leading to `incompatible companies` error. Steps to reproduce: 1- On multi-company setup, assign a website to the second company. 2- Configure pickup method for second company. 3- Configure fiscal positions for both companies. 4- Setup auto invoice for second company. 5- Using public user, add a product to cart and checkout. 6- Use pickup method, and pay. The order is not confirmed. If you enable debug mode after payment, it will show an `incompatible companies` error. Cause: --- https://github.com/odoo/odoo/blob/43f5ceadbc1f7df9898c327bf65bffdbe9860c1c/addons/account/models/partner.py#L247-L279 `_get_fiscal_position` is using environment company to compute the fiscal position. However, `_compute_fiscal_position_id` causing the issue here is triggered inside `report_saleorder` template with user set as odoobot when trying to to send the confirmation. As a result, the odoobot company's fiscal position will be used causing this issue. Fix: --- We should ensure company from sale order is used by setting it as env company. opw-6186296 Forward-Port-Of: odoo/odoo#264123
This fix resolves an issue where payroll account merges incorrectly combined employee payments, leading to inaccurate analytic distribution reporting. The update ensures that each employee's specific analytic distribution is correctly applied, preventing data aggregation and maintaining accurate financial reporting. This improves the reliability of payroll accounting data.
Original PR description
Steps to reproduce 1. Enable "Batch Account Move Lines" in the Payroll settings. 2. Configure two employees' versions with an analytic distribution on the same analytic account but with different…
Steps to reproduce
1. Enable "Batch Account Move Lines" in the Payroll settings.
2. Configure two employees' versions with an analytic distribution on the
same analytic account but with different percentages (e.g. {acc: 50}
for the first employee and {acc: 70} for the second).
3. Generate a payslip run containing both employees and validate it.
Issue
The generated account move aggregates the two payslips into a single
line whose analytic_distribution matches only the last employee being
processed; the other employee's percentage is silently lost.
`_get_existing_lines` decides whether an incoming line can merge into an
already accumulated one. When the incoming line has an analytic
distribution, the merge condition delegates to
`_check_partially_matching_accounts`:
https://github.com/odoo/enterprise/blob/e4a1326c7a8a74da7970aeaa9900c19d01634e31/hr_payroll_account/models/hr_payslip.py#L254-L271
https://github.com/odoo/enterprise/blob/e4a1326c7a8a74da7970aeaa9900c19d01634e31/hr_payroll_account/models/hr_payslip.py#L273-L283
That helper returns True as soon as any analytic account of the new
line appears anywhere in the existing line's distribution dict, without
comparing percentages. Two distributions such as {acc: 50} and
{acc: 70} share the same account, so the helper returns True, the
lines are merged, and whichever distribution ends up on the merged line
overwrites the other — the total amount is correct but the analytic
split is wrong.
The logic introduced in commit https://github.com/odoo-dev/enterprise/commit/e40a3166286a6bc546e9543b935233d2a110dc52 successfully addressed merging for rule-level distributions
with composite keys (e.g., {'13,7,12': 40}). However, that implementation is overly inclusive for employee-specific distributions.
It fails to differentiate between cases where the same analytic account is utilized across various employees but with different percentage allocations.
Because it only checks for an account overlap rather than a perfect distributional match, it incorrectly aggregates distinct financial dimensions into a single journal line
Solution
Compare the full analytic_distribution dict by strict equality. Lines
merge only when the distribution is identical (same keys AND same
percentages), keeping the batch feature anonymizing identically
configured employees while preserving one line per distinct
distribution.
opw-6102508
Forward-Port-Of: odoo/enterprise#114156This update resolves a bug that prevented users from opening the payroll module when creating overtime attendance records. The fix addresses an issue where the system was receiving duplicate overtime data, causing an error. This ensures payroll processing functions correctly for all attendance scenarios.
Original PR description
Steps to reproduce: - Install `hr_work_entry_attendance` module - Create an Employee and set contract date - Attendance > Create attendance for Employee(eg: [image](https://www.awesomescreenshot.com/image/58801595?key=ecc9a2f5ec51cb569432e5bf580540f9)) - Add a new line in Overtime Details (eg: [image](https://www.awesomescreenshot.com/image/58801650?key=f5a886217299bca8bbece27839377bf4)) - Try to open `Payroll` Traceback: `ValueError: Expected singleton: hr.attendance.overtime.line(309, 310)` At [1], this error occurs because we are getting multiple records of `hr.attendance.overtime.line` in `overtime_intervals`. [1]: https://github.com/odoo/enterprise/blob/62f59f87a513a86a61f871ca743e7f7b04926a82/hr_work_entry_attendance/models/hr_version.py#L82 sentry-7251235434
This update resolves an issue where intercompany invoices were flagged with an incorrect tax validation error. The fix ensures that taxes are correctly recalculated when processing invoices between companies with different fiscal positions, improving the accuracy of intercompany accounting. This prevents disruptions to cross-border transactions.
Original PR description
**Steps to reproduce:** * Install the *Accounting* module. * Install localisation modules for two different regions: * *Belgium* (**l10n_be**) * *Luxembourg* (**l10n_lu**) * Configure two companies,…
**Steps to reproduce:** * Install the *Accounting* module. * Install localisation modules for two different regions: * *Belgium* (**l10n_be**) * *Luxembourg* (**l10n_lu**) * Configure two companies, each assigned to one of the above regions. * Create fiscal positions: * In the Belgium company, create a fiscal position for Luxembourg. * In the Luxembourg company, create a fiscal position for Belgium. * Go to *Accounting > Configuration > Settings*. Enable *Inter-Company Transactions*. Enable synchronization of *Vendor Bills and Invoices* for both companies. * Create an invoice in the Luxembourg company. Select a partner belonging to the Belgium company. Add a product with applicable taxes. **Observed behavior:** * A validation error is raised: 'This entry contains taxes that are not compatible with your fiscal position. Please check the country set in the fiscal position and in your tax configuration.' **Cause:** * During intercompany bill creation, a foreign fiscal position is applied before recomputing taxes. * If no mapped foreign taxes exist, the system keeps domestic purchase taxes. * This leads to a mismatch between taxes and fiscal position, triggering the validation error. **Fix:** * Add a safeguard in *_inter_company_create_invoices()*. * After *_inter_company_sync_invoice_line_taxes()* recomputes taxes, *_inter_company_has_incompatible_fiscal_position_taxes()* checks whether the fiscal position is incompatible. * If incompatible, the fiscal position is removed and taxes are recomputed without it. opw-6103671 Forward-Port-Of: odoo/enterprise#117450 Forward-Port-Of: odoo/enterprise#115085
This update fixes an error in the Italian Annual VAT Report that was incorrectly calculating the balance amount for line VF25. The fix ensures the report accurately reflects the total taxable base as required by Italian tax regulations. This ensures compliance with Italian tax reporting standards.
Original PR description
### Issue before this commit: In the Italian Annual VAT Report, the balance (base amount) for line VF25 displays incorrect values. Instead of computing the sum of the taxable bases for the passive…
### Issue before this commit: In the Italian Annual VAT Report, the balance (base amount) for line VF25 displays incorrect values. Instead of computing the sum of the taxable bases for the passive operations, the report erroneously mixes tax amounts into the balance column. ### Steps to reproduce the issue: 1. Download Accounting and l10n_it 2. Go to Tax Report and visualize the Annual Tax Report (IT) 3. Go to VF VAT Report 4. See the VF25 is mixing taxes and balances ### Cause of the issue: The root cause lies in the aggregation_formula definition for the tax_annual_report_line_VF25 record. The formula was incorrectly configured to aggregate the .tax expressions for lines VF1 to VF13 (VF1.tax + VF2.tax + ...) instead of their respective .balance expressions, while correctly using .balance for the remaining lines (VF17 to VF24). https://github.com/odoo/odoo/blob/878c08cf522a3278b4e6ff5f3d18444989e9998d/addons/l10n_it/data/tax_report/annual_report_sections/vf.xml#L286-L299 It's just a typo in this commit: https://github.com/odoo/odoo/pull/164064/changes/f292ba119d6376dbfb3c1fac4960c9c56a74d938 ### Reason to introduce the fix: From documentation https://www.agenziaentrate.gov.it/portale/documents/20143/9602686/IVA_ANNUALE_2026_istr.pdf/2a42fb92-1b76-229a-d0f5-06069d79b514?t=1768504755711 : > Rigo VF25, colonna 1, va indicato il totale degli imponibili determinato sommando gli importi riportati ai righi da VF1 a VF23, colonna 1, diminuito dell’importo di cui al rigo VF24. In colonna 2 va indicato il totale delle imposte determinato sommando gli importi delle colonne 2 dei righi da VF1 a VF13. opw-6172791 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264379
This update resolves a restriction in the l10n_mx_edi module that prevented credit notes (out-refunds) from using Payment Policy Defaults (PPD). Previously, the Mexican SAT portal required PPD for certain credit note types, but this functionality was not available within Odoo. This change aligns Odoo with SAT requirements, streamlining the process for Mexican businesses.
Original PR description
Currently, credit notes cannot be PPD (payment_policy), however, SAT portal allows it. **STEP TO REPRODUCE** 1. Install the l10n_mx_edi module. 2. Create an invoice with PPD (either changing it or through payment terms). 3. After send CFDI, generate a credit note and try to set PPD **FIX** Allow move_type = 'out_refund' to be PPD. Task-6049654 Forward-Port-Of: odoo/enterprise#114886
This update fixes a bug that caused remote meeting tabs to crash when the host ended a call. The change ensures that call action elements handle call disappearances gracefully, preventing errors and maintaining the existing user interface. This improves stability and reliability for users accessing meetings from multiple tabs.
Original PR description
**Steps to Reproduce:** - Start a new meeting (Host Tab). - Duplicate the tab or open the same meeting URL in another tab (remote tab). - In the remote tab, open the call menu (dropdown). - From the…
**Steps to Reproduce:** - Start a new meeting (Host Tab). - Duplicate the tab or open the same meeting URL in another tab (remote tab). - In the remote tab, open the call menu (dropdown). - From the host tab, disconnect/end the call. - Crashes on Remote Tab. **Current behavior before PR:** Before this PR, duplicating a meeting tab could leave the remote tab with a stale call action dropdown after the host ended the call. Since some action properties and handlers still assumed that selfSession and channel were always available, interacting with the dropdown could crash with errors. **Desired behavior after PR is merged:** After this PR, call action labels/classes defensively tolerate missing selfSession or channel references, and stale click handlers gracefully no-op when the call disappears mid-interaction. This prevents remote tab crashes during call teardown while preserving the existing UI behavior. task-[6191740](https://www.odoo.com/odoo/project/1519/tasks/6191740) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr