WFDASH-WEBAPP/src/lib/server
David dce54934f0 fix(invoicing): bill only what's collected, support partial pickups + kit splits
The invoice qty rule used to read the customer's order qty regardless
of how much the driver actually collected. QuickBooks ended up billing
8-of-10 on one line and 7-of-10 on the other for Kusasalethu PO 390588
(INV10924) — a 5-unit overbilling that the mine's receiving team flags
as suspicious.

The rule now caps the invoice qty at min(qty_collected, quantity):
  - Short pickup → bill what's collected, the row stays at
    item_status="ready_invoice" with qty_invoiced < quantity, and a
    follow-up invoice fires automatically when the rest arrives.
  - MOQ overflow → still capped at the customer's order qty; the
    surplus-book flow continues to route the overflow to stock.

The Invoicing page now shows "N short" / "N units short" badges on
short-pickup rows, a "N hidden" badge when supplier-side rows are
suppressed, and a "Show supplier-side lines" toggle (default OFF) so
the invoicing operator doesn't see kit-component remainders unless she
needs to. A split-remainder dialog on the order process page lets the
operator explicitly flag a remainder as exclude_from_invoice=true when
the original line was a kit (e.g. "M20 bolt comes with nut and washer"
split across 3 suppliers).

PB schema additions (one-time, run scripts/nss-add-invoice-columns.ts):
  - order_items.qty_invoiced            (number)
  - order_items.customer_invoice_number (text)
  - order_items.invoiced_date           (date)

These three columns were referenced throughout the codebase but never
existed on the live schema, so writes were being silently dropped. The
schema fix unblocks the reconcile flow that stamps them after every
QB webhook returns.

Backfill for the live Kusasalethu order: scripts/nss-fix-kusasalethu-inv10924.ts
updates order_items.quantity 10→8 / 10→7 to match what was collected,
stamps the new columns, and flips order.invoiced=true.

New server helper reconcileOrderItemInvoicedStatus() runs after each
QB webhook and per-row decides:
  - item_status = "invoiced"     if qty_invoiced >= quantity (fully billed)
  - item_status = "ready_invoice" otherwise (still partial — stays in
    the to-invoice tab for a follow-up invoice once the rest arrives)

Wired into both the bulk invoicing page and the delivery-note-invoice
route. markOrderInvoiced now compares against qty_invoiced vs
quantity rather than the flat item_status check, and its error
message names the outstanding shortfall per row.
2026-09-17 13:53:36 +02:00
..
agent-auth.test.ts
agent-auth.ts
ai-settings-service.ts
ai-system-prompt.ts
attachment-extractor.ts
boss-dashboard-service.test.ts test(boss-dashboard): honour expand in mock + assert customer name in rep activity 2026-08-28 00:02:02 +02:00
boss-dashboard-service.ts chore: update page.tsx 2026-09-02 01:38:33 +02:00
browser-session.test.ts feat: add getBrowserSessionUser for routes that need the caller's identity 2026-09-01 01:33:10 +02:00
browser-session.ts feat: add getBrowserSessionUser for routes that need the caller's identity 2026-09-01 01:33:10 +02:00
buyer-tasks-service.test.ts feat(quotes): enhance scoring logic to include price matching 2026-08-24 07:09:39 +02:00
buyer-tasks-service.ts feat(quotes): enhance scoring logic to include price matching 2026-08-24 07:09:39 +02:00
collection-confirm-service.test.ts feat(collection-confirm): update stock item filtering logic in listCollectedItems 2026-08-17 08:27:36 +02:00
collection-confirm-service.ts feat(collection-confirm): update stock item filtering logic in listCollectedItems 2026-08-17 08:27:36 +02:00
collection-confirm-upload.test.ts
completed-window.test.ts feat(quotes): enhance scoring logic to include price matching 2026-08-24 07:09:39 +02:00
counter-service.ts
customers-coordinates.test.ts feat(visits): batch pin tool — tag every customer on a shaft at once 2026-09-07 08:30:23 +02:00
customers-service.test.ts
customers-service.ts feat(customers): add status toggle and site/location field 2026-09-16 09:47:09 +02:00
dashboard-service.test.ts
dashboard-service.ts
deliveries-service.test.ts feat(deliveries): enhance delivery notes management and UI 2026-08-17 01:27:03 +02:00
deliveries-service.ts fix(deliveries): group by company and show items on delivery-note rows 2026-09-14 12:58:43 +02:00
delivery-note-order-match.test.ts feat(orders): include selling_price in duplicate-detection line match 2026-08-31 09:03:00 +02:00
delivery-note-order-match.ts feat(orders): include selling_price in duplicate-detection line match 2026-08-31 09:03:00 +02:00
delivery-notes-service.test.ts fix(delivery-notes): backfill customer/company when linking a DN's order 2026-09-07 10:39:22 +02:00
delivery-notes-service.ts feat(quotes): split attachments into internal vs outbound with operator upload UI 2026-09-09 13:43:56 +02:00
driver-stops.ts fix(orders): bill the customer quantity, not the supplier order_qty 2026-08-30 18:28:33 +02:00
item-history-service.test.ts
item-history-service.ts
item-intel-service.ts
management-service.ts
mcp-upstream-fetch.test.ts
mcp-upstream-fetch.ts
order-completion.test.ts
order-completion.ts
order-delivery-note-link-service.test.ts feat(orders): include selling_price in duplicate-detection line match 2026-08-31 09:03:00 +02:00
order-delivery-note-link-service.ts feat(orders): include selling_price in duplicate-detection line match 2026-08-31 09:03:00 +02:00
order-item-context-service.test.ts
order-item-context-service.ts
order-item-margin-approval-service.test.ts feat(orders): bypass margin gate for non-invoiceable extras 2026-08-30 17:21:28 +02:00
order-item-margin-approval-service.ts feat(orders): bypass margin gate for non-invoiceable extras 2026-08-30 17:21:28 +02:00
order-item-status.test.ts
order-item-status.ts
order-items-service.test.ts fix(invoicing): bill only what's collected, support partial pickups + kit splits 2026-09-17 13:53:36 +02:00
order-items-service.ts fix(invoicing): bill only what's collected, support partial pickups + kit splits 2026-09-17 13:53:36 +02:00
order-number-duplicate-link-service.test.ts fix(orders): document PB schema prerequisite + strengthen duplicate-matcher tests 2026-08-30 22:08:24 +02:00
order-number-duplicate-link-service.ts fix(orders): document PB schema prerequisite + strengthen duplicate-matcher tests 2026-08-30 22:08:24 +02:00
order-order-duplicate-link-service.test.ts perf(orders): bulk-fetch candidate items in suggestOrderDuplicate (kill N+1) 2026-08-30 23:57:20 +02:00
order-order-duplicate-link-service.ts feat(orders): include selling_price in duplicate-detection line match 2026-08-31 09:03:00 +02:00
order-quote-link-service.test.ts feat(orders): add quote-match backlog sweep with age-gap reporting 2026-08-30 08:45:23 +02:00
order-quote-link-service.ts feat(orders): add quote-match backlog sweep with age-gap reporting 2026-08-30 08:45:23 +02:00
order-quote-match.test.ts fix(orders): parse PocketBase date format explicitly in the matcher 2026-08-29 13:20:40 +02:00
order-quote-match.ts fix(orders): parse PocketBase date format explicitly in the matcher 2026-08-29 13:20:40 +02:00
orders-service-review.test.ts fix(orders): update order_number collision-checking logic 2026-08-31 01:24:56 +02:00
orders-service.test.ts fix(invoicing): bill only what's collected, support partial pickups + kit splits 2026-09-17 13:53:36 +02:00
orders-service.ts fix(invoicing): bill only what's collected, support partial pickups + kit splits 2026-09-17 13:53:36 +02:00
po-email-template.ts
po-number.test.ts
po-number.ts
pocketbase-admin.test.ts
pocketbase-admin.ts
pos-auth.test.ts feat(pos): add assertPosAuth for POS_API_KEY-gated routes 2026-08-31 01:30:52 +02:00
pos-auth.ts feat(pos): add assertPosAuth for POS_API_KEY-gated routes 2026-08-31 01:30:52 +02:00
pos-letterhead-service.ts fix(pos): print the letterhead's own logo, and match delivery note to the sale slip 2026-09-06 23:03:24 +02:00
pos-service.test.ts feat: implement discount functionality in POS system 2026-09-03 12:19:21 +02:00
pos-service.ts fix(pos): fix uncaught 500 on checkout, allow overselling into negative stock 2026-09-04 13:00:12 +02:00
pos-slip-layout-service.test.ts feat(pos): add pos-slip-layout-service for reading/writing per-letterhead slip layouts 2026-09-04 13:23:09 +02:00
pos-slip-layout-service.ts feat(pos): add pos-slip-layout-service for reading/writing per-letterhead slip layouts 2026-09-04 13:23:09 +02:00
price-list-match.test.ts
price-list-match.ts
price-list-service.test.ts feat(stock): seed pricing fields on create + sync price_list to stock_items 2026-09-14 13:04:08 +02:00
price-list-service.ts feat(stock): seed pricing fields on create + sync price_list to stock_items 2026-09-14 13:04:08 +02:00
purchase-order-agent-service.test.ts
purchase-order-agent-service.ts
purchase-orders-service.test.ts
purchase-orders-service.ts
quote-email-template.ts
quote-items-insights-service.test.ts
quote-items-insights-service.ts
quote-items-service.test.ts
quote-items-service.ts
quote-pdf-service.test.ts fix(quotes): persist letterhead choice on terminal-status quotes too 2026-09-09 18:09:27 +02:00
quote-pdf-service.ts fix(quotes): persist letterhead choice on terminal-status quotes too 2026-09-09 18:09:27 +02:00
quoted-before-service.test.ts feat(quotes): add quote-level "Quoted before?" panel to the process page 2026-08-29 08:52:19 +02:00
quoted-before-service.ts feat(quotes): add quote-level "Quoted before?" panel to the process page 2026-08-29 08:52:19 +02:00
quotes-ai-processor.ts
quotes-from-email-service.test.ts fix(quotes-intake): clamp email_body to PB's 5000-char cap 2026-09-08 10:28:20 +02:00
quotes-from-email-service.ts fix(quotes-intake): clamp email_body to PB's 5000-char cap 2026-09-08 10:28:20 +02:00
quotes-search-service.test.ts fix(quotes-search): order hits by created desc so the most recent match is on top 2026-09-08 10:24:34 +02:00
quotes-search-service.ts fix(quotes-search): order hits by created desc so the most recent match is on top 2026-09-08 10:24:34 +02:00
quotes-service.test.ts feat(quotes): split attachments into internal vs outbound with operator upload UI 2026-09-09 13:43:56 +02:00
quotes-service.ts feat(quotes): split attachments into internal vs outbound with operator upload UI 2026-09-09 13:43:56 +02:00
rep-dashboard-service.test.ts feat(dashboard2): trim Row 1 to Selling-only with last-month delta 2026-09-01 01:55:52 +02:00
rep-dashboard-service.ts perf(dashboard2): consolidate 14 PB count queries into 1 fetch 2026-09-01 02:08:52 +02:00
repairs-service.ts chore: update AGENTS.md 2026-09-02 01:17:05 +02:00
stock-booking-service.test.ts
stock-booking-service.ts feat(stock): implement auto-markup for selling price and markup on stock item creation and updates 2026-09-16 09:49:52 +02:00
stock-cost-service.ts feat(stock): implement auto-markup for selling price and markup on stock item creation and updates 2026-09-16 09:49:52 +02:00
stock-default-markup-service.test.ts feat(stock): implement auto-markup for selling price and markup on stock item creation and updates 2026-09-16 09:49:52 +02:00
stock-default-markup-service.ts feat(stock): implement auto-markup for selling price and markup on stock item creation and updates 2026-09-16 09:49:52 +02:00
stock-items-export.test.ts feat: implement discount functionality in POS system 2026-09-03 12:19:21 +02:00
stock-items-import.test.ts feat: implement discount functionality in POS system 2026-09-03 12:19:21 +02:00
stock-items-service.test.ts feat(stock): implement auto-markup for selling price and markup on stock item creation and updates 2026-09-16 09:49:52 +02:00
stock-items-service.ts feat(stock): implement auto-markup for selling price and markup on stock item creation and updates 2026-09-16 09:49:52 +02:00
stock-out.ts
stock-pricing-service.test.ts test(stock): cover validation + not_found + per-row independence 2026-08-31 16:48:40 +02:00
stock-pricing-service.ts fix(stock): skip ledger row on first-time pricing + include cost delta in notes 2026-08-31 16:46:42 +02:00
stock-purchase-invoice-matching-service.test.ts
stock-purchase-invoice-matching-service.ts
stock-purchase-items-service.test.ts chore(tests): fix ~60 pre-existing TS errors across 11 test files 2026-08-27 04:43:40 +02:00
stock-purchase-items-service.ts feat(collection-confirm): add quantity collection handling and deduplication improvements 2026-08-17 02:17:27 +02:00
stock-purchases-migration.test.ts
stock-purchases-service.attachments.test.ts
stock-purchases-service.test.ts
stock-purchases-service.ts
stock-quantities-service.test.ts feat(stock): inline qty editing + column sort + pricing-gap operator scripts 2026-09-14 13:04:26 +02:00
stock-quantities-service.ts feat(stock): inline qty editing + column sort + pricing-gap operator scripts 2026-09-14 13:04:26 +02:00
stock-quick-draft-service.test.ts feat(stock): implement auto-markup for selling price and markup on stock item creation and updates 2026-09-16 09:49:52 +02:00
stock-quick-draft-service.ts feat(stock): implement auto-markup for selling price and markup on stock item creation and updates 2026-09-16 09:49:52 +02:00
stock-surplus.test.ts fix(orders): bill the customer quantity, not the supplier order_qty 2026-08-30 18:28:33 +02:00
stock-surplus.ts fix(orders): bill the customer quantity, not the supplier order_qty 2026-08-30 18:28:33 +02:00
tracker-service.test.ts feat(tracker): breadcrumb poller — WFDASH's own vehicle position history 2026-09-06 20:08:20 +02:00
tracker-service.ts feat(tracker): breadcrumb poller — WFDASH's own vehicle position history 2026-09-06 20:08:20 +02:00
tv-dashboard-service.ts feat(tv-dashboard): enhance TV dashboard with driver stops and performance metrics 2026-08-19 10:16:49 +02:00
tv-session.ts
vehicle-trail-service.test.ts feat(tracker): breadcrumb poller — WFDASH's own vehicle position history 2026-09-06 20:08:20 +02:00
vehicle-trail-service.ts feat(tracker): breadcrumb poller — WFDASH's own vehicle position history 2026-09-06 20:08:20 +02:00
visits-service.test.ts fix(visits): surface batch write failures instead of a silent 200 2026-09-06 21:25:52 +02:00
visits-service.ts fix(visits): surface batch write failures instead of a silent 200 2026-09-06 21:25:52 +02:00