Follow-up to the merged #11 PR (which shipped the enum-based catalogue): make categories user-defined data and the PO T&C a dynamic editor. - categories are a TermsCategory TABLE (not an enum) — admins add new ones; - every PO T&C line is catalogued, incl. the previously-fixed boilerplate (seeded under a "General" category) and an "Others" bucket; - the PO form is a dynamic editor: "+ Add term", pick a category, type/pick a clause (components/po/po-terms-editor.tsx), used by new/edit/manager-edit. Migration: the already-released 20260624140000 migration is untouched; a new 20260624150000 FORWARD migration renames the enum, creates the table, migrates existing enum clauses onto category rows, adds isDefault/sortOrder + the two fixed lines under General, and adds PurchaseOrder.terms (JSON snapshot that supersedes the legacy tc* columns for export/detail; old POs fall back to tc*). Tests rewritten for category creation + catalogue/default helpers. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
28 lines
1.2 KiB
TypeScript
28 lines
1.2 KiB
TypeScript
import { db } from "@/lib/db";
|
|
import type { CatalogueCategory, PoTerm } from "@/lib/terms";
|
|
|
|
/** Active categories (ordered) each with their active clause texts — for the PO T&C editor (#11). */
|
|
export async function getTermsCatalogue(): Promise<CatalogueCategory[]> {
|
|
const cats = await db.termsCategory.findMany({
|
|
where: { isActive: true },
|
|
orderBy: [{ sortOrder: "asc" }, { name: "asc" }],
|
|
include: {
|
|
clauses: {
|
|
where: { isActive: true },
|
|
orderBy: [{ sortOrder: "asc" }, { createdAt: "asc" }],
|
|
select: { text: true },
|
|
},
|
|
},
|
|
});
|
|
return cats.map((c) => ({ id: c.id, name: c.name, clauses: c.clauses.map((x) => x.text) }));
|
|
}
|
|
|
|
/** The default T&C set pre-filled on a NEW PO — every active isDefault clause, ordered. */
|
|
export async function getDefaultPoTerms(): Promise<PoTerm[]> {
|
|
const rows = await db.termsCondition.findMany({
|
|
where: { isDefault: true, isActive: true, category: { isActive: true } },
|
|
orderBy: [{ category: { sortOrder: "asc" } }, { sortOrder: "asc" }],
|
|
select: { text: true, category: { select: { name: true } } },
|
|
});
|
|
return rows.map((r) => ({ category: r.category.name, text: r.text }));
|
|
}
|