import { NextRequest, NextResponse } from "next/server"; import { getDb } from "@/lib/db"; interface SourceInfo { product_name: string; sku: string; qty_per_unit: number; batch_size: number; subtotal: number; } interface AcceptItem { component_id: number; part_number: string; component_name: string; category_name: string | null; package_type: string | null; shelf_location: string | null; unit_price: number; stock_quantity: number; total_needed: number; shortage: number; is_internal: boolean; manufacturer: string | null; supplier: string | null; supplier_part_number: string | null; sources: SourceInfo[]; } interface AcceptProduct { product_name: string; sku: string; batch_size: number; } export async function POST(request: NextRequest) { try { const sql = getDb(); const body = await request.json(); const { name, items, products, summary, link_po_ids } = body as { name: string; items: AcceptItem[]; products: AcceptProduct[]; summary: { totalProducts: number; totalComponents: number; totalParts: number; totalCost: number; shortageCount: number; }; link_po_ids?: number[]; }; if (!items || items.length === 0) { return NextResponse.json( { error: "No items to accept" }, { status: 400 } ); } const planName = name || `Production Plan ${new Date().toLocaleDateString("en-GB", { day: "2-digit", month: "2-digit", year: "numeric" })}`; // 1. Create the planning history record const phRows = await sql( `INSERT INTO planning_history (name, status, products_json, summary_json) VALUES ($1, $2, $3, $4) RETURNING *`, [planName, "accepted", JSON.stringify(products || []), JSON.stringify(summary || {})] ); const plan = phRows[0]; // 2. Insert all items with full data snapshots for (const item of items) { await sql( `INSERT INTO planning_history_items (planning_id, component_id, part_number, component_name, category_name, package_type, shelf_location, unit_price, stock_at_time, quantity_needed, shortage, is_internal, manufacturer, supplier, supplier_part_number, sources_json) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)`, [ plan.id, item.component_id, item.part_number, item.component_name, item.category_name || null, item.package_type || null, item.shelf_location || null, item.unit_price || 0, item.stock_quantity || 0, item.total_needed, item.shortage || 0, item.is_internal, item.manufacturer || null, item.supplier || null, item.supplier_part_number || null, JSON.stringify(item.sources || []), ] ); } // 3. Decrement stock for ALL components (both internal and external) for (const item of items) { await sql( `UPDATE components SET stock_quantity = GREATEST(0, stock_quantity - $1) WHERE id = $2`, [item.total_needed, item.component_id] ); } // 4. Link selected Supplier POs to this planning record if (link_po_ids && link_po_ids.length > 0) { for (const poId of link_po_ids) { await sql( `UPDATE supplier_pos SET planning_id = $1 WHERE id = $2`, [plan.id, poId] ); } } return NextResponse.json({ plan, message: "Planning accepted. History saved and stock decremented.", }, { status: 201 }); } catch (error) { console.error("Error accepting production plan:", error); return NextResponse.json( { error: "Failed to accept production plan" }, { status: 500 } ); } }