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 }); } };