From 5aae45299bd7df586701c7f11b52304964033764 Mon Sep 17 00:00:00 2001 From: Hardik Date: Wed, 24 Jun 2026 02:08:59 +0530 Subject: [PATCH] feat(po): admin-managed delivery locations + Place of Delivery dropdown (#19) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the free-text "Place of Delivery" with a dropdown sourced from a new admin-managed Delivery Locations list (each = a Company FK + free-text address). - schema + migration: new DeliveryLocation model (companyId, address, isActive). - permission: manage_delivery_locations granted to Manager + SuperUser + Admin (Manager-accessible, not admin-only, per the issue). - admin screen /admin/delivery-locations: table + Add/Edit dialogs + activate/deactivate + delete (mirrors /admin/sites); sidebar link under Administration for Manager/SuperUser/Admin. - PO forms (new / edit / manager-edit): shared native select populated from active locations, formatted "Company — address". - PurchaseOrder.placeOfDelivery stays a free-text SNAPSHOT (no FK) — the dropdown only changes how the value is picked, so export/import/historical POs are unchanged, and an edit preserves a current value not in the list as a "(current)" option. Deleting a location is therefore always safe. - tests: delivery-location CRUD + permission guard (6). Co-Authored-By: Claude Opus 4.8 (1M context) --- App/CLAUDE.md | 6 + .../admin/delivery-locations/actions.ts | 77 ++++++++++ .../delivery-location-form.tsx | 110 ++++++++++++++ .../delivery-locations-table.tsx | 140 ++++++++++++++++++ .../admin/delivery-locations/page.tsx | 35 +++++ .../approvals/[id]/manager-edit-po-form.tsx | 6 +- App/app/(portal)/approvals/[id]/page.tsx | 6 +- .../(portal)/po/[id]/edit/edit-po-form.tsx | 6 +- App/app/(portal)/po/[id]/edit/page.tsx | 6 +- App/app/(portal)/po/new/new-po-form.tsx | 16 +- App/app/(portal)/po/new/page.tsx | 6 +- App/components/layout/sidebar.tsx | 6 +- App/components/po/delivery-location-field.tsx | 36 +++++ App/lib/delivery-location.ts | 9 ++ App/lib/permissions.ts | 4 + .../migration.sql | 17 +++ App/prisma/schema.prisma | 20 ++- .../integration/delivery-locations.test.ts | 89 +++++++++++ 18 files changed, 578 insertions(+), 17 deletions(-) create mode 100644 App/app/(portal)/admin/delivery-locations/actions.ts create mode 100644 App/app/(portal)/admin/delivery-locations/delivery-location-form.tsx create mode 100644 App/app/(portal)/admin/delivery-locations/delivery-locations-table.tsx create mode 100644 App/app/(portal)/admin/delivery-locations/page.tsx create mode 100644 App/components/po/delivery-location-field.tsx create mode 100644 App/lib/delivery-location.ts create mode 100644 App/prisma/migrations/20260624130000_delivery_locations/migration.sql create mode 100644 App/tests/integration/delivery-locations.test.ts diff --git a/App/CLAUDE.md b/App/CLAUDE.md index ed2a1f5..0e104df 100644 --- a/App/CLAUDE.md +++ b/App/CLAUDE.md @@ -98,6 +98,12 @@ A PO's **cost centre is a Vessel** (the `Vessel` model). `PurchaseOrder.vesselId `Company` represents the sister company a PO is billed under (`PurchaseOrder.companyId`, optional). Fields: `name`, `code` (unique short code, e.g. `PMS`), `gstNumber`, `address`, `telephone`, `mobile`, `email`, `invoiceEmail`, `invoiceAddress`. Managed at `/admin/companies`. The selected company's details populate the **exported PO header / invoice block** (falling back to hardcoded Pelagia defaults when no company is linked). +### Delivery Locations (issue #19) + +`DeliveryLocation` (a `Company` FK + free-text `address` + `isActive`) is an admin-managed list that backs the PO **Place of Delivery** dropdown. Managed at `/admin/delivery-locations`, gated by the **`manage_delivery_locations`** permission (Manager + SuperUser + Admin — explicitly **not** admin-only, per the issue). The CRUD mirrors `/admin/sites` (table + Add/Edit dialogs + activate/deactivate + delete). + +The three PO forms (`new-po-form`, `edit-po-form`, `manager-edit-po-form`) render a shared `` — a native ` + + {companies.map((c) => ( + + ))} + + +
+ +