Add tax features: summary report, deductible expenses, invoice tax fix, CSV export

- Add taxDeductible boolean to expenses schema + migration 0002
- Update expenses router, form, and list to support tax-deductible flag
- Fix invoice-view tax calculation (was hardcoded $0.00; now uses taxRate)
- New Tax Summary tab in Reports: year selector, income/deductions breakdown,
  SE tax + federal income estimates, quarterly bar chart
- CSV export for accountant with income + expense rows and tax summary

https://claude.ai/code/session_012sqEgNQpx676isepeoX4Mi
This commit is contained in:
Claude
2026-04-05 03:21:08 +00:00
parent 1f76cf38a7
commit 74f9696023
8 changed files with 409 additions and 175 deletions
+12 -6
View File
@@ -423,18 +423,24 @@ export function InvoiceView({ invoiceId }: InvoiceViewProps) {
<div className="flex justify-between text-sm">
<span className="text-muted-foreground">Subtotal</span>
<span className="text-foreground font-medium">
{formatCurrency(invoice.totalAmount)}
{formatCurrency(invoice.totalAmount, invoice.currency)}
</span>
</div>
<div className="flex justify-between text-sm">
<span className="text-muted-foreground">Tax</span>
<span className="text-foreground font-medium">$0.00</span>
</div>
{(invoice.taxRate ?? 0) > 0 && (
<div className="flex justify-between text-sm">
<span className="text-muted-foreground">
Tax ({((invoice.taxRate ?? 0) * 100).toFixed(1)}%)
</span>
<span className="text-foreground font-medium">
{formatCurrency(invoice.totalAmount * (invoice.taxRate ?? 0), invoice.currency)}
</span>
</div>
)}
<Separator />
<div className="flex justify-between text-lg font-bold">
<span className="text-foreground">Total</span>
<span className="text-primary">
{formatCurrency(invoice.totalAmount)}
{formatCurrency(invoice.totalAmount * (1 + (invoice.taxRate ?? 0)), invoice.currency)}
</span>
</div>
</div>