pelagia-portal/App/prisma/migrations/20260624140000_terms_conditions/migration.sql
Hardik 5764403f1c feat(po): user-defined T&C categories + dynamic PO terms editor (#11)
Reworks the T&C feature per review:
- categories are user-defined DATA, not a fixed enum — admins add new ones;
- ALL PO T&Cs are 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.

- schema: TermsCategory (name/sortOrder/isActive) + TermsCondition (categoryId
  FK + text + isDefault + isActive). PurchaseOrder.terms Json snapshot. Migration
  seeds every standard line as a clause (named slots, the two fixed lines under
  General, empty Others); isDefault rows pre-fill new POs.
- admin /admin/terms: Add/Edit clause form's category is a combobox — typing a
  new name creates the category; isDefault checkbox.
- PO editor components/po/po-terms-editor.tsx: dynamic rows (category + clause
  comboboxes), used by new/edit/manager-edit forms; new POs pre-fill from
  getDefaultPoTerms, edits load po.terms or legacyPoTerms (old tc* + fixed lines).
- storage: PurchaseOrder.terms ([{category,text}]) supersedes tc* for export +
  detail; null on old POs falls back to tc* + fixed lines. parsePoTerms validates.
- export route + po-detail render from terms when present.
- tests rewritten for category creation + catalogue/default helpers.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 04:08:30 +05:30

52 lines
3.1 KiB
SQL

-- CreateTable: user-defined T&C categories
CREATE TABLE "TermsCategory" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"sortOrder" INTEGER NOT NULL DEFAULT 0,
"isActive" BOOLEAN NOT NULL DEFAULT true,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "TermsCategory_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX "TermsCategory_name_key" ON "TermsCategory"("name");
-- CreateTable: clauses belonging to a category
CREATE TABLE "TermsCondition" (
"id" TEXT NOT NULL,
"categoryId" TEXT NOT NULL,
"text" TEXT NOT NULL,
"isDefault" BOOLEAN NOT NULL DEFAULT false,
"isActive" BOOLEAN NOT NULL DEFAULT true,
"sortOrder" INTEGER NOT NULL DEFAULT 0,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "TermsCondition_pkey" PRIMARY KEY ("id")
);
CREATE INDEX "TermsCondition_categoryId_idx" ON "TermsCondition"("categoryId");
ALTER TABLE "TermsCondition" ADD CONSTRAINT "TermsCondition_categoryId_fkey" FOREIGN KEY ("categoryId") REFERENCES "TermsCategory"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- Dynamic T&C snapshot on the PO
ALTER TABLE "PurchaseOrder" ADD COLUMN "terms" JSONB;
-- Seed: every standard PO T&C line becomes a catalogued clause. "General" holds
-- the previously-fixed boilerplate; the five named slots keep their default
-- wording; "Others" is an empty bucket admins fill. isDefault rows pre-fill new POs.
INSERT INTO "TermsCategory" ("id", "name", "sortOrder", "updatedAt") VALUES
('tcat_general', 'General', 0, CURRENT_TIMESTAMP),
('tcat_delivery', 'Delivery', 1, CURRENT_TIMESTAMP),
('tcat_dispatch', 'Dispatch Instructions',2, CURRENT_TIMESTAMP),
('tcat_inspect', 'Inspection', 3, CURRENT_TIMESTAMP),
('tcat_transit', 'Transit Insurance', 4, CURRENT_TIMESTAMP),
('tcat_payment', 'Payment Terms', 5, CURRENT_TIMESTAMP),
('tcat_others', 'Others', 6, CURRENT_TIMESTAMP);
INSERT INTO "TermsCondition" ("id", "categoryId", "text", "isDefault", "sortOrder", "updatedAt") VALUES
('tcc_fixed1', 'tcat_general', 'Please quote this purchase order no. for further communications and invoices pertaining to this indent.', true, 0, CURRENT_TIMESTAMP),
('tcc_fixed2', 'tcat_general', 'We encourage bulk packaging and avoid plastic. No asbestos to be used in any product or packing material.', true, 1, CURRENT_TIMESTAMP),
('tcc_delivery', 'tcat_delivery', 'Within 4 to 5 days', true, 0, CURRENT_TIMESTAMP),
('tcc_dispatch', 'tcat_dispatch', 'To be transported to site address as above. Freight Supplier''s A/C', true, 0, CURRENT_TIMESTAMP),
('tcc_inspect', 'tcat_inspect', 'NA', true, 0, CURRENT_TIMESTAMP),
('tcc_transit', 'tcat_transit', 'NA', true, 0, CURRENT_TIMESTAMP),
('tcc_payment', 'tcat_payment', 'Within 30 days from delivery.', true, 0, CURRENT_TIMESTAMP);