Skip to content

Insurance Billing (فوترة التأمين)

The insurance billing system provides end-to-end insurance claim management: applying insurance to lab requests, auto-calculating patient/insurance shares, generating split invoices, and monthly aggregation for batch settlement with insurance companies.

Insurance Billing Workflow

Coverage Types

Percentage Coverage

Insurance pays a percentage of the test price. Patient pays the remainder.

FieldExampleDescription
coverage_typepercentageType indicator
default_coverage_value80Insurance covers 80%
Test price: 100Insurance: 80, Patient: 20Calculated split

Fixed Copay

Patient pays a fixed amount per test. Insurance covers the rest.

FieldExampleDescription
coverage_typefixed_copayType indicator
default_coverage_value15Patient pays 15 per test
Test price: 100Insurance: 85, Patient: 15Calculated split

Price Resolution Priority

When calculating insurance prices, the system follows this priority chain:

  1. Contract Investigation -- Explicit approved_price, patient_share, insurance_share on lab_insurance_contract_investigations
  2. Contract Price List -- Price from the contract's linked price_list_id
  3. Investigation Default -- The investigation's base price field

Max Coverage Cap

If max_coverage_per_visit is set, the total insurance amount is capped. When the cap is reached, excess is redistributed proportionally to patient shares.

Example: 2 tests at 100 and 200, 80% coverage, cap at 100:

  • Without cap: insurance = 240, patient = 60
  • With cap: insurance = 100, patient = 200 (proportionally redistributed)

Insurance on Requests

Request Insurance Fields

FieldTypeDescription
insurance_contract_idFKApplied insurance contract
insurance_approval_numberstringPrior authorization number
insurance_statusenumpending, approved, rejected, claimed
coverage_percentagedecimalResolved coverage percentage
patient_share_totaldecimalTotal patient share
insurance_share_totaldecimalTotal insurance share

Per-Investigation Insurance Fields

FieldTypeDescription
insurance_pricedecimalResolved price for this investigation
patient_sharedecimalPatient pays this amount
insurance_sharedecimalInsurance pays this amount

API Endpoints

Insurance on Requests

MethodEndpointDescriptionPermission
POST/api/lis/requests/{id}/apply-insuranceApply insurance to a requestlis.requests.update
POST/api/lis/requests/{id}/remove-insuranceRemove insurance from a requestlis.requests.update
POST/api/lis/requests/{id}/recalculate-insuranceRecalculate insurance shareslis.requests.update

Invoice Generation

MethodEndpointDescriptionPermission
POST/api/lis/invoices/generateGenerate invoice(s) from requestlis.insurance-invoices.generate

Monthly Insurance Invoices

MethodEndpointDescriptionPermission
GET/api/lis/insurance-invoices/pending-aggregationList pending aggregationslis.insurance-invoices.monthly.view
GET/api/lis/insurance-invoices/monthlyList monthly invoiceslis.insurance-invoices.monthly.view
GET/api/lis/insurance-invoices/monthly/{id}Show monthly invoicelis.insurance-invoices.monthly.view
POST/api/lis/insurance-invoices/generate-monthlyGenerate monthly aggregatelis.insurance-invoices.monthly.generate

Request / Response Examples

Apply Insurance to a Request

bash
curl -X POST /api/lis/requests/1/apply-insurance \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "insurance_contract_id": 1,
    "insurance_approval_number": "AUTH-2026-001"
  }'
dart
final response = await dio.post('/api/lis/requests/1/apply-insurance', data: {
  'insurance_contract_id': 1,
  'insurance_approval_number': 'AUTH-2026-001',
});

Generate Split Invoices

bash
curl -X POST /api/lis/invoices/generate \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{"request_id": 1}'
dart
final response = await dio.post('/api/lis/invoices/generate', data: {
  'request_id': 1,
});
// Returns: { patient_invoice: {...}, insurance_invoice: {...} }
// Or for non-insured: { invoice: {...} }

Generate Monthly Aggregate

bash
curl -X POST /api/lis/insurance-invoices/generate-monthly \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "insurance_contract_id": 1,
    "month": "2026-03"
  }'
dart
final response = await dio.post('/api/lis/insurance-invoices/generate-monthly', data: {
  'insurance_contract_id': 1,
  'month': '2026-03',
});

Monthly Insurance Invoice Attributes

FieldTypeDescription
idintegerPrimary key
insurance_contract_idFKInsurance contract
partner_idFKBusinessPartner
monthstring(7)Period (YYYY-MM)
aggregate_invoice_idFKGenerated aggregate invoice
claims_countintegerNumber of individual invoices
total_patient_amountdecimalSum of patient shares
total_insurance_amountdecimalSum of insurance shares
total_amountdecimalGrand total
statusenumpending, generated, posted, paid
generated_atdatetimeWhen generated
generated_byFKUser who generated

Business Rules

  1. Split invoicing -- Insured requests produce 2 invoices (patient + insurance); non-insured produce 1 standard invoice.
  2. No duplicate generation -- A request can only have invoices generated once. Attempting again returns an error.
  3. Doctor commissions -- Only calculated on standard and patient_invoice types, never on insurance_invoice (prevents double-counting).
  4. Insurance accounting -- Insurance invoices use the contract's insurance_receivable_account_id (DR) and revenue_account_id (CR) for journal entries.
  5. Monthly uniqueness -- Only one monthly aggregate per (company, contract, month) combination.
  6. Aggregation scope -- Only posted insurance invoices are eligible for monthly aggregation.
  7. Related invoices -- Patient and insurance invoices are cross-linked via related_invoice_id.

Moon ERP API Documentation