# Insurance Approval Integration Documentation ## Overview The Insurance Approval Request module has been successfully integrated with all relevant clinical order modules in the hospital management system. This document outlines the integration points and usage patterns. --- ## Integrated Modules ### 1. Laboratory Module ✅ **Model:** `LabOrder` **File:** `laboratory/models.py` #### Integration Details: - Added `GenericRelation` to link lab orders with approval requests - Added helper methods for approval status checking - Supports multi-tenant approval tracking #### Helper Methods Added: ```python # Check if order has valid approval lab_order.has_valid_approval() # Returns True/False # Get active approval lab_order.get_active_approval() # Returns InsuranceApprovalRequest or None # Check if approval is required lab_order.requires_approval() # Returns True/False # Get approval status for display lab_order.approval_status # Returns status string ``` #### Usage Example: ```python from laboratory.models import LabOrder from insurance_approvals.models import InsuranceApprovalRequest # Create a lab order lab_order = LabOrder.objects.get(order_number='LAB-1-000001') # Check if approval is needed if lab_order.requires_approval(): # Create approval request approval = InsuranceApprovalRequest.objects.create( tenant=lab_order.tenant, patient=lab_order.patient, insurance_info=lab_order.patient.insurance_info.first(), request_type='LABORATORY', content_object=lab_order, # Links to lab order service_description=f"Lab tests: {', '.join([t.test_name for t in lab_order.tests.all()])}", procedure_codes=', '.join([t.cpt_code for t in lab_order.tests.all() if t.cpt_code]), diagnosis_codes=lab_order.diagnosis_code or '', clinical_justification=lab_order.clinical_indication, requesting_provider=lab_order.ordering_provider, service_start_date=lab_order.collection_datetime.date() if lab_order.collection_datetime else timezone.now().date(), priority='ROUTINE', status='PENDING_SUBMISSION', ) # Check approval status if lab_order.has_valid_approval(): print("Order has valid approval - proceed with processing") else: print(f"Approval status: {lab_order.approval_status}") # Get all approval requests for this order approvals = lab_order.approval_requests.all() ``` --- ### 2. Radiology Module ✅ **Model:** `ImagingOrder` **File:** `radiology/models.py` #### Integration Details: - Added `GenericRelation` to link imaging orders with approval requests - Added identical helper methods as laboratory module - Supports all imaging modalities (CT, MRI, X-Ray, etc.) #### Helper Methods Added: ```python # Check if order has valid approval imaging_order.has_valid_approval() # Returns True/False # Get active approval imaging_order.get_active_approval() # Returns InsuranceApprovalRequest or None # Check if approval is required imaging_order.requires_approval() # Returns True/False # Get approval status for display imaging_order.approval_status # Returns status string ``` #### Usage Example: ```python from radiology.models import ImagingOrder from insurance_approvals.models import InsuranceApprovalRequest # Create an imaging order imaging_order = ImagingOrder.objects.get(order_number='IMG-1-000001') # Check if approval is needed if imaging_order.requires_approval(): # Create approval request approval = InsuranceApprovalRequest.objects.create( tenant=imaging_order.tenant, patient=imaging_order.patient, insurance_info=imaging_order.patient.insurance_info.first(), request_type='RADIOLOGY', content_object=imaging_order, # Links to imaging order service_description=imaging_order.study_description, procedure_codes=imaging_order.modality, # Could be enhanced with CPT codes diagnosis_codes=imaging_order.diagnosis_code or '', clinical_justification=imaging_order.clinical_indication, requesting_provider=imaging_order.ordering_provider, service_start_date=imaging_order.requested_datetime.date() if imaging_order.requested_datetime else timezone.now().date(), priority='URGENT' if imaging_order.is_stat else 'ROUTINE', status='PENDING_SUBMISSION', ) # Access approvals active_approval = imaging_order.get_active_approval() if active_approval: print(f"Authorization Number: {active_approval.authorization_number}") print(f"Expires: {active_approval.expiration_date}") ``` --- ## Common Integration Patterns ### Pattern 1: Pre-Order Approval Check ```python def create_order_with_approval_check(patient, order_type, **order_data): """ Create an order and check if insurance approval is required. """ # Create the order if order_type == 'LAB': order = LabOrder.objects.create(patient=patient, **order_data) elif order_type == 'IMAGING': order = ImagingOrder.objects.create(patient=patient, **order_data) # Check if approval is required if order.requires_approval(): # Redirect to approval request creation return { 'order': order, 'requires_approval': True, 'redirect_url': f'/insurance-approvals/create/?order_type={order_type}&order_id={order.id}' } return { 'order': order, 'requires_approval': False } ``` ### Pattern 2: Approval Status Display ```python def get_order_status_with_approval(order): """ Get comprehensive order status including approval information. """ status = { 'order_status': order.status, 'has_insurance': order.patient.insurance_info.exists(), 'requires_approval': order.requires_approval(), 'approval_status': order.approval_status, 'can_proceed': False } if not status['has_insurance']: status['can_proceed'] = True # No insurance, no approval needed elif order.has_valid_approval(): status['can_proceed'] = True status['approval'] = order.get_active_approval() return status ``` ### Pattern 3: Bulk Approval Status Check ```python def get_orders_needing_approval(tenant, order_type='LAB'): """ Get all orders that need insurance approval. """ if order_type == 'LAB': Model = LabOrder elif order_type == 'IMAGING': Model = ImagingOrder orders = Model.objects.filter( tenant=tenant, status__in=['PENDING', 'SCHEDULED'] ) orders_needing_approval = [] for order in orders: if order.requires_approval(): orders_needing_approval.append({ 'order': order, 'patient': order.patient, 'insurance': order.patient.insurance_info.first(), 'approval_status': order.approval_status }) return orders_needing_approval ``` --- ## Approval Request Types The system supports the following request types: 1. **LABORATORY** - Lab tests and panels 2. **RADIOLOGY** - Imaging studies (CT, MRI, X-Ray, etc.) 3. **PHARMACY** - Medications (to be integrated) 4. **PROCEDURE** - Medical procedures (to be integrated) 5. **SURGERY** - Surgical procedures (to be integrated) 6. **THERAPY** - Physical/Occupational therapy 7. **DME** - Durable Medical Equipment 8. **HOME_HEALTH** - Home health services 9. **HOSPICE** - Hospice care 10. **TRANSPORTATION** - Medical transportation 11. **OTHER** - Other services --- ## Approval Workflow States ``` DRAFT → PENDING_SUBMISSION → SUBMITTED → UNDER_REVIEW ↓ MORE_INFO_REQUIRED (can loop back to SUBMITTED) ↓ APPROVED / PARTIALLY_APPROVED / DENIED ↓ APPEAL_SUBMITTED → APPEAL_APPROVED / APPEAL_DENIED ↓ EXPIRED (if expiration_date passes) ``` --- ## Database Relationships ### GenericForeignKey Pattern ```python # In InsuranceApprovalRequest model content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) object_id = models.PositiveIntegerField() content_object = GenericForeignKey('content_type', 'object_id') # In LabOrder/ImagingOrder models approval_requests = GenericRelation( 'insurance_approvals.InsuranceApprovalRequest', content_type_field='content_type', object_id_field='object_id', related_query_name='lab_order' # or 'imaging_order' ) ``` ### Querying Across Relationships ```python # Get all lab orders with approvals from django.contrib.contenttypes.models import ContentType from laboratory.models import LabOrder from insurance_approvals.models import InsuranceApprovalRequest lab_order_ct = ContentType.objects.get_for_model(LabOrder) approvals_for_lab_orders = InsuranceApprovalRequest.objects.filter( content_type=lab_order_ct ) # Get specific lab order's approvals lab_order = LabOrder.objects.get(pk=1) approvals = lab_order.approval_requests.all() # Reverse query - get order from approval approval = InsuranceApprovalRequest.objects.get(pk=1) order = approval.content_object # Returns LabOrder or ImagingOrder instance ``` --- ## Template Integration Examples ### Display Approval Status in Order List ```django {% for order in orders %} {{ order.order_number }} {{ order.patient.get_full_name }} {% if order.approval_status == 'APPROVED' %} Approved {% elif order.approval_status == 'APPROVAL_REQUIRED' %} Approval Required Request Approval {% elif order.approval_status == 'NO_INSURANCE' %} No Insurance {% else %} {{ order.get_approval_status_display }} {% endif %} {% endfor %} ``` ### Display Approval Details in Order Detail ```django {% if order.has_valid_approval %}
Insurance Approval Active
{% with approval=order.get_active_approval %}

Authorization Number: {{ approval.authorization_number }}

Expires: {{ approval.expiration_date|date:"M d, Y" }}

Approved Quantity: {{ approval.approved_quantity }}

{% endwith %}
{% elif order.requires_approval %}
Insurance Approval Required

This order requires insurance approval before processing.

Request Approval
{% endif %} ``` --- ## API Integration (DRF) ### Serializer Example ```python from rest_framework import serializers from laboratory.models import LabOrder from insurance_approvals.models import InsuranceApprovalRequest class LabOrderSerializer(serializers.ModelSerializer): approval_status = serializers.CharField(read_only=True) has_valid_approval = serializers.BooleanField(read_only=True) requires_approval = serializers.SerializerMethodField() active_approval = serializers.SerializerMethodField() class Meta: model = LabOrder fields = '__all__' def get_requires_approval(self, obj): return obj.requires_approval() def get_active_approval(self, obj): approval = obj.get_active_approval() if approval: return { 'id': approval.id, 'approval_number': approval.approval_number, 'authorization_number': approval.authorization_number, 'status': approval.status, 'expiration_date': approval.expiration_date } return None ``` --- ## Future Integration Points ### Pharmacy Module (Pending) - **Model:** `PharmacyOrder` or `Prescription` - **Request Type:** `PHARMACY` - Same integration pattern as Lab and Radiology ### Operating Theatre Module (Pending) - **Model:** `SurgerySchedule` or `OperativeCase` - **Request Type:** `SURGERY` or `PROCEDURE` - Same integration pattern ### Other Potential Integrations: - Home Health Orders - DME Orders - Physical Therapy Orders - Hospice Care Orders --- ## Migration Notes **IMPORTANT:** Migrations are NOT included in this integration. The user will handle migrations separately. ### To apply changes: 1. Create migrations: `python manage.py makemigrations laboratory radiology` 2. Review migrations carefully 3. Apply migrations: `python manage.py migrate` --- ## Testing Recommendations ### Unit Tests ```python from django.test import TestCase from laboratory.models import LabOrder from insurance_approvals.models import InsuranceApprovalRequest class LabOrderApprovalIntegrationTest(TestCase): def test_order_requires_approval_with_insurance(self): # Create patient with insurance patient = self.create_patient_with_insurance() order = LabOrder.objects.create(patient=patient, ...) self.assertTrue(order.requires_approval()) def test_order_has_valid_approval(self): order = self.create_lab_order() approval = InsuranceApprovalRequest.objects.create( content_object=order, status='APPROVED', expiration_date=timezone.now().date() + timedelta(days=30), ... ) self.assertTrue(order.has_valid_approval()) self.assertEqual(order.get_active_approval(), approval) ``` --- ### 3. Pharmacy Module ✅ **Model:** `Prescription` **File:** `pharmacy/models.py` #### Integration Details: - Added `GenericRelation` to link prescriptions with approval requests - Added helper methods for approval status checking - Enhanced with prior authorization support - Checks medication formulary status for approval requirements #### Helper Methods Added: ```python # Check if prescription has valid approval prescription.has_valid_approval() # Returns True/False # Get active approval prescription.get_active_approval() # Returns InsuranceApprovalRequest or None # Check if approval is required prescription.requires_approval() # Returns True/False # Get approval status for display prescription.approval_status # Returns status string ``` #### Special Features: - **Prior Authorization Integration**: Checks both approval requests and prior authorization fields - **Formulary Status**: Automatically requires approval for RESTRICTED or PRIOR_AUTH medications - **Enhanced Status**: Returns specific statuses like 'PRIOR_AUTH_REQUIRED', 'PRIOR_AUTH_EXPIRED', etc. #### Usage Example: ```python from pharmacy.models import Prescription from insurance_approvals.models import InsuranceApprovalRequest # Create a prescription prescription = Prescription.objects.get(prescription_number='RX-1-000001') # Check if approval is needed (considers formulary status) if prescription.requires_approval(): # Create approval request approval = InsuranceApprovalRequest.objects.create( tenant=prescription.tenant, patient=prescription.patient, insurance_info=prescription.patient.insurance_info.first(), request_type='PHARMACY', content_object=prescription, # Links to prescription service_description=f"{prescription.medication.display_name} - {prescription.quantity_prescribed} {prescription.quantity_unit}", procedure_codes=prescription.medication.ndc_number or '', diagnosis_codes=prescription.diagnosis_code or '', clinical_justification=prescription.indication or 'As prescribed', requesting_provider=prescription.prescriber, service_start_date=prescription.date_written, priority='URGENT' if prescription.medication.is_controlled_substance else 'ROUTINE', status='PENDING_SUBMISSION', requested_quantity=prescription.quantity_prescribed, ) # Check prior authorization if prescription.prior_authorization_required: if not prescription.prior_authorization_number: print("Prior authorization required but not obtained") ``` --- ### 4. Operating Theatre Module ✅ **Model:** `SurgicalCase` **File:** `operating_theatre/models.py` #### Integration Details: - Added `GenericRelation` to link surgical cases with approval requests - Added helper methods for approval status checking - Enhanced with emergency case handling - Supports elective and emergency approval workflows #### Helper Methods Added: ```python # Check if surgical case has valid approval surgical_case.has_valid_approval() # Returns True/False # Get active approval surgical_case.get_active_approval() # Returns InsuranceApprovalRequest or None # Check if approval is required surgical_case.requires_approval() # Returns True/False # Get approval status for display surgical_case.approval_status # Returns status string ``` #### Special Features: - **Emergency Case Handling**: Different approval requirements for emergency vs elective cases - **Enhanced Status**: Returns 'EMERGENCY_APPROVAL_REQUIRED' for emergency cases - **Procedure Code Support**: Integrates with procedure_codes JSON field #### Usage Example: ```python from operating_theatre.models import SurgicalCase from insurance_approvals.models import InsuranceApprovalRequest # Create a surgical case surgical_case = SurgicalCase.objects.get(case_number='SURG-20250103-0001') # Check if approval is needed if surgical_case.requires_approval(): # Determine priority based on case type if surgical_case.is_emergency: priority = 'STAT' is_expedited = True else: priority = 'ROUTINE' is_expedited = False # Create approval request approval = InsuranceApprovalRequest.objects.create( tenant=surgical_case.tenant, patient=surgical_case.patient, insurance_info=surgical_case.patient.insurance_info.first(), request_type='SURGERY', content_object=surgical_case, # Links to surgical case service_description=surgical_case.primary_procedure, procedure_codes=', '.join(surgical_case.procedure_codes) if surgical_case.procedure_codes else '', diagnosis_codes=', '.join(surgical_case.diagnosis_codes) if surgical_case.diagnosis_codes else surgical_case.diagnosis, clinical_justification=surgical_case.clinical_notes or f"Surgical intervention required for {surgical_case.diagnosis}", requesting_provider=surgical_case.primary_surgeon, service_start_date=surgical_case.scheduled_start.date(), priority=priority, is_expedited=is_expedited, status='PENDING_SUBMISSION', ) ``` --- ## Summary ✅ **Laboratory Module** - Fully integrated ✅ **Radiology Module** - Fully integrated ✅ **Pharmacy Module** - Fully integrated (with prior auth support) ✅ **Operating Theatre Module** - Fully integrated (with emergency handling) All integrated modules now support: - Automatic approval requirement detection - Approval status tracking - Multi-tenant approval management - Complete audit trail - Flexible workflow states - Module-specific enhancements (prior auth, emergency cases, etc.) The integration is backward compatible and does not affect existing functionality.