54 lines
2.6 KiB
TypeScript
54 lines
2.6 KiB
TypeScript
|
|
import { serverAuth } from "@/lib/pb";
|
||
|
|
import { buildSupplierSpend } from "@/lib/supplier-spend";
|
||
|
|
import { Suppliers2View } from "@/components/Suppliers2View";
|
||
|
|
|
||
|
|
export const dynamic = "force-dynamic";
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Suppliers 2 — the Income Overview treatment for suppliers: one card per company with a
|
||
|
|
* 12-month spend chart, this month's spend, and what is payable. Cash suppliers are hidden
|
||
|
|
* by default. Same data as /expenses/suppliers; nothing here is written.
|
||
|
|
*/
|
||
|
|
export default async function Suppliers2Page() {
|
||
|
|
const pb = await serverAuth();
|
||
|
|
const [suppliers, purchases, invoices, slips, payments] = await Promise.all([
|
||
|
|
pb.collection("suppliers").getFullList({ sort: "name" }),
|
||
|
|
pb.collection("purchases").getFullList({ fields: "id,po_no,po_date,total,supplier_ref" }),
|
||
|
|
pb.collection("purchase_invoices").getFullList({ fields: "purchase,invoice_no,invoice_date,amount_incl" }).catch(() => [] as any[]),
|
||
|
|
pb.collection("cash_float_entries").getFullList({ filter: 'kind = "expense"', fields: "amount,occurred_on,created,supplier_ref" }),
|
||
|
|
// Created by scripts/setup-supplier-payments-collection.mjs; absent on a fresh database.
|
||
|
|
pb.collection("supplier_payments").getFullList().catch(() => [] as any[]),
|
||
|
|
]);
|
||
|
|
const invByPo = new Map<string, any[]>();
|
||
|
|
for (const v of invoices) invByPo.set(v.purchase, [...(invByPo.get(v.purchase) ?? []), v]);
|
||
|
|
|
||
|
|
const now = new Date();
|
||
|
|
const rows = buildSupplierSpend({
|
||
|
|
year: now.getFullYear(),
|
||
|
|
month: now.getMonth() + 1,
|
||
|
|
suppliers: suppliers.map((s) => ({ id: s.id, name: String(s.name), code: String(s.code || ""), terms: String(s.terms || "") })),
|
||
|
|
purchases: purchases.map((p) => ({
|
||
|
|
id: p.id, po_no: String(p.po_no || ""), po_date: String(p.po_date || ""), total: Number(p.total || 0), supplier_ref: String(p.supplier_ref || ""),
|
||
|
|
invoices: (invByPo.get(p.id) ?? []).map((v) => ({
|
||
|
|
invoice_no: String(v.invoice_no || ""), invoice_date: String(v.invoice_date || ""),
|
||
|
|
amount_incl: typeof v.amount_incl === "number" && v.amount_incl > 0 ? v.amount_incl : null,
|
||
|
|
})),
|
||
|
|
})),
|
||
|
|
payments: payments.map((x) => ({
|
||
|
|
id: x.id, supplier_ref: String(x.supplier || ""), paid_on: String(x.paid_on || ""),
|
||
|
|
description: String(x.description || ""), amount: Number(x.amount || 0),
|
||
|
|
})),
|
||
|
|
slips: slips.map((s) => ({ amount: Number(s.amount || 0), at: String(s.occurred_on || s.created || ""), supplier_ref: String(s.supplier_ref || "") })),
|
||
|
|
});
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div className="p-4 sm:p-8 max-w-[1400px]">
|
||
|
|
<Suppliers2View
|
||
|
|
rows={rows}
|
||
|
|
year={now.getFullYear()}
|
||
|
|
month={now.getMonth() + 1}
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|