Skip to content

Investigation Packages (باقات الفحوصات)

Commercial test packages are discounted bundles of investigations sold at a reduced price. They are a pricing concept — distinct from panels (which are atomic test units defined via is_panel on investigations).

Entity Attributes

FieldTypeDescription
idbigintPrimary key
company_idFKCompany
namestringEnglish name
name_arstringArabic name
codestring(50)Auto-generated or manual (unique per company)
descriptiontextOptional description
total_pricedecimal(12,3)Sum of member investigation prices (auto-calculated)
package_pricedecimal(12,3)Discounted bundle price
savings_percentagedecimal(5,2)Auto-calculated: (total_price - package_price) / total_price * 100
is_activebooleanWhether package is available for selection
valid_fromdateStart of validity period (nullable)
valid_todateEnd of validity period (nullable)
created_byFKCreator user
updated_byFKLast updater

ER Diagram

API Endpoints

MethodPathDescriptionPermission
GET/api/lis/packagesList packageslis.packages.view
POST/api/lis/packagesCreate packagelis.packages.create
GET/api/lis/packages/{id}Show packagelis.packages.view
PUT/api/lis/packages/{id}Update packagelis.packages.update
DELETE/api/lis/packages/{id}Delete packagelis.packages.delete

Query Parameters (index)

ParameterTypeDescription
searchstringFilter by name, name_ar, or code
is_activebooleanFilter by active status

Create / Update Request

bash
curl -X POST /api/lis/packages \
  -H "Authorization: Bearer {token}" \
  -d '{
    "name": "Comprehensive Panel",
    "name_ar": "باقة شاملة",
    "package_price": 80.000,
    "investigations": [
      {"investigation_id": 1, "sort_order": 0},
      {"investigation_id": 2, "sort_order": 1},
      {"investigation_id": 3, "sort_order": 2}
    ]
  }'
dart
final response = await dio.post('/api/lis/packages', data: {
  'name': 'Comprehensive Panel',
  'name_ar': 'باقة شاملة',
  'package_price': 80.0,
  'investigations': [
    {'investigation_id': 1, 'sort_order': 0},
    {'investigation_id': 2, 'sort_order': 1},
    {'investigation_id': 3, 'sort_order': 2},
  ],
});

Using Packages in Request Creation

When creating a lab request, you can include packages[] alongside investigations[]:

bash
curl -X POST /api/lis/requests \
  -H "Authorization: Bearer {token}" \
  -d '{
    "patient_id": 1,
    "investigations": [
      {"investigation_id": 10, "price": 15.000}
    ],
    "packages": [
      {"package_id": 1}
    ]
  }'
dart
final response = await dio.post('/api/lis/requests', data: {
  'patient_id': 1,
  'investigations': [
    {'investigation_id': 10, 'price': 15.0},
  ],
  'packages': [
    {'package_id': 1},
  ],
});

Business Rules

  • Auto-calculation: total_price is computed as the sum of member investigation prices; savings_percentage is derived from the difference.
  • Duplicate prevention: When a package is added to a request, investigations already present (from individual selection or another package) are skipped.
  • Inactive/expired rejection: Only active packages within their validity period are processed; invalid packages are silently skipped.
  • Price snapshot: When a package is selected on a request, package_price and discount_amount are snapshotted to lab_request_packages.
  • Net amount formula: net_amount = total_amount - discount_amount - package_discount
  • Delete guard: Packages used in non-cancelled requests cannot be deleted.
  • Code auto-generation: If code is not provided, it is auto-generated via the PKG sequence.

Moon ERP API Documentation