Files
website-secure/app/api/supplier-pos/route.ts
T
pm 9c14a19a87
DevSecOps Enterprise Pipeline / security-gate-and-deploy (push) Failing after 41s
chore: upload parte 1 - logica
2026-06-01 15:35:53 +01:00

125 lines
4.5 KiB
TypeScript

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<string, unknown>[] = [];
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 }
);
}
}