-
Notifications
You must be signed in to change notification settings - Fork 137
Inward Item Request API
The Inward Item Request API (/api/itemrequests) lets an external system — such as a patient mobile app or a ward request terminal — submit service requests (e.g. ward services, investigations) and stock item requests (e.g. medicines, consumables) against an admitted patient's BHT.
Requests are saved as Pending — the patient is not charged and no stock moves. Each request is routed to a target department's in-app queue, where a privileged department user processes each line by billing it through the normal Add Services/Investigations page (services) or Direct Issue to BHTs page (stock items), or rejects still-pending lines with a reason. Status is tracked per line, so a request can be fulfilled gradually across more than one visit, and can end up partially fulfilled and partially rejected.
Important: Processing and rejection happen only inside HMIS — there is no API for them. The external system polls
GET /api/itemrequests/{id}to learn the outcome.
For the in-app side of the workflow, see Inward Service and Item Requests (Approval Queue).
All endpoints require an API key in the Finance HTTP header:
Finance: <your-api-key>
API keys are issued in the HMIS Admin panel under API Key Management. The key must be active (not retired), activated, and not expired. Missing or invalid keys return 401.
{"status": "success", "code": 200, "data": { ... }}
{"status": "error", "code": 400, "message": "..."}POST /api/itemrequests
Request body:
{
"bhtNo": "RH/2026/001234",
"targetDepartmentId": 42,
"comments": "Patient requested via mobile app",
"lines": [
{"itemId": 1001, "qty": 1},
{"itemId": 2002, "qty": 2}
]
}A single request may mix service lines and stock item lines. Validation rules:
-
bhtNomust be an active admission (not discharged, final bill not settled) -
targetDepartmentIdmust be an active department - At least one line; every
itemIdmust be an active item; everyqtymust be greater than 0
Response 200 — the request in PENDING state:
{
"status": "success",
"code": 200,
"data": {
"id": 98765,
"requestNo": "Inward//26/000123",
"bhtNo": "RH/2026/001234",
"targetDepartmentId": 42,
"targetDepartmentName": "Ward",
"status": "PENDING",
"comments": "Patient requested via mobile app",
"createdAt": "2026-07-02 09:15:00",
"createdBy": "api-user",
"fulfillingBillIds": [],
"lines": [
{"billItemId": 111, "itemId": 1001, "itemName": "Oxygen Charges", "itemType": "SERVICE", "qty": 1.0, "netValue": 0.0, "status": "PENDING"},
{"billItemId": 112, "itemId": 2002, "itemName": "Panadol 500mg tab", "itemType": "INVENTORY", "qty": 2.0, "netValue": 0.0, "status": "PENDING"}
]
}
}GET /api/itemrequests/{id}
Returns the same structure as above. status on the request reflects the mix of its lines — PENDING, PARTIALLY_FULFILLED, FULFILLED, REJECTED, PARTIALLY_FULFILLED_AND_REJECTED, or CANCELLED. fulfillingBillIds lists every distinct real bill id that has fulfilled at least one line so far. Each line in lines carries its own status (PENDING / FULFILLED / REJECTED), and once fulfilled or rejected also carries fulfillingBillId + fulfillingBillType, or rejectionReason respectively. Unknown ids return 404.
Example of a partially processed request (one line billed, one still pending):
{
"status": "success",
"code": 200,
"data": {
"id": 98765,
"requestNo": "Inward//26/000123",
"status": "PARTIALLY_FULFILLED",
"fulfillingBillIds": [55321],
"lines": [
{"billItemId": 111, "itemId": 1001, "itemName": "Oxygen Charges", "itemType": "SERVICE",
"qty": 1.0, "netValue": 500.0, "status": "FULFILLED",
"fulfillingBillId": 55321, "fulfillingBillType": "InwardBill"},
{"billItemId": 112, "itemId": 2002, "itemName": "Panadol 500mg tab", "itemType": "INVENTORY",
"qty": 2.0, "netValue": 0.0, "status": "PENDING"}
]
}
}GET /api/itemrequests?targetDepartmentId=&status=&fromDate=&toDate=&limit=
All query parameters are optional:
| Parameter | Format | Meaning |
|---|---|---|
targetDepartmentId |
number | Only requests for this department |
status |
PENDING | PARTIALLY_FULFILLED | FULFILLED | REJECTED | PARTIALLY_FULFILLED_AND_REJECTED | CANCELLED
|
Filter by the request's overall derived status |
fromDate / toDate
|
yyyy-MM-dd |
Filter by submission date |
limit |
number | Maximum rows returned |
Returns a list of lightweight rows: id, requestNo, bhtNo, targetDepartmentName, status, createdAt.
PUT /api/itemrequests/{id}/cancel
Request body:
{"reason": "Duplicate submission"}Withdraws the request while it is still PENDING (no line has been fulfilled or rejected yet). Returns the updated request with status: "CANCELLED". If any line has already been fulfilled or rejected, the call fails — cancel a request only before anyone has acted on it.
Status is derived from the mix of line statuses, not stored as a single flag:
PENDING --(this API, cancel)--------------------------------> CANCELLED
PENDING --(department processes some lines)-----------------> PARTIALLY_FULFILLED
PENDING --(department processes all lines)-------------------> FULFILLED
PENDING --(department rejects all remaining lines)-----------> REJECTED
PARTIALLY_FULFILLED --(department rejects the rest)----------> PARTIALLY_FULFILLED_AND_REJECTED
- PENDING — no line has been fulfilled or rejected yet.
- PARTIALLY_FULFILLED — at least one line fulfilled, at least one still pending.
- FULFILLED — every line fulfilled (no pending or rejected lines remain).
- REJECTED — every line rejected, none fulfilled.
- PARTIALLY_FULFILLED_AND_REJECTED — every line is either fulfilled or rejected, with at least one of each, and none still pending.
- CANCELLED — withdrawn by the requesting system before any line was acted on; no charge, no stock change.
A line becomes FULFILLED the moment a department user bills or issues it through the normal Add Services / Direct Issue pages — the BHT is charged (and, for stock items, department stock deducted from the earliest-expiry non-expired batch at the batch's retail sale rate) at that point, not before. A line becomes REJECTED when a department user rejects the request's remaining lines with a reason. Fulfillment and rejection happen per line, so a single request commonly ends up PARTIALLY_FULFILLED for a while before becoming fully resolved.
| Code | Meaning |
|---|---|
| 400 | Validation error — unknown/retired item, quantity ≤ 0, invalid/discharged/settled BHT, unknown department, malformed JSON |
| 401 | Missing or invalid Finance API key |
| 404 | Unknown request id |
| 409 | Cancelling a request that already has a fulfilled or rejected line, or was already cancelled |
| 500 | Unexpected server error |
Error responses carry a human-readable message explaining what to fix.
Before integrating, the hospital must configure the requestable items:
- Service and investigation items — created as inward services or investigations with fees and a category configured, so department staff can bill them via Add Services & Investigations.
- Stock items — created as stock-tracked items and stocked into each target department through the normal GRN flow. Processing an inventory line deducts that department's stock and charges the batch retail sale rate.
- Privileges — department users who will process/reject lines need the Inward Service/Item Request Approval / Rejection privileges.
- API key — issued to the integrating system via Admin → API Key Management.
The external system needs the HMIS item ids and department ids to build requests; the hospital administrator supplies these after creating the master data.
- Inward Service and Item Requests (Approval Queue) — the in-app approval workflow for department staff
- Inward Online Payment API — companion API for online inpatient payments