Skip to content

Edit a vendor invoice after upload (add/edit fingerprint + fields) + delete-unless-matched

Goal

Owner decision (2026-06-13, from T-029): rather than risky automatic word-by-word merchant-name matching (e.g. "GmbH" is too generic and would mis-match), let the USER make a first-seen vendor matchable by hand. So: 1. After upload, open a vendor invoice in a VIEW/EDIT drawer and edit its info β€” crucially ADD/EDIT the matching fingerprint (e.g. "OMNISALE") on its vendor, plus correct merchant/amount/date/currency/GL if needed. Saving a fingerprint should (re)run matching so a now-fingerprinted invoice can auto-link. 2. Allow DELETING an uploaded invoice β€” UNLESS it is already matched to a tx (matched invoices are locked from deletion; unmatch first).

Notes

  • The store already supports updates (updateReceipt/updateDocument) and the vendor fingerprint upsert (upsertVendorServer); the gap is the VIEW-TIME UI to edit the fingerprint + the delete-guard. Matcher entry: onVendorInvoiceCreated / vendorMatch.
  • Owner also floated auto word-by-word matching but rejected it as too risky (generic tokens). This task is the chosen alternative.

Confirmation (2026-06-13)

Owner: "use only fingerprint added by a user to match to tx if there's one." The matcher ALREADY does exactly this β€” vendorMatch.server.ts:133 requires vendor.fingerprints (stored, user-curated) and there is NO auto-derivation from the invoice merchant name. So the engine requirement is satisfied; T-031's job is purely the VIEW-TIME UI to add/edit that fingerprint (and re-run the match on save) + the delete-unless-matched guard. Possible add: an "amount as charged (HKD)" field for foreign-currency invoices (T-029b) so a USD invoice matches the settled-HKD tx without an FX engine.

Log

  • 2026-06-13 created from T-029 (owner asked for its own UID).
  • 2026-06-13 confirmed engine already fingerprint-only; scope = view-time edit UI + delete guard.
  • 2026-06-13 BACKEND done β€” new pages/api/records/vendor-invoices/[id].ts: PATCH edits invoice metadata + adds/replaces the vendor FINGERPRINT (upsertVendorServer) then re-runs onVendorInvoiceCreated (skips if already matched); DELETE returns 409 if the invoice is matched (status==='matched' || transactionId), else deletes. Typecheck clean. REMAINING: the VIEW-TIME UI in components/records/VendorInvoiceDetailDrawer.tsx (edit-mode fingerprint + fields, Saveβ†’PATCH, Deleteβ†’Popconfirm w/ 409 handling) + onUpdated refresh in VendorInvoicesTab.tsx. Browser-verify after.
  • 2026-06-14 UI DONE β€” VendorInvoiceDetailDrawer now shows a "Matching & actions" section for manual invoices: a Fingerprint input + "Save & match" (PATCH β†’ re-match, toasts the linked count) and a "Delete invoice" Popconfirm (handles the 409 matched-guard). Tab passes onChanged={fetchRows} to refresh. Typecheck clean. NOT browser-verified β€” port 3000 held by the owner's dev server; verify on Records β†’ Vendor Invoices (double-click a manual invoice).