WFDASH-WEBAPP/docs/order-payments.md
Dave 97603dce71 refactor: simplify supplier payments to document checklist
Remove payment amount, reference, notes and manual combining forms. Link supplier POs automatically and record paid from supplier evidence plus proof, keeping readiness and attachment safeguards.

Keep active supplier/company views current and retire stale supplier evidence on routing changes. Verified 5167 tests with only the two existing script-import errors.
2026-11-03 07:18:56 +02:00

39 lines
5.4 KiB
Markdown

# Supplier payments and order-item approvals
Under Orders, open **Payments and Approvals** (`/orders/payments-approvals`).
1. On the order process page, toggle **Payment required** for an item. Create and send its supplier PO normally.
2. The payment row automatically links the PO. Choose **Upload supplier invoice** to add an invoice, pro forma or photo.
3. Choose **Upload proof of payment**, then **Mark paid** once payment has been made. No amount, reference, notes or request-confirmation form is needed; the supplier document tells the payer what to pay.
4. The item can now become ready through the normal collection flow. Payment itself does not mark ready, assign a driver, change markup approval or move the workflow forward.
Rows show Company/order, Supplier, Items, PO, Supplier documents, Proof of payment and Paid. The history filter retains paid/cancelled records. Approvals is the existing order-item markup approval queue; its current WhatsApp/n8n process remains unchanged.
The backend requires supporting evidence (uploaded supplier document or linked PO PDF), proof and a current item revision before recording Paid. If an item changes while a payer has the page open, refresh before retrying. Existing file preservation, atomic upload deduplication, historical paid proof protection and collection-readiness checks remain in force.
## Live rollout (manual)
No live migration, hook publish or application deploy is performed by implementing this feature.
1. Back up the live PB database using the normal deployment procedure.
2. Run `npm run pb:migrate:order-payments` with the intended PB admin environment. The migration is idempotent. It creates the metadata-only `supplier_payment_requests` collection and `order_items.payment_status` / `payment_request`; it does **not** alter the existing `item_status` select values. Request collection list/view/write rules are admin-only; application routes validate the office browser session.
3. Commit/publish `pocketbase/pb_hooks/` using `npm run pb:hooks:publish` after its changes have reached the deployment branch. `DEPLOY` includes both `order_payments.pb.js` and `order_payment_utils.js` plus the audit helper. The VPS sync process reloads hooks; see `scripts/pb-hooks/README.md`.
4. Verify the superuser-authenticated `GET /api/wfdash/order-payments-capability` returns `{ "version": 3 }`. It verifies required schema fields and identifies the simplified document-and-proof workflow with transactionally deduplicated uploads. Do not enable requests with an older guard. The Next service checks this endpoint before every mutation and displays an unavailable state until schema and hooks are ready.
5. Deploy the application. Document uploads use a PocketBase transaction for capacity checks, content-identity lookup and additive writes, so concurrent retries cannot append duplicate proof. All paid proof files remain protected across later payment requests. New APIs accept a validated user PB token in `Authorization: Bearer …`; the browser helper sends it. No agent secret is exposed to the browser. Existing office access is used; no new accountant role is introduced.
6. On a designated test order, require payment and verify supplier PO processing remains possible; direct and manual ready-for-collection must fail before proof/paid. Complete the test request with real designated test evidence, confirm that Paid alone does not set ready, then perform the normal readiness step. Also verify the readiness date tick skips an unpaid test item.
Deploy enforcement before making any payment requirement available. A missing capability/schema produces a 503 on mutations; legacy items without payment fields/requirements continue normally. Do not run test writes against real customer items accidentally.
## Verification
- `npm run test:run` for the full suite. Existing baseline script-import errors, if any, must be reported separately rather than ignored.
- `npx tsc --noEmit` and `npm run build`.
- `npx vitest run src/lib/server/order-payment-hooks.test.ts src/lib/server/order-payment-service.test.ts src/app/api/v1/order-payments/route.test.ts src/components/orders/order-item-payment.test.tsx src/components/orders/payments-approvals-page.test.tsx src/lib/server/collection-ready-dates-service.test.ts`.
- `E2E_BASE_URL=http://localhost:3194 npx playwright test e2e/order-payments.spec.ts --workers=1` checks desktop/mobile with fixture API responses, proof-required interaction and actual form submission.
- `POCKETBASE_TEST_BINARY=/absolute/path/to/pocketbase node scripts/smoke/order-payments-hooks.mjs` starts an ephemeral isolated local PB 0.39.8 instance, runs the migration twice and exercises actual hooks/transactions. It never connects to the live PB. Obtain the platform binary from the official PocketBase release for that pinned version.
The model/request guards use PocketBase's transaction and event APIs; see [record operations](https://pocketbase.io/docs/js-records/) and [event hooks](https://pocketbase.io/docs/js-event-hooks/).
## Rollback
Do not remove payment guards or fields while there are outstanding holds. First stop new requests by reverting the app feature, retain the hooks and metadata, and settle or explicitly cancel outstanding requests through the payment actions. Removing guards alone permits unpaid collection; removing metadata loses evidence/history. Restore a tested database backup only through the established rollback process, never by deleting request records.