Files
chronus/src/utils/invoice.ts
Atridad Lahiji ea0a83f44d
Some checks failed
Docker Deploy / build-and-push (push) Has been cancelled
Added discounts to invoices
2026-01-19 10:06:04 -07:00

63 lines
1.6 KiB
TypeScript

import { db } from "../db";
import { invoices, invoiceItems } from "../db/schema";
import { eq } from "drizzle-orm";
/**
* Recalculates the subtotal, tax amount, and total for a specific invoice
* based on its items and tax rate.
*/
export async function recalculateInvoiceTotals(invoiceId: string) {
// Fetch invoice to get tax rate
const invoice = await db
.select()
.from(invoices)
.where(eq(invoices.id, invoiceId))
.get();
if (!invoice) return;
// Fetch all items
const items = await db
.select()
.from(invoiceItems)
.where(eq(invoiceItems.invoiceId, invoiceId))
.all();
// Calculate totals
// Note: amounts are in cents
const subtotal = items.reduce((acc, item) => acc + item.amount, 0);
// Calculate discount
const discountType = invoice.discountType || "percentage";
const discountValue = invoice.discountValue || 0;
let discountAmount = 0;
if (discountType === "percentage") {
discountAmount = Math.round(subtotal * (discountValue / 100));
} else {
// Fixed amount is assumed to be in cents
discountAmount = Math.round(discountValue);
}
// Ensure discount doesn't exceed subtotal
discountAmount = Math.max(0, Math.min(discountAmount, subtotal));
const taxableAmount = subtotal - discountAmount;
const taxRate = invoice.taxRate || 0;
const taxAmount = Math.round(taxableAmount * (taxRate / 100));
const total = taxableAmount + taxAmount;
// Update invoice
await db
.update(invoices)
.set({
subtotal,
discountAmount,
taxAmount,
total,
})
.where(eq(invoices.id, invoiceId));
}