Adds a "Discard" button to the PO detail header for any DRAFT PO.
Submitters, managers, and superusers can discard. The action deletes
the PO and its related actions/notifications, then redirects to
/my-orders. Non-cascade child records (POAction, Notification) are
explicitly deleted in a transaction before the PO row is removed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Permissions & access:
- MANAGER gains create_po, submit_po, edit_own_draft_po, view_own_pos, manage_vendors
- ACCOUNTS gains manage_vendors
- ACCOUNTS added to provide_vendor_id state transition
- MANAGER added to DRAFT/EDITS_REQUESTED submit allowed roles
- canProvideVendorId now includes ACCOUNTS and any MANAGER/SUPERUSER
Vendor required for approval:
- approvepo() now returns error if po.vendorId is null
- Approval page shows danger banner when vendor is missing
Navigation:
- MANAGER gets "New PO", "My Purchase Orders", "Import PO", "Vendors" nav items
- ACCOUNTS gets "Vendors" nav item
Seed data:
- Vendors: 12 total (up from 3), with GST, address, contact details
- Products: 25 total (up from 4), with lastPrice pre-populated
Product fuzzy search in line items editor:
- Typing ≥2 chars in description fetches /api/products/search?q=
- Dropdown shows code, name, description, last price
- Selecting a product auto-fills description and unit price
- Linked items show a "✓ linked" indicator
- productId passed through FormData to createPo action and stored on POLineItem
Excel PO import (/po/import):
- MANAGER, SUPERUSER, ADMIN can access
- Uploads .xlsx file to /api/po/import which parses the Pelagia PO format
- Extracts vendor, line items, quotation ref, T&C, delivery address
- Preview step: user selects vessel + account, auto-matches vendor by name
- Confirmed import creates PO in DRAFT status
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Convert quantity, unitPrice, totalPrice, gstRate, and totalAmount to
plain numbers in server pages before passing to client components,
preventing Next.js serialization errors on Decimal objects.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
font-mono (monospace) renders optically larger than the surrounding
sans-serif at the same em size. Removing it from quantity, unit price,
taxable, GST% and total cells in both read-only and edit mode makes
all numbers visually consistent with the rest of the page.
formatCurrency reverted to Intl.NumberFormat with style:currency (the
original implementation); the spacing issue the user saw was font-related,
not symbol-related.
formatCurrency: manually prepend Rs symbol instead of using Intl currency
style, which could inject a non-breaking space between the symbol and number.
po-detail vendor section: replace font-mono on Vendor ID with font-medium
text-neutral-900 so it matches all other detail fields. Not assigned
indicator changed from italic warning text to a small pill badge.
GSTIN keeps mono (it is a standardised code) but now has correct text colour
and tracking for legibility.
Replaces the line-items-only editor with a full ManagerEditPoForm that
covers every field: title, vessel, account, vendor, project code, delivery
date, PI/Quotation No+Date, Requisition No+Date, place of delivery, all
structured T&C fields, and line items (with GST rate).
Edit toggle is amber-styled to distinguish manager changes from submitter
input. On save, a complete snapshot of original values is written to the
audit trail (MANAGER_LINE_EDIT action with metadata.original).
managerEditPo server action: validates manager permission, checks
status == MGR_REVIEW, recalculates totalAmount as grand total including
GST, and persists all updated fields.
Approval detail page now fetches vessels/accounts/vendors to populate the
edit form dropdowns.
link-document server action attaches an uploaded file to a PO after creation.
requirements.txt lists Python packages used for standalone PO generation scripts.
GET /api/po/[id]/export?format=pdf — HTML print page; company header, PO meta grid,
vendor block with GSTIN, line items table with taxable/GST%/total columns,
totals (taxable subtotal, GST, grand total), numbered T&C list, dual signature block.
GET /api/po/[id]/export?format=xlsx — SheetJS workbook matching Sample_PO.xlsx column layout.
Export PDF / Export XLSX buttons added to PO detail header.
Products: code, name, description; lastPrice and lastVendor are read-only.
On markPaid: for each line item linked to a product, Product.lastPrice and
lastVendorId are updated automatically and logged as PRODUCT_PRICE_UPDATED.
Users: CRUD with role assignment, bcrypt password, cannot deactivate own account.
Vendors: CRUD with address, GSTIN, contact mobile; isVerified set when vendorId provided.
Vessels: CRUD with IMO number uniqueness check.
Accounts: CRUD with unique account code.
Full audit list of all POs (latest 200). Filters: date range, vessel, status.
CSV export respects active filters. PDF export renders print-optimised HTML table.
My Orders: all submitter POs grouped as open/past with live status, manager note inline.
Receipt: upload receipt file, optional notes; confirms delivery and closes PO to CLOSED.
Step 1 (process): MGR_APPROVED → SENT_FOR_PAYMENT, notifies submitter and managers.
Step 2 (mark paid): SENT_FOR_PAYMENT → PAID_DELIVERED, stores paymentRef.
On mark paid: auto-updates Product.lastPrice and lastVendorId for any line items
linked to a product code; logs PRODUCT_PRICE_UPDATED action.
Approval queue: paginated list with search (PO number, vessel, submitter, date range).
Decision actions: approve, approve with note, reject (with reason), request edits,
request vendor ID.
Manager line edit: amend line items during review; original snapshot saved to audit
trail; diff shown with amber strikethrough on PO detail.
Detail: order info, vendor (address/GSTIN/contact), line items with GST breakdown,
structured T&C, attachments, activity trail, Export PDF/XLSX buttons.
Vendor ID form: inline on PO detail when status is VENDOR_ID_PENDING.
Edit: pre-populated form for DRAFT and EDITS_REQUESTED; resubmit transitions to MGR_REVIEW.
Form sections: order info, quotation reference (PI No/Date), requisition (No/Date),
place of delivery, line items (UoM dropdown, size, GST% per item), vendor, T&C, attachments.
Line items editor: add/remove rows, GST dropdown (0/5/12/18/28%, default 18%),
live taxable/GST/grand-total breakdown.
T&C: fixed line 1, individual inputs for Delivery, Dispatch, Inspection,
Transit Insurance, Payment Terms, Others.
Save as draft or submit directly for approval (→ MGR_REVIEW).
Submitter: open PO count, recent orders table, New PO CTA.
Manager: approvals count, approved PO listing, spend by vessel and month bar charts (Recharts).
Accounts: payment queue total value, ready-for-payment count.
Admin/Auditor: total PO count card.
Sign API returns presigned upload URL + storage key.
Dev: files served through auth-gated /api/files/dev route with path-traversal protection.
Prod: R2 presigned URLs for upload and time-limited download.
7 event templates: po-submitted, po-approved, po-rejected, edits-requested,
vendor-id-needed, payment-processed, receipt-confirmed.
Notifier uses Resend in production and console.log in development.
10 statuses, 11 transitions. Each transition declares allowedRoles,
requiresNote flag and sideEffects (which email groups to notify).
Helpers: getTransition, canPerformAction, getAvailableActions, requiresNote.