Tuesday, April 21, 2026
10 changes · saas-18.2
Resolved issues and error corrections
Sales orders using early payment discounts with tax-included prices now calculate the untaxed amount correctly. This prevents small rounding or tax-display errors on quotes and orders, improving customer-facing amount accuracy.
Original PR description
Steps to produce: --- - Install the `Sales` module. - Go to `Invoicing > Configuration > Payment Terms`. - Open `Immediate Payment` and enable Early Discount. - Set `Reduced Tax` to `Always (upon…
Steps to produce: --- - Install the `Sales` module. - Go to `Invoicing > Configuration > Payment Terms`. - Open `Immediate Payment` and enable Early Discount. - Set `Reduced Tax` to `Always (upon invoice)`. - Go to Invoicing > Configuration > Taxes. - Create a 21% tax with `Tax included`. - Create a product with a sale price of 7.50 and assign the tax. - Create a Sale Order with this product > Set Immediate Payment as payment term. Issue: --- - The untaxed amount is computed as 6.22 instead of 6.20. Root cause: --- - At [1], in `_add_base_lines_for_early_payment_discount`, the base lines generated for early payment discount were missing the `special_mode='total_excluded'`. - Consequently, the tax engine interpreted these amounts as tax-included and attempted to recompute the untaxed base, resulting in an incorrect untaxed amount. Solution: --- - Add `special_mode='total_excluded'` to the base lines created for early payment discount computation. - This ensures the discount amounts are treated as already tax-excluded. [1]https://github.com/odoo/odoo/blob/a2b4f618328f3ce3f654fd2c1ee4410365706a7e/addons/sale/models/sale_order.py#L515-L550 opw-6023472 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#255724
This fix updates the Windows packaging setup to include optional dependencies that were previously missing. It helps ensure Windows installations include the expected supporting components, reducing setup issues for users on that platform.
Original PR description
Forward-Port-Of: odoo/odoo#258128
Draft delivery orders now show products as available when existing stock is enough to cover the requested quantity. This prevents users from seeing a false red warning when inventory exactly matches demand, improving confidence in stock planning.
Original PR description
Steps to reproduce: - Create a storable product "P1" - Update on-hand quantity to 2 units - Create a delivery with 2 units of P1 and keep it in draft state Problem: The forecast availability is…
Steps to reproduce: - Create a storable product "P1" - Update on-hand quantity to 2 units - Create a delivery with 2 units of P1 and keep it in draft state Problem: The forecast availability is displayed in red (not available), even though the stock is sufficient to fulfill the move. Explication: For draft consuming moves, the forecast availability is computed as: `virtual_available - move.product_qty` In the case where stock exactly matches the demand, this results in 0. However, on the JS side, availability is evaluated with: `forecast_availability >= product_qty` So with forecast_availability = 0 and product_qty = 2, the condition evaluates to False, incorrectly marking the move as not available. https://github.com/odoo/odoo/blob/c7fede7f44c668ccc0a094d8341c3cae8879a7f1/addons/stock/static/src/widgets/forecast_widget.js#L31 Solution: When the available quantity is sufficient to cover the move (using float_compare), set forecast_availability to the full available quantity instead of subtracting the move quantity. This ensures the JS condition correctly evaluates to True and the move is marked as available. opw-5159142 Forward-Port-Of: odoo/odoo#257354
Fixed an issue in Attendance kiosk mode where searching for an employee after selecting a department could trigger an error. This helps staff reliably identify employees manually without interruptions.
Original PR description
**Steps to Reproduce:**
1. Install `hr_attendance` module with demo data.
2. Go to Attendances > Kiosk Mode > Identify Manually.
3. Select any department.
4. Try searching for an employee.
**Error:**
`ValueError - not enough values to unpack (expected 3, got 1)`
**Cause:**
The `employees_infos()` controller assumes that every item in the domain is a valid triplet (field, operator, value). However, the domain may also contain logical operators ('&'), which are not triplets. And then trying to unpack such entries leads to a ValueError.
**Fix:**
Add a validation to ensure the condition is a proper triplet before unpacking. Non-conforming entries (logical operators) are skipped.
sentry-7401444075
opw-6113268
Forward-Port-Of: odoo/odoo#258825This fixes an unstable automated test around the website editor's link popover. It makes the test better match real user behavior, reducing false failures in the validation pipeline without changing customer-facing functionality.
Original PR description
The popover opening is triggered through click, but there is a selectionchange handler on click that checks if the selection is outside of the link and, if it is, closes the popover. In this case, the click method didn't set the selection inside the link properly because of the presence of \ufeff around the link. The test actually passes by mistake when the runbot was fast, but failed when the runbot was slow, as the selectionchange handler had the time to execute and close the popover. This commit forces the selection to be inside the link after calling click, to be closer to what actually happens when a user click on a link, as opposed to a programmatic click. runbot-161423 Forward-Port-Of: odoo/odoo#259688
Typing an email address in the HTML editor now automatically turns it into a clickable mail link when the user presses space. This makes composing content faster and reduces the need to manually create email links.
Original PR description
Before this commit: when typing an email address, it's not converted to a mailto link after spacing. After this commit: the mailto link is created after spacing. task- 6053993 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#257497
Mobile sales order lines now prevent combo products from being selected in a way that skips required configuration. This avoids creating incorrect zero-price order lines without the expected included items, helping keep sales orders accurate.
Original PR description
Combo products bypasses the configurator in mobile view, resulting in a 0-price line with no child lines. Exclude them via domain on the field. opw-5999935 Forward-Port-Of: odoo/odoo#256790
This fixes an unstable automated test for Mail activities that could fail unpredictably when data loading happened at the same time. The change helps keep quality checks reliable so future updates to activity sharing between browser tabs can be validated with more confidence.
Original PR description
The `@mail/activity/activity/activity updates are shared between tabs` fails in a non-deterministic fashion. It occurs because the `/mail/data` route can interfere with the test. runbot-242616 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
The automatic reset of the user on subscription orders has been moved into a separate step so it can be overridden by customizations. This makes it easier for businesses to adapt subscription behavior without modifying core logic directly.
Original PR description
After this commit, the auto resetting of subscription user is overridable. Doing business logic in CRUD methods makes them impossible to bypass, by encapsulating the logic in another method, it would be easily overridable. Forward-Port-Of: odoo/enterprise#114055
This change prevents an error when generating a W-2 CSV report if no end date is entered. The system now uses the current year for the file name in that case, so users can complete the export without interruption.
Original PR description
Currently, an error occurs when user tries to create a csv for w2 form with no end date defined. Steps to replicate: - Install `l10n_us_hr_payroll`. - Open Payroll > Reporting > W2 Report. - Click…
Currently, an error occurs when user tries to create a csv for w2 form with no end date defined.
Steps to replicate:
- Install `l10n_us_hr_payroll`.
- Open Payroll > Reporting > W2 Report.
- Click `New` > Remove value from `End Date` and click Generate.
Error:
```
File '/home/odoo/odoo19/enterprise/l10n_us_hr_payroll/models/l10n_us_w2.py', line 249, in action_generate_csv
self.csv_filename = f'form_w2_{self.date_end.year or date.today().year}.csv'
^^^^^^^^^^^^^^^^^^
AttributeError: 'bool' object has no attribute 'year'
```
Cause:
- As the user did not give any value for `End Date`, False was passed and when the execution flow reached [here] `self.end_date` is False and attempting to access `self.end_date.year` results in this error.
Solution:
- If we do not receive the `self.end_date` while generating the CSV, we will use the current year to generate the CSV file name.
[here]: https://github.com/odoo/enterprise/blob/01be8d6e9384bcb340559847d529b4887e073519/l10n_us_hr_payroll/models/l10n_us_w2.py#L248
No ID
Forward-Port-Of: odoo/enterprise#113408