WFDASH-WEBAPP/docs/handover-driver-invoice-photos.md
Dave 16743f87ed docs: driver invoice photo handover - widen the filter, use confirm_collected
Tested the handover against live PB on 2026-10-27. The read path works as
written; four defects fixed:

- The filter only caught item_status = 'assigned'. The collection_pool
  tab group is [collection_pool, assigned, ready_delivery] and
  order_items.confirm_collected accepts collection_pool or assigned, so
  a line stuck in either was invisible to the sweep.
- Stock POs were not covered at all. Stock lines live in
  stock_purchase_items and their photos on the parent
  stock_purchases.additional_attachments.
- The write path hand-rolled order_items.update + update_status, which
  skips the eligibility check, the over-collect guard, drv_collected_at
  and the actor-stamped audit note. Now uses
  order_items.confirm_collected / stock_purchase_items.mark_collected.
- No de-duplication: the NSS M24 line is still 'assigned' with a photo,
  so every run would re-report it. Added a 'Waiting on a person' list.

Also noted that no cron runs this yet, that order_items_attachements is
multi-file (read every filename), and added a supplier check.
2026-10-27 07:07:40 +02:00

5.6 KiB
Raw Blame History

Handover: driver invoice photos that were never collected

Run every 30 minutes during the working day (06:00–17:00 SAST).

Not scheduled yet. No cron task runs this — the 5 live crons are the MCODe basket, three PocketBase backups and the n8n watchdog. Until one is created, someone has to run this by hand.

The problem

Drivers photograph the supplier invoice on a PO in the driver app, but sometimes never tap Collect. The line then stays waiting, so it never reaches Collection Confirm and never gets invoiced. A new app version (auto invoice match + "Collect these items?" prompt) should stop this, but until it is proven, check by hand.

Sometimes the photo is also on the wrong PO (e.g. the Metabo invoice was uploaded on the Mega Lube PO), or is not an invoice at all.

Two sides to check — they are different collections with different attachment fields:

Side Line lives in Waiting statuses Photo lives in
Customer PO order_items collection_pool, assigned, ready_delivery order_items.order_item_attachements
Stock PO stock_purchase_items collection_pool, assigned_to_driver stock_purchases.additional_attachments (on the parent PO)

All three customer waiting statuses count. The "collection pool" tab group is ["collection_pool", "assigned", "ready_delivery"] and order_items_confirm_collected accepts collection_pool or assigned — a line stuck in any of them never reaches Collection Confirm.

The check

1. Find the lines

Customer lines — order_items_list with filter:

(item_status = "collection_pool" || item_status = "assigned" || item_status = "ready_delivery") && order_item_attachements:length > 0

expand purchase_order,supplier — the PO number is expand.purchase_order.po_number, it is not a field on the line itself.

Stock lines — stock_purchase_items_list with filter:

status = "collection_pool" || status = "assigned_to_driver"

expand purchase — the PO number is expand.purchase.purchase_number (looks like PO26100606STK, not PO...MAS), and the photos are in expand.purchase.additional_attachments.

2. Read every photo

order_item_attachements is a multi-file field (up to 10), and stock POs can have several pages (..._p1_, ..._p2_). Open each filename:

  • customer line → files_fetch, collection order_items, the line id, the filename
  • stock line → files_fetch, collection stock_purchases, the parent PO id, the filename

If a photo cannot be read as an invoice, treat the whole line as unreadable (below).

3. Compare the invoice with the line

  • the PO number printed on the invoice (reference / customer order no.) = the line's PO number
  • the supplier on the invoice = the line's supplier
  • the item matches the line's description
  • the quantity on the invoice = the line's quantity
  • the invoice is dated today or recently

What to do

  • Everything matches → mark it collected. Do not hand-roll this with order_items_update + order_items_update_status; use the tool that exists for it, because it validates eligibility, refuses to over-collect, stamps the audit note and refuses rows that are already past the pool:
    • customer line → order_items_confirm_collected with { item_ids: [...], actor: { id, name }, quantity_collected: { <line id>: <invoice qty> } }
    • stock line → stock_purchase_items_mark_collected with { id: <line id>, quantity_collected: <invoice qty> }
    • quantity_collected is the qty to add, not the new total. Omit it to collect the full remaining quantity.
    • actor.id is a free-form string — use mavis / Mavis so the notes feed shows who did it.
    • Do every line on that PO that is on the invoice.
  • Invoice shows less than ordered → do NOT mark it. Report it (the driver must collect the short quantity on the item card).
  • Photo is for a different PO → do NOT mark it. Report both PO numbers so a person can move the photo to the right PO.
  • Photo is not an invoice → do NOT mark it. Report it.
  • Can't read the photo / not sure → do NOT mark it. Report it.

Never cancel, delete, confirm, or change prices. Only ever mark a line collected, and nothing else.

Report

A short list: what you marked collected (supplier, PO, item, qty, invoice number) and what needs a person (and why). If nothing was found, say "nothing new".

Do not re-report what is already on the "Waiting on a person" list below — those lines stay in the waiting status until somebody moves them, so every run would otherwise find them again and repeat the same report 22 times a day. Add anything new to that list.

Waiting on a person

  • NSS M24 × 160 hex bolt ×60, PO202610018MAS (line 890919xtp0i8zfp, driver Joachim): the photo on it is NSS invoice 5031768 for PO202610080MAS (M12 cap screws, already collected and confirmed on 27 Oct). Wrong photo, so nothing proves the M24 bolts were collected. Ask Joachim.
  • Mega Lube oil aerosol ×3, PO202610073MAS (line ganf24h10lyrzdl, driver Joachim): no Mega Lube invoice anywhere — the line has no attachment at all, so the filter will not find it. Moved to 27 Oct. Ask Joachim.
  • UPL UNBRAKO 1 1/2 × 7 allen caps ×34, PO202609005CEM (line 47it7cxyu27dmd5): photo is on the line, but an operator bounced it back to "NOT READY" on 26 Oct, so it is not a forgotten Collect. Do not mark it.
  • NSS M6 × 30 CSK ×100, PO26100606STK (stock line o9jtrr0wasxxq2g): the photo on the PO is a picture of a laptop keyboard, not an invoice. Needs a person to re-shoot it.