hospital-management/tools/markdown/INSURANCE_APPROVAL_INTEGRATION.md
Marwan Alwali 263292f6be update
2025-11-04 00:50:06 +03:00

19 KiB

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:

# 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:

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:

# 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:

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

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

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

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

# 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

# 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

{% for order in orders %}
<tr>
    <td>{{ order.order_number }}</td>
    <td>{{ order.patient.get_full_name }}</td>
    <td>
        {% if order.approval_status == 'APPROVED' %}
            <span class="badge bg-success">Approved</span>
        {% elif order.approval_status == 'APPROVAL_REQUIRED' %}
            <span class="badge bg-warning">Approval Required</span>
            <a href="{% url 'insurance_approvals:create' %}?order_id={{ order.id }}" 
               class="btn btn-sm btn-primary">Request Approval</a>
        {% elif order.approval_status == 'NO_INSURANCE' %}
            <span class="badge bg-secondary">No Insurance</span>
        {% else %}
            <span class="badge bg-info">{{ order.get_approval_status_display }}</span>
        {% endif %}
    </td>
</tr>
{% endfor %}

Display Approval Details in Order Detail

{% if order.has_valid_approval %}
<div class="alert alert-success">
    <h6><i class="fa fa-check-circle"></i> Insurance Approval Active</h6>
    {% with approval=order.get_active_approval %}
    <p><strong>Authorization Number:</strong> {{ approval.authorization_number }}</p>
    <p><strong>Expires:</strong> {{ approval.expiration_date|date:"M d, Y" }}</p>
    <p><strong>Approved Quantity:</strong> {{ approval.approved_quantity }}</p>
    {% endwith %}
</div>
{% elif order.requires_approval %}
<div class="alert alert-warning">
    <h6><i class="fa fa-exclamation-triangle"></i> Insurance Approval Required</h6>
    <p>This order requires insurance approval before processing.</p>
    <a href="{% url 'insurance_approvals:create' %}?order_id={{ order.id }}" 
       class="btn btn-primary">Request Approval</a>
</div>
{% endif %}

API Integration (DRF)

Serializer Example

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

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:

# 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:

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:

# 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:

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.