Inventory
Supply Request
A SupplyRequest is a single line item: a quantity of one catalogue item that someone wants moved. Requests never stand alone — each belongs to a RequestOrder that groups them and describes the movement into a destination facility location,…
3.1 · versioned documentation · 6 min read
A SupplyRequest is a single line item: a quantity of one catalogue item (ProductKnowledge) that someone wants moved. Requests never stand alone — each belongs to a RequestOrder that groups them and describes the movement into a destination facility location, optionally from a supplier organization and/or an origin location. You create requests when an order needs stock; you read them back as part of the order they hang off.
The Django model is only storage. status, priority, intent, reason, category, and supplied_item_condition are plain CharFields with no DB-level constraint, so the database will hold any string. The allowed values, validation, and request/response shapes live in the Pydantic resource specs under care/emr/resources/inventory/supply_request/, covered below.
Source:
- Model:
care/emr/models/supply_request.py - Spec:
care/emr/resources/inventory/supply_request/spec.py - Spec:
care/emr/resources/inventory/supply_request/request_order.py
Models
| Model | Purpose |
|---|---|
SupplyRequest |
A request for a quantity of a catalogue item (product knowledge), grouped under an order |
RequestOrder |
An order that groups supply requests for movement of items into a destination facility location |
Both extend EMRBaseModel, the shared MANSOQ EMR base providing external_id, audit fields (created_date/modified_date/created_by/updated_by), soft-delete via deleted, and history/meta JSON.
SupplyRequest fields
| Field | Type | Notes |
|---|---|---|
status |
CharField(255) |
Lifecycle status, spec-bound to SupplyRequestStatusOptions (see below). Required on write. |
quantity |
DecimalField |
max_digits=20, decimal_places=6, nullable in DB. The write spec accepts a Decimal capped to decimal_places=0 (whole numbers); the read spec returns it as an int. |
supplied_item_condition |
CharField(255) |
Model-only — no current spec reads or writes it, so it's unreachable through the API. |
item |
FK → ProductKnowledge |
CASCADE. The catalogue item being requested. Required on create, resolved server-side from an external_id. Cannot be changed afterwards. |
order |
FK → RequestOrder |
CASCADE, nullable in DB but required by the spec on both create and update. Resolved server-side from an external_id. |
SupplyRequestStatusOptions values
Defined in spec.py and bound to SupplyRequest.status.
| Value |
|---|
draft |
active |
suspended |
cancelled |
processed |
completed |
entered_in_error |
Related models
RequestOrder
The order is the unit you actually work with. It collects one or more SupplyRequest rows and carries the routing: a required destination facility location, plus an optional supplier organization and origin location.
supplier → FK Organization (nullable, CASCADE)
origin → FK FacilityLocation (nullable, CASCADE, related_name="origin_request_orders")
destination → FK FacilityLocation (CASCADE, related_name="destination_request_orders")
| Field | Type | Notes |
|---|---|---|
name |
CharField(255) |
Required. |
status |
CharField(255) |
Spec-bound to SupplyRequestOrderStatusOptions. |
note |
TextField |
Optional (str | None). |
tags |
ArrayField[int] |
Default list; tag IDs, not a relational join. Expanded to tag objects on read via SingleFacilityTagManager. |
priority |
CharField(255) |
Spec-bound to SupplyRequestPriorityOptions. |
intent |
CharField(255) |
Spec-bound to SupplyRequestIntentOptions. |
reason |
CharField(255) |
Spec-bound to SupplyRequestReason. |
category |
CharField(255) |
Spec-bound to SupplyRequestCategoryOptions. |
supplier |
FK → Organization |
Nullable CASCADE. On write, must be an organization with org_type == "product_supplier" — the server rejects anything else. |
origin |
FK → FacilityLocation |
Nullable CASCADE, related_name="origin_request_orders". The sending location. |
destination |
FK → FacilityLocation |
CASCADE, related_name="destination_request_orders". The receiving location. Required. |
origin and destination both point at FacilityLocation but carry distinct related_names, so one location can list the orders it sends (origin_request_orders) separately from the orders it receives (destination_request_orders).
RequestOrder enum values
From request_order.py. Each binds to the matching RequestOrder CharField.
SupplyRequestOrderStatusOptions (→ status)
| Value |
|---|
draft |
pending |
in_progress |
completed |
abandoned |
entered_in_error |
SUPPLY_REQUEST_ORDER_COMPLETED_STATUSES = [abandoned, entered_in_error, completed] marks the terminal/closed statuses.
SupplyRequestIntentOptions (→ intent)
| Value |
|---|
proposal |
plan |
directive |
order |
original_order |
reflex_order |
filler_order |
instance_order |
SupplyRequestCategoryOptions (→ category)
| Value |
|---|
central |
nonstock |
SupplyRequestPriorityOptions (→ priority)
| Value |
|---|
routine |
urgent |
asap |
stat |
SupplyRequestReason (→ reason)
| Value |
|---|
patient_care |
ward_stock |
Resource specs (API schema)
Every spec extends EMRResource (serialize / de_serialize, with perform_extra_serialization / perform_extra_deserialization hooks). Write specs resolve foreign keys from external_id values in perform_extra_deserialization; read specs expand related objects in perform_extra_serialization.
Supply request specs (spec.py)
| Spec class | Role | Fields | Notes |
|---|---|---|---|
BaseSupplyRequestSpec |
shared | id, status, quantity |
__model__ = SupplyRequest, __exclude__ = ["item"]. quantity: Decimal(max_digits=20, decimal_places=0). status: SupplyRequestStatusOptions. |
SupplyRequestWriteSpec |
write · create | base + item: UUID4, order: UUID4 |
Resolves item → ProductKnowledge and order → RequestOrder by external_id; 404 if either is missing. |
SupplyRequestUpdateSpec |
write · update | base + order: UUID4 |
Resolves order → RequestOrder by external_id. Omits item — the catalogue item is fixed once created. |
SupplyRequestReadSpec |
read · detail/list | base + quantity: int, item: dict, order: dict |
id = external_id. item expanded via ProductKnowledgeReadSpec; order via SupplyRequestOrderReadSpec. |
Request order specs (request_order.py)
| Spec class | Role | Fields | Notes |
|---|---|---|---|
BaseSupplyRequestOrderSpec |
shared | id, status, name, note, intent, category, priority, reason |
__model__ = RequestOrder. Coded fields bound to their enums; note optional. |
SupplyRequestOrderWriteSpec |
write · create/update | base + supplier: UUID4 | None, origin: UUID4 | None, destination: UUID4 |
Resolves supplier/origin/destination by external_id. Raises ValidationError unless supplier.org_type == "product_supplier". |
SupplyRequestOrderReadSpec |
read · detail/list | base + supplier, origin: dict | None, destination: dict, tags: list[dict], created_date, modified_date, created_by, updated_by |
id = external_id. supplier expanded via OrganizationReadSpec; origin/destination via FacilityLocationListSpec; tags via SingleFacilityTagManager; audit users via serialize_audit_users. |
Validation and server-maintained behaviour
- FK resolution. Every foreign key on write comes in as an
external_idUUID and is resolved server-side withget_object_or_404:item,order,supplier,origin,destination. - Supplier type guard.
SupplyRequestOrderWriteSpecrejects anysupplierwhoseorg_typeis notproduct_supplier. idhandling. Read specs setidtoexternal_id;de_serializenever writesidorexternal_idback to the row.quantity. Write accepts aDecimalpinned todecimal_places=0(whole numbers) even though the DB column allowsdecimal_places=6; read returns anint.itemimmutability. Create takesitem;SupplyRequestUpdateSpecdrops it, so the requested catalogue item can't change after creation.
Methods and save behaviour
- Neither model overrides
save(); standardEMRBaseModelaudit and soft-delete behaviour applies. - Status is free-text at the DB layer — the lifecycle is enforced only by the spec enums at the API boundary. Neither model tracks
status_history. - Deleting a
RequestOrdercascades to itsSupplyRequestrows (theorderFK isCASCADE); deleting a referencedProductKnowledgecascades to the request.
API integration notes
- Payload field names match the spec fields above. Foreign keys go out as
external_idUUIDs on write and come back as expanded objects on read. - Send
status,priority,intent,reason, andcategoryas the exact strings listed above — they're validated against the spec enums. supplied_item_conditionlives on the model but no current spec surfaces it.quantitytravels as a whole number through the specs; the DB column keeps six decimal places regardless.tagsonRequestOrderis an integer array of tag IDs, rendered to tag objects on read by the facility tag manager.external_id(fromEMRBaseModel) is the stable public identifier in API URLs — never the internal primary key.
Related
- Reference: Product Knowledge
- Reference: Supply Delivery
- Reference: Inventory Item
- Reference: Location
- Reference: Organization
- Reference: EMR base model
- Source: supply_request.py on GitHub
- Spec: supply_request/spec.py on GitHub
- Spec: supply_request/request_order.py on GitHub
Source evidence
References are pinned to the private MANSOQ source repository. Repository access is required to open these links.