Overview
InvoicesService.generateAndArchiveInvoice() creates every invoice with taxAmount: 0 and totalAmount: payment.amount, so the total is always identical to the net amount and no tax is ever recorded. The Invoice entity models amount, taxAmount, and totalAmount as three separate decimal columns precisely because they are meant to differ. For any jurisdiction where VAT, GST, or sales tax applies, the archived invoice is not a valid tax document, and the revenue recognition report in ReportingService that reads these columns understates the tax liability to zero.
Specifications
Features:
- Tax is computed from the customer's jurisdiction and the applicable rate.
totalAmount equals amount plus taxAmount by construction.
- The tax rate and jurisdiction applied are recorded on the invoice.
Tasks:
- Introduce a tax resolution step keyed on the customer's billing country/region, sourced from the payment or user profile.
- Compute
taxAmount with decimal-safe arithmetic and set totalAmount = amount + taxAmount.
- Persist the applied rate and jurisdiction in the invoice
items or a dedicated column for audit purposes.
- Render the tax line in the generated invoice document.
- Add unit tests for a zero-rate jurisdiction, a standard-rate jurisdiction, and a rounding boundary.
Impacted Files:
src/payments/invoices/invoices.service.ts
src/payments/entities/invoice.entity.ts
src/payments/reporting/reporting.service.ts
Acceptance Criteria
- An invoice for a taxable jurisdiction carries a non-zero
taxAmount.
totalAmount always equals amount + taxAmount.
- The applied rate is recoverable from the stored invoice.
- Revenue reporting reflects the recorded tax.
Overview
InvoicesService.generateAndArchiveInvoice()creates every invoice withtaxAmount: 0andtotalAmount: payment.amount, so the total is always identical to the net amount and no tax is ever recorded. TheInvoiceentity modelsamount,taxAmount, andtotalAmountas three separate decimal columns precisely because they are meant to differ. For any jurisdiction where VAT, GST, or sales tax applies, the archived invoice is not a valid tax document, and the revenue recognition report inReportingServicethat reads these columns understates the tax liability to zero.Specifications
Features:
totalAmountequalsamountplustaxAmountby construction.Tasks:
taxAmountwith decimal-safe arithmetic and settotalAmount = amount + taxAmount.itemsor a dedicated column for audit purposes.Impacted Files:
src/payments/invoices/invoices.service.tssrc/payments/entities/invoice.entity.tssrc/payments/reporting/reporting.service.tsAcceptance Criteria
taxAmount.totalAmountalways equalsamount + taxAmount.