Skip to content

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

FieldTypeRequiredDescription
idintegerautoPrimary key
investigation_idFKautoParent investigation (from URL)
reagent_idFKyesReagent consumed
quantity_per_testdecimal(10,4)yesQuantity consumed per test run
is_activebooleannoActive status (default: true)
notesstringnoAdditional notes
created_atdatetimeautoCreation timestamp
updated_atdatetimeautoLast update timestamp

ER Diagram

API Endpoints

MethodEndpointDescriptionPermission
GET/api/lis/investigations/{id}/consumablesList consumables for an investigationlis.investigations.view
POST/api/lis/investigations/{id}/consumablesAdd a consumable to an investigationlis.investigations.update
PUT/api/lis/investigations/{id}/consumables/{consumableId}Update a consumablelis.investigations.update
DELETE/api/lis/investigations/{id}/consumables/{consumableId}Delete a consumablelis.investigations.update
PUT/api/lis/investigations/{id}/consumables/batchBatch 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

  1. Nested resource -- consumables are always accessed through their parent investigation URL. The investigation must belong to the authenticated user's company.
  2. Cost recalculation -- every create, update, delete, and batch sync operation triggers an automatic cost recalculation on the parent investigation via LisCostCalculatorService.
  3. Line cost -- the response includes a computed line_cost field: quantity_per_test * reagent.effective_cost.
  4. Batch sync is destructive -- the batch endpoint deletes all existing consumables for the investigation and recreates them from the provided array.
  5. Reagent relation -- each consumable references a LabReagent record. The reagent details (name, unit, cost) are included in the response.
  6. Write permission -- all mutating operations (create, update, delete, batch sync) require the lis.investigations.update permission rather than a separate consumable permission.

Moon ERP API Documentation