---
title: Suppliers and finance
description: 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).

```bash
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`.

```bash
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.

```bash
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.

```bash
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
```

### Next steps

**[Customers and credit](/operations/customers-and-credit)**

Compare supplier payables with customer receivables.

**[Reports and dashboard](/operations/reports-and-dashboard)**

Review purchase spend by supplier in the purchases report.
