Thursday, April 30, 2026
22 changes · saas-19.3
Enhancements to existing features
This update adjusts Odoo's reporting to align with new Indonesian tax regulations (Act 2025). Previously, reports relied on specific tax sections, but now they utilize report line names and tax tags for accurate calculations. This ensures compliance with the latest tax requirements.
Original PR description
In this commit, the XLSX export and report warning are adapted to support the newly introduced TDS/TCS reports as per Act 2025. Previously, the XLSX reports depended on TDS/TCS sections. However, with Act 2025, certain taxes no longer have associated sections. This dependency has been removed, and report generation now relies on report line names and tax tags instead. task-6124431 Forward-Port-Of: odoo/enterprise#115679 Forward-Port-Of: odoo/enterprise#113916
Resolved issues and error corrections
This update strengthens the security of Xendit payments by requiring a valid access token linked to the specific transaction being processed. Previously, payments could be executed without this verification, creating a potential risk. Now, payments are restricted to the correct transaction, improving data integrity and security.
Original PR description
**Description of the issue/feature this PR addresses:** The `/payment/xendit/payment` endpoint did not enforce validation of an access token tied to the transaction when processing direct payment requests. **Current behavior before PR:** The endpoint accepted public requests using only the transaction reference, allowing payment execution without verifying that the request was linked to the intended transaction. **Desired behavior after PR is merged:** The endpoint now requires a valid access_token associated with the transaction (reference) before processing. This ensures that payment execution is restricted to the correct transaction. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#261912 Forward-Port-Of: odoo/odoo#260258
This update ensures the IRN (Invoice Reference Number) generated during E-Invoicing is correctly saved and displayed on the invoice itself, both in the PDF and the invoice form. Previously, the IRN was only present in the PDF but not on the invoice record, now it's consistently saved for easier tracking and reporting.
Original PR description
**Steps to reproduce:** * Install module *Indian - GSTR with E-invoice (l10n_in_edi_gstr)*. * Configure *Indian integration* with required credentials (E-Invoicing, E-Way bill, etc.). * Save the…
**Steps to reproduce:** * Install module *Indian - GSTR with E-invoice (l10n_in_edi_gstr)*. * Configure *Indian integration* with required credentials (E-Invoicing, E-Way bill, etc.). * Save the settings. * Create a *customer invoice*. * Post the invoice. * Send the invoice through *E-Invoicing (EDI)*. * Open the generated *Invoice PDF* and the *form view*. **Observed behavior:** * The *IRN number* is correctly present in the *Invoice PDF*. * However, it is *not saved/displayed* in the invoice form view. **Cause:** * The invoice flow did not store the *IRN number* on the invoice after receiving the EDI response, even though the value was available. **Fix:** * Inherit *_l10n_in_edi_send_invoice*. * Add a condition after the invoice is sent and the JSON response is received. * When the *IRN number* is present in the response, set it on the *l10n_in_irn_number* field of the invoice (in lower case). opw-6097923 Forward-Port-Of: odoo/enterprise#115522 Forward-Port-Of: odoo/enterprise#114350
This update fixes an issue where the leave balance report was incorrectly calculating employee leave accruals and balances, particularly when leaves were taken over multiple periods. The fix ensures accurate reporting by addressing timezone discrepancies and improving the calculation of overlapping leave allocations. This improves the reliability of leave tracking data.
Original PR description
__ISSUE__: - FIFO balance miscalculation for non-overlapping allocations. cumulative_allocated_days was partitioned globally by (employee, leave_type), but taken_per_allocation scoped leaves to each…
__ISSUE__:
- FIFO balance miscalculation for non-overlapping allocations. cumulative_allocated_days was partitioned globally by (employee, leave_type), but taken_per_allocation scoped leaves to each allocation's date range. This caused the FIFO formula to silently absorb leaves from one period into another's allocation capacity.
ex:
Alloc A (20 days) 2025, taken leaves 15 days
Alloc B (20 days) 2026, taken leaves 5 days
report: 2025: (15 taken), (5 left)
2026: (7 taken), (20 left)
- Left" rows shifted by one year in non-UTC timezones. Allocation date_from/date_to (Date fields) were cast to timestamp as midnight UTC. In negative-UTC /positive-UTC timezones midnight UTC of Dec 31 renders as the prev/next day.
__FIX__:
- detect overlap groups using a running MAX(date_to) and partition the cumulative sums within each overlap group. This way non-overlapping allocations are treated as independent, while overlapping or open-ended allocations still share FIFO within their group.
- offset allocation dates by 12 hours so no timezone can shift them across a day boundary.
- opw-5169606
- opw-5352114
Forward-Port-Of: odoo/odoo#259083
Forward-Port-Of: odoo/odoo#257873This update corrects a reporting issue within the GSTR-3B report for Indian companies using the '18% IGST (IMP-Service)' tax. The previous configuration resulted in the tax not being accurately reflected in the report. This fix ensures correct reporting of service taxes, aligning with Indian tax regulations.
Original PR description
**Steps to reproduce:** - Install l10n_in_reports - Switch to an Indian company (e.g. IN Company) - Create a bill with a Service product and "18% IGST (IMP-Service)" tax - Confirm the bill - Go to "Accounting / Reporting / India / GSTR-3B" **Issue:** In "4. (A) (2) Import of services" section of the report, the bill that has been created is not taken into account. **Cause:** The "18% IGST (IMP-Service)" tax has a distribution of: * 100% of the tax in "100570" account with "IGST" tax tag * -100% of the tax in same account with "IGST" tax tag Therefore, both distribution lines with the tax tag cancel themselves. opw-6116356 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#260631
This update resolves a bug that prevented users from scheduling rental tours correctly. Previously, attempts to set times in the past would cause scheduling errors. The fix ensures tours always use valid, future dates and times, improving the reliability of the rental booking process.
Original PR description
Since 605c8b47d52854e36c7cb822ccb2d40de44c4c3c, rourly rental products default to a rental period starting at the next hour of the current day. Tours override the time of the rental period, but not the date. If the tours tries to set a time which is in the past, the datepicker will discard the time, breaking the tour. Scenario: Running the tour between 11am-11:59am breaks test_website_sale_renting_ui: - Product page shows default times: today 12pm (start) to 1pm (end) - Tour tries to set start time to 8am - Datepicker rejects 8am (it's before the current time 11am-11:59am) and keeps 12pm - Tour then sets end time to 12pm, resulting in equal start and end times - Equal times are invalid, cart addition fails, tour breaks This commit, extracts the existing utility function into a shared helper that returns a guaranteed future date (next Monday + offset), ensuring tours always set valid times regardless of when they run. runbot-243459
This update resolves an issue where multi-company invoices were experiencing errors due to incorrect tax calculations. The change ensures tax information is handled securely, preventing crashes when products from different companies are involved. This improves the reliability of invoicing for businesses using Odoo's multi-company functionality.
Original PR description
Description of the issue this commit addresses: In multi-company setups, invoice line tax recomputation could read product or account taxes in user context and trigger an AccessError on account.tax when products carry taxes from another company. Desired behavior after this commit is merged: This patch hardens account.move.line tax recomputation paths by reading tax M2M values in sudo and returning filtered results in normal env, so compute logic no longer crashes on cross-company tax records. Ticket [link](https://www.odoo.com/odoo/project.task/6036638) opw-6036638 Forward-Port-Of: odoo/odoo#260948
This update resolves an issue where backorder returns weren't properly associated with the original delivery. The change ensures that when a backorder is created from a return, the return's ID is correctly set, allowing for accurate tracking and reporting of returned items within the delivery context. This improves inventory accuracy and reporting.
Original PR description
### Steps to reproduce: - Create, confirm and validate a delivery for 2 units of a product A - Click Return > Return All - Validate the return for 1 unit and backorder #### > The backorder does not belong to the return list of the delivery ### Cause of the issue: Backorder pickings are created by copying the picking to backorder: https://github.com/odoo/odoo/blob/9ad995ff6b59a6a2fdfbbd6cf385fe27568dd3ea/addons/stock/models/stock_picking.py#L1580-L1593 https://github.com/odoo/odoo/blob/9ad995ff6b59a6a2fdfbbd6cf385fe27568dd3ea/addons/stock/models/stock_picking.py#L1571-L1578 However, the `return_id` is a `copy=False` field that is not manully set during this copy process: https://github.com/odoo/odoo/blob/9ad995ff6b59a6a2fdfbbd6cf385fe27568dd3ea/addons/stock/models/stock_picking.py#L558 opw-6111544 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#261831 Forward-Port-Of: odoo/odoo#259804
This update resolves an issue where users could unintentionally bypass tax group restrictions when changing Argentinian fiscal packages. The system now explicitly checks for a 'force_delete' flag, ensuring that tax group deletions are handled correctly and restoring the previous behavior. This prevents data inconsistencies and maintains the integrity of Argentinian tax reporting.
Original PR description
Commit 947e4dc9de3a replaced MODULE_UNINSTALL_FLAG with an explicit 'force_delete' context flag, and as the commit message warns, callees that relied on the previous flag must now detect 'force_delete' on their own. There is no automatic bypass anymore. **STEP TO REPRODUCE** 1.- Install l10n_ar 2-. Select one argentinian regime (fiscal package) & save 3-. Try to change package **FIX** Detect 'force_delete' in check_uninstall_required and return early, restoring 19.0 behavior. Manual deletions of the tax group are still blocked. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#261561
This update enhances the visual clarity of form fields by ensuring consistent styling for required, readonly, invalid, and focused states. The changes prioritize clear indication of the active field and improve overall usability. This ensures users can easily identify and interact with the correct fields within the application.
Original PR description
Before this commit, the focus style wasn't applied on a required field. We now have improved consistency across field states and their visual design. Here’s how to visually distinguish each field state: **Required**: the border is more prominent **Readonly**: the label is greyed out (as well as the background color) **Invalid**: the background color is red **Focused**: the border color is green We no longer want to change the label color for simplicity. For example, if you see a thicker green border with a greyed-out background, it means the field is **focused**, **readonly**, and **required**. Note: the "invalid" style is removed when the field receives focus. We chose not to support this combination. Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an issue where generating timesheets would produce errors when a previously employed employee was archived and a related holiday was still active. The fix prevents timesheet generation from considering time off requests for archived employees, ensuring accurate timesheet calculations. This improves data integrity and prevents potential reporting discrepancies.
Original PR description
[FIX] project_timesheet_holidays: Exclude archived employees from time-off # Description of the issue/feature this PR addresses: ## Steps to Reproduce: 1. Create a time off for Employee A (it should…
[FIX] project_timesheet_holidays: Exclude archived employees from time-off # Description of the issue/feature this PR addresses: ## Steps to Reproduce: 1. Create a time off for Employee A (it should affect the timesheets). 2. Create a new public holiday (global time off) that overlaps with Employee A’s time off. 3. Archive Employee A. 4. Delete the public holiday created in step 2. 5. An error related to timesheet generation appears. ## Expected Behavior: - The public holiday / global time off should be deleted without any error. # Desired behavior after PR is merged: ## Fix (Implemented): When regenerating timesheets due to changes in holidays or time off, leaves related to archived employees should not be taken into account. A check was added inside the `_generate_timesheets` function in `project_timesheet_holidays/models/hr_holidays.py` to exclude leaves belonging to archived employees. ## Alternative Fix (Not Implemented): Instead of filtering out leaves linked to archived employees, we could delete those leaves when an employee is archived. However, this approach is not ideal, as archived employees may be reactivated later and would still need their previously requested time off to be preserved. ## Version: This bug appears in both version 17.0 and 19.0. I assumed that it also appears in 18.0 but didn't directly test ## Task: [5474038](https://www.odoo.com/odoo/project/4105/tasks/5474038) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#261909 Forward-Port-Of: odoo/odoo#244203
This update fixes a discrepancy in the sale details report by accurately reflecting cash rounding adjustments. Now, the report displays the total cash rounding applied during a session, ensuring a more precise representation of sales transactions, especially when cash payments are involved. This improves reporting accuracy and provides a clearer picture of financial data.
Original PR description
The sale details report total_paid was computed from sum(order.amount_total), which does not include the cash rounding adjustment. This caused a discrepancy between the displayed total and the sum of individual payment lines when cash rounding is enabled. Use the sum of actual payment amounts instead, which naturally includes cash rounding since payments are recorded with their rounded values. opw-5253018 Forward-Port-Of: odoo/odoo#261884 Forward-Port-Of: odoo/odoo#254401
This update fixes an issue where byproducts added directly to manufacturing orders weren't correctly linked to the stock moves, preventing accurate tracking of origin. The change ensures byproducts added through the MO are properly associated with stock movements, resolving a discrepancy in location data. This improves the reliability of production tracking.
Original PR description
When we add a byproduct followed by SN directly in the MO it will not have the its location as production. Steps to reproduce: ------------------- * Create product tracked by Serial number * Create a…
When we add a byproduct followed by SN directly in the MO it will not have the its location as production. Steps to reproduce: ------------------- * Create product tracked by Serial number * Create a Manufacturing order * Add the Product tracked by serial number on the MO as byproduct * Confirm the MO * Go to shop floor * Add the by-product quantity and create a new serial number. * Close production and go back to the MO in manufacturing * Open stock moves -> the by-product does not have "production" for origin Observation: ------------- When we add the byproduct directly in the MO, they will be added to move_byproduct_ids in the MO but not in byproduct_ids on the stock.move because byproduct_ids it's a [link](https://github.com/odoo/odoo/blob/d14bf6289da21065860ff959185c47b947a7418c/addons/mrp/models/stock_move.py#L50-L52) between the stock.move and the BOM. When adding the byproduct in shopfloor, it will create the quant: https://github.com/odoo/enterprise/blob/06be616bb4d74f0a089e8e318d25c2424594f813/mrp_workorder/static/src/mrp_display/mrp_record_line/stock_move.js#L163-L171 Additionaly when creating the quant it will decide the source location depending if the product its a byproduct: https://github.com/odoo/enterprise/blob/1d10ee238a50e7bdb552efdeafc068c5127cd49a/mrp_workorder/static/src/mrp_display/mrp_record_line/stock_move.js#L189-L192 The issue arise because it check if the product it's a byproduct by checking byproduct_ids and since our product was added directly on the MO and not from the BOM it will not appear in byproduct_ids https://github.com/odoo/enterprise/blob/dc5bb0fe8e15063f977970841bdaf8aff1a61e41/mrp_workorder/static/src/mrp_display/mrp_record_line/stock_move.js#L108-L110 #### Additional notes: The default value for [byproduct_id](https://github.com/odoo/odoo/blob/abb5777cc8324cff0cdf841a8ae42413060dcf92/addons/mrp/models/mrp_production.py#L1263) when creating the stock move is false opw-5974582 Forward-Port-Of: odoo/enterprise#110122
This update fixes an issue where the ewallet discount was incorrectly included in delivery calculations. The change adjusts the pricing logic to accurately exclude ewallet amounts from delivery costs, ensuring consistent and accurate shipping charges for customers. This improves the overall customer experience and billing accuracy.
Original PR description
Issue: --- Ewallet line is included in delivery pricing. Steps to reproduce: 1- Create a delivery method `based on rules`. 2- In pricing set rules: - price <= 99 => delivery price = 30 - price > 99…
Issue: --- Ewallet line is included in delivery pricing. Steps to reproduce: 1- Create a delivery method `based on rules`. 2- In pricing set rules: - price <= 99 => delivery price = 30 - price > 99 => delivery price = 50 3- Create a eWallet with balance = 200. 4- Create a SO add a line with product. Set the SOL unit amount to 100. 5- Click on `add a shipping`. Add the created delivery method. 6- As you see, the delivery amount is correctly calculated. 7- Now apply the eWallet using `reward` button. 8. Update the shipping cost. The shipping cost is 30, which is not expected. Cause: --- In calculation of shipping amount the ewallet is not taken into account. Even though technically it's considered a discount, ewallet is not functionally the same as discount. However, in `_get_price_available` we cannot have information about `ewallet` lines as it doesn't depend on `sale_loyalty`. Fix: --- We use `_compute_amount_total_without_delivery` which is overridden in `sale_loyalty_delivery` to exclude ewallet and gift cards. opw-6124209 Forward-Port-Of: odoo/odoo#260134
This update fixes an error in the Datev general ledger export that resulted in incorrect tax rates. The issue stemmed from how multiple tax repartition lines were handled, leading to amounts being replaced instead of added. This ensures accurate tax reporting for Datev customers.
Original PR description
With l10n_de_reports: - Configure a foreign currency with an exchange rate. - Configure a tax with multiple repartition lines. - Create a vendor bill in this foreign currency with this tax. - In the general ledger export the datev csv. In the datev csv the rate is wrong. In the method _l10n_de_datev_get_csv, we build a tax_amount dict. However when one tax has multiple lines, the amount is replaced and not added. opw-6010097 Forward-Port-Of: odoo/enterprise#115535 Forward-Port-Of: odoo/enterprise#110453
This update corrects a display issue on rental product pages when 'continue selling' is enabled. Previously, the available quantity was incorrectly shown as 2 regardless of the rental period. The fix ensures the quantity accurately reflects the remaining availability based on the selected rental timeframe, improving the customer experience.
Original PR description
**Issue**: The displayed available quantity on the ecommerce product page is incorrect for rental products when "continue selling" is enabled. **Steps to reproduce**: - Create a rental product…
**Issue**: The displayed available quantity on the ecommerce product page is incorrect for rental products when "continue selling" is enabled. **Steps to reproduce**: - Create a rental product tracked in stock with a quantity of 5 - Enable "continue selling" and "show available quantity below 10" - Go to the ecommerce page of this product - Rent 3 units for a given period, confirm and pay - Return to the ecommerce product page -> Whatever the selected renting period, the displayed quantity is always 2 **Cause**: The website displays `free_qty`: https://github.com/odoo/enterprise/blob/41c729e22c5fd1abb690f8335e933f793be0b319/website_sale_stock_renting/static/src/xml/website_sale_stock_renting_product_availability.xml#L15 `free_qty` is computed in: https://github.com/odoo-dev/odoo/blob/0935829ddaecd7b2b6eec9157f8f790b546d06ff/addons/website_sale_stock/models/product_template.py#L36 which leads to: https://github.com/odoo/enterprise/blob/41c729e22c5fd1abb690f8335e933f793be0b319/website_sale_stock_renting/models/website.py#L10 and ultimately relies on: https://github.com/odoo/odoo/blob/37bf1703c7478a3010b71cd60bbb43b3295a605b/addons/stock/models/product.py#L213 This computation does not take the selected renting period into account. There is a period-aware computation here: https://github.com/odoo/enterprise/blob/41c729e22c5fd1abb690f8335e933f793be0b319/website_sale_stock_renting/models/website.py#L15C17-L21C1 but it is only triggered when `product.allow_out_of_stock_order` is False (i.e. when "continue selling" is disabled). opw-[5354163](https://www.odoo.com/web#id=5354163&view_type=form&model=project.task) Forward-Port-Of: odoo/enterprise#108493 Forward-Port-Of: odoo/enterprise#103333
This update resolves an issue impacting the accuracy of real margin reports within the Odoo system. The changes adjust the report's structure to ensure correct aggregation of data, leading to more reliable margin calculations. This improves the financial reporting capabilities for sales teams.
Original PR description
Adjust the real margins pivot report structure --- task-6168613
This update resolves a bug that prevented users without project access from correctly linking project values to sales quotations or rental orders. The change uses a temporary access method to ensure project information is included, allowing for accurate order creation even without direct project permissions. This improves the functionality of the sales and rental processes.
Original PR description
Before this commit if a lead is converted into either of sales quotation or rental quotation, if the user doesnt have access to project but has access to sales and CRM, it throws a error to read the project. Rationale: - Even when there is no access to project, it is neccesary for the project value to be linked in the suqsequent quotation or rental order. So using a sudo to to read the value and assigning it as a default value is neccessary.
This update fixes a potential timeout issue in the website builder when users upload multiple images simultaneously. Previously, a 10-second timeout would trigger errors, but this change allows builder actions to remain active until image uploads are complete, improving the user experience and preventing frustrating errors.
Original PR description
Steps to reproduce: 1.Drop a gallery slider 2.Add multiple images at the same time 3.Wait more than 10 seconds before finalizing uploads 4.A toaster error is displayed Before this change: Builder actions relying `this.dependencies.media.openMediaDialog` inside their `apply` method could time out while the media dialog was still open. This was due to OperationPlugin enforcing a default 10s timeout, even when the user was still interacting with the dialog (e.g., selecting or uploading images).(see PR[1]) After this change: The timeout is disabled by using `this.canTimeout = false` for actions that open the media dialog using apply method, ensuring they remain active until the media dialog completes and preventing false timeout errors. [1]:https://github.com/odoo/odoo/pull/233079 task-6131455
This update fixes an issue impacting how sales advantages are calculated. Specifically, discounts are now excluded from these calculations, ensuring more accurate and reliable advantage reporting. This change improves the accuracy of sales performance analysis.
Original PR description
for the computation of advantages. Only exclude rewards of type discount for the advantage calculation. opw-6159239
This update fixes a slow performance issue that occurred when searching for stock quantities based on certain product selections. Previously, the system would fetch all available quantities regardless of a specified limit, leading to delays. Now, the system respects the limit defined in the search criteria, resulting in significantly faster response times.
Original PR description
## Problem: During an `onchange` call, if a field is defined in the `fields_spec` with a `limit` attribute, the `fetch` method doesn't respect it, and will fetch all records satisfying the domain. In…
## Problem: During an `onchange` call, if a field is defined in the `fields_spec` with a `limit` attribute, the `fetch` method doesn't respect it, and will fetch all records satisfying the domain. In certain circumstances, this leads to slow requests. ## Solution: Enforce the `limit` when fetching if it is present. ## Steps to reproduce: - Have a product with many quant records 1. Open a picking for this product in Barcode 2. Change the lot/serial The frontend will send an `onchange` request that includes `product_stock_quant_ids` in the `fields_spec` (with default `limit` 40). Odoo will fetch all quants for this product regardless of the limit, and the request will take a while to resolve. ## Benchmark: <table> <thead> <tr> <th># of quants</th> <th>Before</th> <th>After</th> </tr> </thead> <tbody> <tr> <td>17193</td> <td>~9s</td> <td>~400ms</td> </tr> </tbody> </table> opw-6041705 Forward-Port-Of: odoo/odoo#261904 Forward-Port-Of: odoo/odoo#259983
This update resolves a bug that prevented users from scheduling rental tours correctly. Previously, attempts to set times in the past were rejected, leading to broken booking processes. The fix ensures tours always use valid, future dates, improving the reliability of the rental booking experience.
Original PR description
Since 605c8b47d52854e36c7cb822ccb2d40de44c4c3c, rourly rental products default to a rental period starting at the next hour of the current day. Tours override the time of the rental period, but not the date. If the tours tries to set a time which is in the past, the datepicker will discard the time, breaking the tour. Scenario: Running the tour between 11am-11:59am breaks test_website_sale_renting_ui: - Product page shows default times: today 12pm (start) to 1pm (end) - Tour tries to set start time to 8am - Datepicker rejects 8am (it's before the current time 11am-11:59am) and keeps 12pm - Tour then sets end time to 12pm, resulting in equal start and end times - Equal times are invalid, cart addition fails, tour breaks This commit, extracts the existing utility function into a shared helper that returns a guaranteed future date (next Monday + offset), ensuring tours always set valid times regardless of when they run. runbot-243459