Wednesday, March 18, 2026
2 changes · 17.0
Resolved issues and error corrections
This update resolves a bug that prevented users from previewing draft invoices when no invoice date was specified. The fix ensures that the invoice preview correctly uses today's date as a default, mirroring the behavior when the invoice is confirmed. This improves the usability of the invoice preview feature.
Original PR description
## Issue When clicking the *Preview* button on a draft invoice with an early discount payment term and no invoice date, the following traceback would appear: ``` File…
## Issue
When clicking the *Preview* button on a draft invoice with an early discount payment term and no invoice date, the following traceback would appear:
```
File ".../addons/account/models/account_payment_term.py", line 274, in _get_last_discount_date
return date_ref + relativedelta(days=self.discount_days or 0) if self.early_discount else False
~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
TypeError: unsupported operand type(s) for +: 'bool' and 'relativedelta'
```
## Steps to reproduce
1. Install *Accounting* (`account_accountant`)
2. In Accounting > Configuration > Payment Terms, chose a Payment Term PT and toggle its *Early Discount* field
3. In Accounting > Customers > Invoices, create **but do not confirm** a new Invoice
- Any Customer
- Payment Term PT
- Any Product
- **No Invoice Date**
4. Click the *Preview* button
5. **A _500: Internal Server Error_ traceback appears**
## Cause
The traceback occurs in `AccountPaymentTerm._get_last_discount_date`:
https://github.com/odoo/odoo/blob/6cc36886c612c7ed8878117637ee11bc6234d0e4/addons/account/models/account_payment_term.py#L272-L274
where `date_ref` is False. This method is called by `AccountMove._is_eligible_for_early_payment_discount`:
https://github.com/odoo/odoo/blob/6cc36886c612c7ed8878117637ee11bc6234d0e4/addons/account/models/account_move.py#L2026-L2032
where `self.invoice_date` is False, because that field is not required, and the user can click the *Preview* button before a date is set. If the invoice is confirmed before being previewed, the issue does not occur, as confirming an invoice with no date will use today's date by default. This is done in `AccountMove._post`:
https://github.com/odoo/odoo/blob/6cc36886c612c7ed8878117637ee11bc6234d0e4/addons/account/models/account_move.py#L3967-L3971
## Fix
We can apply the same behavior as if the invoice was confirmed, and use today's date by default if no invoice date is given when trying to preview a draft invoice. The same logic should be applied to `_get_last_discount_date_formatted` for the date to be correctly evaluated in `account/views/report_invoice.xml`:
https://github.com/odoo/odoo/blob/6cc36886c612c7ed8878117637ee11bc6234d0e4/addons/account/views/report_invoice.xml#L252-L254
where `o.invoice_date` is also `False`, leading to `AccountPaymentTerm._get_last_discount_date_formatted` to return None:
https://github.com/odoo/odoo/blob/6cc36886c612c7ed8878117637ee11bc6234d0e4/addons/account/models/account_payment_term.py#L276-L280
which then displays the default date (`2024-01-01`) instead of *today + the early discount time limit*.
## Test
[The test](https://github.com/odoo/odoo/blob/6cc36886c612c7ed8878117637ee11bc6234d0e4/addons/account/tests/test_early_payment_discount.py#L92-L116) added by https://github.com/odoo/odoo/commit/572a6a82576a91005d9eedb673acfb088eb52cd1 and edited by https://github.com/odoo/odoo/commit/abe7fb51235dc3d47e6352505065fcd15100b21b does not follow the same execution flow as the *Preview* button. In the test case, the `reference_date` passed to the `is_eligible_for_early_payment_discount` method is `False`, skipping the problematic section of the condition. When using the *Preview* button, a `reference_date` is passed from `AccountMoveLine._get_epd_data` since https://github.com/odoo/odoo/commit/b9abe46c1492b09e369434e76ec8196c6b02dd19:
https://github.com/odoo/odoo/blob/6cc36886c612c7ed8878117637ee11bc6234d0e4/addons/account/models/account_move_line.py#L3287-L3295
opw-6008959This update resolves an issue where vendor bills imported from XML incorrectly applied two taxes (G and S) to products, particularly when a product had a default service tax. The fix ensures only the relevant tax is applied based on the product type, preventing duplicate tax calculations and improving data accuracy.
Original PR description
**Issue**: Importing a vendor bill from XML may lead to two taxes being applied to the same product if: - The product exists in the database. - It matches a product reference in the XML. - The…
**Issue**: Importing a vendor bill from XML may lead to two taxes being applied to the same product if: - The product exists in the database. - It matches a product reference in the XML. - The product has a default service tax (e.g. 22% S). **Steps to reproduce**: - Create a product with a service tax (22% S). - Ensure you have a test XML referencing that product (see tests for an example). - Go to Accounting > Vendors > Bills. - Upload the XML file. - Observe that the product line has two taxes: 22% G (from XML) and 22% S (from product). **Cause**: Two taxes are applied because: - The tax defined in the product: [Line 875 in `account_move_line.py`](https://github.com/odoo/odoo/blob/767341d4ec6aaa4fbd379827da4baf04e561eb32/addons/account/models/account_move_line.py#L875) which is triggered by [L1285C1-L1288C30 in `account_move.py`](https://github.com/odoo/odoo/blob/e705690d2340245a0d18b7e76347575dde9ea2be/addons/l10n_it_edi/models/account_move.py#L1285C1-L1288C30) - Then, the XML tax is also added: [L1012C1-L1016C44 in `account_move.py`](https://github.com/odoo/odoo/blob/e705690d2340245a0d18b7e76347575dde9ea2be/addons/l10n_it_edi/models/account_move.py#L1012C1-L1016C44) An attempt to reset the `tax_ids` after setting the product is already present: [Line 1319](https://github.com/odoo/odoo/blob/e705690d2340245a0d18b7e76347575dde9ea2be/addons/l10n_it_edi/models/account_move.py#L1319), but it is ineffective because the original `tax_ids` are re-applied afterward, dues to side effects. **Solution**: There are two possible ways to fix this: - Make sure `move_line.tax_ids = []` works as intended - Clean the `move_line.tax_ids` recordset. Chose the second option as it's simpler and avoids modifying unrelated code **Additional Notes**: The tax extracted from the XML does not take into account whether the product is a good or a service. For example, if the tax rate is 22%, the logic return taxes[0] if taxes else taxes will always return 22% G, even if the product should be taxed as 22% S. To solve this, an extra domain filter is added based on the product type to ensure only applicable taxes are considered. opw-4844469 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: BACKPORT OF #218309 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr