Investigation Consumables (مستهلكات الفحوصات)
Investigation consumables track which reagents are consumed when running a specific laboratory investigation, along with the quantity used per test. This enables cost-per-test calculation and reagent consumption forecasting. Consumables are managed as nested resources under investigations, with support for individual CRUD and batch synchronization.
Entity Attributes
| Field | Type | Required | Description |
|---|---|---|---|
id | integer | auto | Primary key |
investigation_id | FK | auto | Parent investigation (from URL) |
reagent_id | FK | yes | Reagent consumed |
quantity_per_test | decimal(10,4) | yes | Quantity consumed per test run |
is_active | boolean | no | Active status (default: true) |
notes | string | no | Additional notes |
created_at | datetime | auto | Creation timestamp |
updated_at | datetime | auto | Last update timestamp |
ER Diagram
API Endpoints
| Method | Endpoint | Description | Permission |
|---|---|---|---|
GET | /api/lis/investigations/{id}/consumables | List consumables for an investigation | lis.investigations.view |
POST | /api/lis/investigations/{id}/consumables | Add a consumable to an investigation | lis.investigations.update |
PUT | /api/lis/investigations/{id}/consumables/{consumableId} | Update a consumable | lis.investigations.update |
DELETE | /api/lis/investigations/{id}/consumables/{consumableId} | Delete a consumable | lis.investigations.update |
PUT | /api/lis/investigations/{id}/consumables/batch | Batch sync (replace all consumables) | lis.investigations.update |
Request/Response Examples
Add Consumable to Investigation
bash
curl -X POST /api/lis/investigations/1/consumables \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"reagent_id": 5,
"quantity_per_test": "0.2500",
"is_active": true,
"notes": "Standard dilution"
}'dart
final response = await dio.post('/api/lis/investigations/1/consumables', data: {
'reagent_id': 5,
'quantity_per_test': '0.2500',
'is_active': true,
'notes': 'Standard dilution',
});Response 201 Created
json
{
"data": {
"id": 1,
"investigation_id": 1,
"reagent_id": 5,
"reagent": {
"id": 5,
"name": "ALT Reagent",
"name_ar": "كاشف ALT",
"unit": "mL",
"effective_cost": "0.3500"
},
"quantity_per_test": "0.2500",
"line_cost": 0.0875,
"is_active": true,
"notes": "Standard dilution",
"created_at": "2026-03-10T08:00:00.000000Z",
"updated_at": "2026-03-10T08:00:00.000000Z"
}
}Batch Sync Consumables
Replace all consumables for an investigation in a single request.
bash
curl -X PUT /api/lis/investigations/1/consumables/batch \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"consumables": [
{ "reagent_id": 5, "quantity_per_test": "0.2500", "is_active": true },
{ "reagent_id": 8, "quantity_per_test": "0.1000", "is_active": true }
]
}'dart
final response = await dio.put('/api/lis/investigations/1/consumables/batch', data: {
'consumables': [
{'reagent_id': 5, 'quantity_per_test': '0.2500', 'is_active': true},
{'reagent_id': 8, 'quantity_per_test': '0.1000', 'is_active': true},
],
});Response 200 OK
json
{
"data": [
{
"id": 10,
"investigation_id": 1,
"reagent_id": 5,
"reagent": { "id": 5, "name": "ALT Reagent", "name_ar": "كاشف ALT", "unit": "mL", "effective_cost": "0.3500" },
"quantity_per_test": "0.2500",
"line_cost": 0.0875,
"is_active": true,
"notes": null,
"created_at": "2026-03-10T09:00:00.000000Z",
"updated_at": "2026-03-10T09:00:00.000000Z"
},
{
"id": 11,
"investigation_id": 1,
"reagent_id": 8,
"reagent": { "id": 8, "name": "Buffer Solution", "name_ar": "محلول منظم", "unit": "mL", "effective_cost": "0.1200" },
"quantity_per_test": "0.1000",
"line_cost": 0.012,
"is_active": true,
"notes": null,
"created_at": "2026-03-10T09:00:00.000000Z",
"updated_at": "2026-03-10T09:00:00.000000Z"
}
]
}Business Rules
- Nested resource -- consumables are always accessed through their parent investigation URL. The investigation must belong to the authenticated user's company.
- Cost recalculation -- every create, update, delete, and batch sync operation triggers an automatic cost recalculation on the parent investigation via
LisCostCalculatorService. - Line cost -- the response includes a computed
line_costfield:quantity_per_test * reagent.effective_cost. - Batch sync is destructive -- the batch endpoint deletes all existing consumables for the investigation and recreates them from the provided array.
- Reagent relation -- each consumable references a
LabReagentrecord. The reagent details (name, unit, cost) are included in the response. - Write permission -- all mutating operations (create, update, delete, batch sync) require the
lis.investigations.updatepermission rather than a separate consumable permission.