Files
chronus/src/pages/api/invoices/[id]/items/add.ts
Atridad Lahiji df82a02f41
All checks were successful
Docker Deploy / build-and-push (push) Successful in 4m3s
2.2.1 - Misc improvements and cleanup
2026-01-19 21:08:46 -07:00

87 lines
2.2 KiB
TypeScript

import type { APIRoute } from "astro";
import { db } from "../../../../../db";
import { invoiceItems, invoices, members } from "../../../../../db/schema";
import { eq, and } from "drizzle-orm";
import { recalculateInvoiceTotals } from "../../../../../utils/invoice";
export const POST: APIRoute = async ({
request,
redirect,
locals,
params,
}) => {
const user = locals.user;
if (!user) {
return redirect("/login");
}
const { id: invoiceId } = params;
if (!invoiceId) {
return new Response("Invoice ID required", { status: 400 });
}
// Fetch invoice to verify existence and check status
const invoice = await db
.select()
.from(invoices)
.where(eq(invoices.id, invoiceId))
.get();
if (!invoice) {
return new Response("Invoice not found", { status: 404 });
}
// Verify membership
const membership = await db
.select()
.from(members)
.where(
and(
eq(members.userId, user.id),
eq(members.organizationId, invoice.organizationId)
)
)
.get();
if (!membership) {
return new Response("Unauthorized", { status: 401 });
}
// Only allow editing if draft
if (invoice.status !== "draft") {
return new Response("Cannot edit a finalized invoice", { status: 400 });
}
const formData = await request.formData();
const description = formData.get("description") as string;
const quantityStr = formData.get("quantity") as string;
const unitPriceStr = formData.get("unitPrice") as string;
if (!description || !quantityStr || !unitPriceStr) {
return new Response("Missing required fields", { status: 400 });
}
const quantity = parseFloat(quantityStr);
const unitPriceMajor = parseFloat(unitPriceStr);
const unitPrice = Math.round(unitPriceMajor * 100);
const amount = Math.round(quantity * unitPrice);
try {
await db.insert(invoiceItems).values({
invoiceId,
description,
quantity,
unitPrice,
amount,
});
await recalculateInvoiceTotals(invoiceId);
return redirect(`/dashboard/invoices/${invoiceId}`);
} catch (error) {
console.error("Error adding invoice item:", error);
return new Response("Internal Server Error", { status: 500 });
}
};