Suppliers and finance
Manage supplier records, track supplier invoices and payments, quarantine batches, and get reorder suggestions.
You manage the supply side from two files: apps/server/src/features/suppliers/route.ts for the supplier directory and apps/server/src/features/supplier-finance/route.ts for invoices, payments, reorder suggestions, and batch quarantine.
Manage the supplier directory
List suppliers with GET /suppliers, paginated at 20 per page and sorted by name. Filter with search (name or tax number) and is_active (true by default, false for deactivated, all for everything). Fetch one record with GET /suppliers/:supplierId.
Create, update, and deactivate suppliers only with the admin, inventory_manager, or branch_manager role. On create, you can set supplier_type (default distributor), lead_time_days (default 7), and reliability_score (default 100).
curl -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"name":"Abacus Parenteral","tax_number":"TIN-1001","supplier_type":"distributor","lead_time_days":5,"reliability_score":95}' \
http://localhost:8000/api/v1/suppliers
Update with PUT /suppliers/:supplierId using the allowlist in allowedUpdates. Delete with DELETE /suppliers/:supplierId performs a soft delete by setting is_active to 0 and returns 204.
Track supplier invoices
Record what you owe a supplier with POST /supplier-finance/invoices, passing supplier_id, total_amount, and optionally branch_id (defaults to your branch), invoice_no, due_date, and notes. The invoice starts with paid_amount 0 and status unpaid.
curl -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"supplier_id":"SUP_ID","invoice_no":"INV-2041","total_amount":850000}' \
http://localhost:8000/api/v1/supplier-finance/invoices
List with GET /supplier-finance/invoices, optionally filtered by supplier_id, newest first, capped at 50 rows.
Pay down an invoice
Pay with POST /supplier-finance/invoices/:invoiceId/payments. The amount must be positive. The handler adds your payment to paid_amount and flips the status to partial, or to paid once the total is covered. Each payment row records method (default cash), reference, and who paid.
curl -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"amount":400000,"method":"bank_transfer","reference":"TRX-991"}' \
http://localhost:8000/api/v1/supplier-finance/invoices/INV_ID/payments
Act on reorder suggestions
Get a restock list with GET /supplier-finance/reorder-suggestions. It returns up to 100 active medicines whose stock sits at or below low_stock_threshold, with suggested_qty computed as twice the threshold minus current stock, ordered with the lowest stock first. Use lead_time_days from the joined supplier to prioritise slow arrivals.
Quarantine a batch
Hold or release stock with POST /supplier-finance/batches/:batchId/quarantine. The body field status accepts only quarantined, active, or recalled, and the handler writes it to batches.sfda_status. Anything else returns a 400.
curl -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"status":"quarantined"}' \
http://localhost:8000/api/v1/supplier-finance/batches/BATCH_ID/quarantine