import { NextRequest, NextResponse } from "next/server"; import { getDb } from "@/lib/db"; export async function GET(request: NextRequest) { try { const sql = getDb(); const { searchParams } = new URL(request.url); const supplierId = searchParams.get("supplier_id"); const statusFilter = searchParams.get("status"); // "active" = draft,ordered,partially_received | "received" | null = all const baseSelect = `SELECT sp.*, s.name AS supplier_name, s.code AS supplier_code, (SELECT COUNT(*) FROM supplier_po_items WHERE supplier_po_id = sp.id) AS item_count, (SELECT COALESCE(SUM(quantity * unit_price), 0) FROM supplier_po_items WHERE supplier_po_id = sp.id) AS total_value, (SELECT COALESCE(SUM(received_quantity), 0) FROM supplier_po_items WHERE supplier_po_id = sp.id) AS total_received, (SELECT COALESCE(SUM(quantity), 0) FROM supplier_po_items WHERE supplier_po_id = sp.id) AS total_ordered FROM supplier_pos sp JOIN suppliers s ON s.id = sp.supplier_id`; const conditions: string[] = []; const values: (string | number)[] = []; let paramIdx = 1; if (supplierId) { conditions.push(`sp.supplier_id = $${paramIdx++}`); values.push(Number(supplierId)); } if (statusFilter === "active") { conditions.push(`sp.status IN ('draft', 'ordered', 'partially_received')`); } else if (statusFilter === "received") { conditions.push(`sp.status IN ('received', 'cancelled')`); } const where = conditions.length > 0 ? ` WHERE ${conditions.join(" AND ")}` : ""; const rows = await sql(`${baseSelect}${where} ORDER BY sp.created_at DESC`, values); return NextResponse.json(rows); } catch (error) { console.error("Supplier POs GET error:", error); return NextResponse.json( { error: "Failed to fetch supplier POs" }, { status: 500 } ); } } export async function POST(request: NextRequest) { try { const sql = getDb(); const body = await request.json(); const { orders, planning_id } = body; // orders: Array<{ supplier_id, supplier_name, items: Array<{ component_id, part_number, component_name, supplier_part_number, quantity, unit_price }> }> if (!orders || !Array.isArray(orders) || orders.length === 0) { return NextResponse.json({ error: "No orders provided" }, { status: 400 }); } const createdPos: Record[] = []; for (const order of orders) { // Generate PO number: PO-EACH-YYYY_MM_DD-RR-SUPPLIERNAME (matching packing list pattern) const now = new Date(); const yyyy = now.getFullYear(); const mm = String(now.getMonth() + 1).padStart(2, "0"); const dd = String(now.getDate()).padStart(2, "0"); const supplierSlug = (order.supplier_name || "UNKNOWN") .toUpperCase() .replace(/[^A-Z0-9]/g, "") .slice(0, 20); const datePrefix = `PO-EACH-${yyyy}_${mm}_${dd}`; const existingRows = await sql( `SELECT COUNT(*) AS cnt FROM supplier_pos WHERE po_number LIKE $1`, [`${datePrefix}%-${supplierSlug}`] ); const revision = String(Number(existingRows[0].cnt) + 1).padStart(2, "0"); const poNumber = `${datePrefix}-${revision}-${supplierSlug}`; const poRows = await sql( `INSERT INTO supplier_pos (po_number, supplier_id, planning_id, status, notes) VALUES ($1, $2, $3, 'draft', $4) RETURNING *`, [ poNumber, Number(order.supplier_id), planning_id ? Number(planning_id) : null, order.notes || null, ] ); const po = poRows[0]; for (const item of order.items) { await sql( `INSERT INTO supplier_po_items (supplier_po_id, component_id, part_number, component_name, supplier_part_number, quantity, unit_price) VALUES ($1, $2, $3, $4, $5, $6, $7)`, [ po.id, Number(item.component_id), item.part_number, item.component_name, item.supplier_part_number || null, Number(item.quantity), Number(item.unit_price), ] ); } createdPos.push({ ...po, supplier_name: order.supplier_name, item_count: order.items.length, }); } return NextResponse.json(createdPos, { status: 201 }); } catch (error) { console.error("Supplier POs POST error:", error); return NextResponse.json( { error: error instanceof Error ? error.message : "Failed to create supplier POs" }, { status: 500 } ); } }