Partial-receipt flows call confirmReceipt multiple times. The nested
`create` on the Receipt relation threw a unique-constraint error on the
second call when both confirmations supplied notes, preventing any
delivery from completing and blocking attachment uploads.
Changed to `upsert` so subsequent confirmations update the existing
Receipt row's notes instead of failing.
Adds integration tests covering full receipt, partial receipt, the
upsert scenario (two confirmations each with notes), and permission guards.
Fixes#9
Moves the ItemInventory upsert from confirmReceipt (CLOSED) to approvePo
(MGR_APPROVED) so site inventory is visible as soon as a purchase order
is manager-approved, without waiting for full closure.
- approvePo: fetch lineItems, upsert ItemInventory per site PO line item
that has a productId; revalidate the site admin path.
- confirmReceipt: remove the now-redundant inventory update block.
- Rename approvepo → approvePo for consistency (fixes import mismatch
in the existing integration test file).
- Add three integration test cases covering: site PO inventory increment,
line items without productId are skipped, vessel-only POs are untouched.
Fixes#7
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Profile (fixes Safari/SSO no-password redirect):
- User lookup falls back to email when JWT id is stale (SSO users)
- generateDownloadUrl wrapped in try/catch so storage never crashes the page
- Signature gate now uses approve_po permission (approvers only)
- SSO/no-password users see a Set Password form (current-password field hidden)
Vendors:
- New create_vendor permission for all PO roles incl. submitters
- Submitters create UNVERIFIED vendors (no Vendor ID); simple form mode
- verifyVendor action + Verify menu item (manage_vendors)
- Vendors auto-verify when a PO closes with them (receipt confirm + import)
- Add Vendor button on /inventory/vendors
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Cost Centre on PO forms now shows only Vessels (plain vesselId field).
Sites are a separate concept and not selectable as cost centres.
- PurchaseOrder.vesselId is required again (NOT NULL restored)
- Vessel.siteId and vessel->site relation removed from schema
- DB migration: drops Vessel.siteId column, restores PO.vesselId NOT NULL
- All PO forms (new/edit/import/manager-edit): plain vessel <select> with
code-prefixed labels (e.g. "HNR1 — HNR 1")
- History, approvals, dashboard, my-orders, payments: back to vesselId
filter params and po.vessel.name display
- Admin vessels: removed Site column and site-assignment dropdown
- Admin sites detail page: removed "Assigned Vessels" section
- Sites table: removed Vessels count column (no longer linked)
- seed-prod.ts and seed.ts: vessels created without siteId
- SearchableSelect accounting code picker retained from previous commit
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Allow accounts to record partial/advance payments against a PO before
full delivery. A new PARTIALLY_PAID status tracks in-progress payment;
paidAmount accumulates across multiple markPaid calls. PO only closes
when both paidAmount >= totalAmount AND all line items are delivered.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
PO_SUBMITTED: managers only, submitter no longer copied
PAYMENT_SENT: submitter only (it is a receipt prompt, not a manager action)
PARTIAL_RECEIPT_CONFIRMED: managers now notified via new event type
RECEIPT_CONFIRMED: unchanged (managers + accounts)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
PARTIALLY_CLOSED was missing from the open-filter so affected POs
disappeared from the submitter''s My Orders view entirely, making it
impossible to confirm remaining deliveries.
Also hardens confirmReceipt() against negative delivery quantities
and extends partial-receipt.spec.ts with US-8c/8d/8e covering the
full PARTIALLY_CLOSED revisit flow.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>