fix: multi-tax detection and net_amount calculation#256
Conversation
Greptile SummaryThis PR fixes two bugs in e-invoice generation for Sales Invoices with multiple tax rows: incorrect basis-amount calculation for multi-rate "On Net Total" rows, and false 0% VAT rate assignment when an Item Tax Template contains a zero-rate entry for a matched account.
Confidence Score: 4/5Safe to merge for the common case the PR targets, but invoices that mix items with and without Item Tax Templates under multiple tax rates can get a wrong BasisAmount without any error signal The _sum_item_net_matching_on_net_total_rate method silently returns a partial sum when some items lack item_tax_template in a multi-tax invoice, and because the fallback chain is or-chained, a non-zero partial sum prevents the reliable calculated fallback from firing. The emitted BasisAmount would be lower than the actual taxable amount for that rate, potentially causing downstream schema validation failures. eu_einvoice/european_e_invoice/custom/sales_invoice.py — specifically the or-chain in _add_taxes_and_charges (lines 574–581) and the _sum_item_net_matching_on_net_total_rate method that feeds it Important Files Changed
|
in V16+ not_applicable is set, so it can be used as the "stronger" link, that this row should be skipped. In V15 and below, if a tax_rate is 0, it is skipped.
PR Description
This PR addresses two connected issues when generating e-invoices for Sales Invoices with multiple tax rows or configurations where a row in Sales Taxes and Charges is present but not applicable.
Example: Sales Invoice
ACC-SINV-2025-00035Expected e-invoice settlement lines:
1) Basis amount for multi-tax "On Net Total" rows
In multi-tax environments, ERPNext v15 does not provide a
net_amounton tax rows for use as the taxable basis. The existing logic relied on fallback options (hasattr(tax, "net_amount")) that could match an uninitialized or zero-valued field, resulting inbasis_amount = 0.Without this PR:
hasattr(tax, "net_amount")evaluated toTrue(for example due to a Custom Field or attribute initialization on the site), the basis could become0or any other value for both tax lines, producing an incorrect e-invoice tax basis.With this PR:
tax_amount / rate * 100(here:41.61 / 19 * 100 = 219.0and7.21 / 7 * 100 = 103.0).net_amountvalues whose resolved VAT rate matches the tax row's rate.This keeps the fast path for exact results and guarantees a correct basis when rounding would otherwise distort the taxable amount.
2) Highest non-zero rate from Item Tax Template
When multiple accounts are listed in Sales Taxes and Charges and an Item Tax Template contains a matching account with 0% tax, the old logic returned the first match, which could be 0%.
Without this PR:
tax_type= "3806 - Umsatzsteuer 19%",tax_rate= 0tax_type= "3801 - Umsatzsteuer 7%",tax_rate= 7With this PR:
tax_rate = 0are excluded in the applicable-account matching path.tax_rateis returned.income_accountis available, direct account matching is still preferred.This avoids false 0% assignments and keeps mixed-tax invoices consistent.