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.
5.4 KiB
Supplier payments and order-item approvals
Under Orders, open Payments and Approvals (/orders/payments-approvals).
- On the order process page, toggle Payment required for an item. Create and send its supplier PO normally.
- The payment row automatically links the PO. Choose Upload supplier invoice to add an invoice, pro forma or photo.
- 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.
- 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.
- Back up the live PB database using the normal deployment procedure.
- Run
npm run pb:migrate:order-paymentswith the intended PB admin environment. The migration is idempotent. It creates the metadata-onlysupplier_payment_requestscollection andorder_items.payment_status/payment_request; it does not alter the existingitem_statusselect values. Request collection list/view/write rules are admin-only; application routes validate the office browser session. - Commit/publish
pocketbase/pb_hooks/usingnpm run pb:hooks:publishafter its changes have reached the deployment branch.DEPLOYincludes bothorder_payments.pb.jsandorder_payment_utils.jsplus the audit helper. The VPS sync process reloads hooks; seescripts/pb-hooks/README.md. - Verify the superuser-authenticated
GET /api/wfdash/order-payments-capabilityreturns{ "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. - 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. - 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:runfor the full suite. Existing baseline script-import errors, if any, must be reported separately rather than ignored.npx tsc --noEmitandnpm 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=1checks 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.mjsstarts 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 and 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.