hospital-management/INSURANCE_APPROVAL_QUICK_REFERENCE.md
2025-10-03 20:11:25 +03:00

12 KiB

Insurance Approval Integration - Quick Reference Card

🚀 Quick Start

Check if Order Needs Approval

if order.requires_approval():
    # Create approval request

Get Approval Status

status = order.approval_status
# Returns: 'APPROVED', 'APPROVAL_REQUIRED', 'NO_INSURANCE', etc.

Check if Has Valid Approval

if order.has_valid_approval():
    # Proceed with order

Get Active Approval

approval = order.get_active_approval()
if approval:
    print(f"Auth #: {approval.authorization_number}")

📦 Integrated Models

Module Model Request Type
Laboratory LabOrder LABORATORY
Radiology ImagingOrder RADIOLOGY
Pharmacy Prescription PHARMACY
Operating Theatre SurgicalCase SURGERY

🔧 Helper Methods (All Models)

requires_approval() → bool

Returns True if order requires insurance approval

if lab_order.requires_approval():
    # Patient has insurance but no valid approval

has_valid_approval() → bool

Returns True if order has a valid, non-expired approval

if imaging_order.has_valid_approval():
    # Can proceed with imaging

get_active_approval() → InsuranceApprovalRequest | None

Returns the active approval or None

approval = prescription.get_active_approval()
if approval:
    auth_number = approval.authorization_number

approval_status → str (property)

Returns current approval status as string

status = surgical_case.approval_status
# 'APPROVED', 'APPROVAL_REQUIRED', 'NO_INSURANCE', etc.

📝 Creating Approval Requests

Laboratory Order

from insurance_approvals.models import InsuranceApprovalRequest

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,
    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(),
    priority='ROUTINE',
    status='PENDING_SUBMISSION',
)

Radiology Order

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,
    service_description=imaging_order.study_description,
    procedure_codes=imaging_order.modality,
    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(),
    priority='URGENT' if imaging_order.is_stat else 'ROUTINE',
    status='PENDING_SUBMISSION',
)

Pharmacy Prescription

approval = InsuranceApprovalRequest.objects.create(
    tenant=prescription.tenant,
    patient=prescription.patient,
    insurance_info=prescription.patient.insurance_info.first(),
    request_type='PHARMACY',
    content_object=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',
    requested_quantity=prescription.quantity_prescribed,
    status='PENDING_SUBMISSION',
)

Surgical Case

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,
    service_description=surgical_case.primary_procedure,
    procedure_codes=', '.join(surgical_case.procedure_codes),
    diagnosis_codes=', '.join(surgical_case.diagnosis_codes),
    clinical_justification=surgical_case.clinical_notes,
    requesting_provider=surgical_case.primary_surgeon,
    service_start_date=surgical_case.scheduled_start.date(),
    priority='STAT' if surgical_case.is_emergency else 'ROUTINE',
    is_expedited=surgical_case.is_emergency,
    status='PENDING_SUBMISSION',
)

🎨 Template Examples

Display Approval Status Badge

{% if order.approval_status == 'APPROVED' %}
    <span class="badge bg-success">
        <i class="fa fa-check"></i> Approved
    </span>
{% elif order.approval_status == 'APPROVAL_REQUIRED' %}
    <span class="badge bg-warning">
        <i class="fa fa-exclamation-triangle"></i> Approval Required
    </span>
{% elif order.approval_status == 'NO_INSURANCE' %}
    <span class="badge bg-secondary">No Insurance</span>
{% else %}
    <span class="badge bg-info">{{ order.approval_status }}</span>
{% endif %}

Show Approval Details

{% if order.has_valid_approval %}
    {% with approval=order.get_active_approval %}
    <div class="alert alert-success">
        <strong>Authorization:</strong> {{ approval.authorization_number }}<br>
        <strong>Expires:</strong> {{ approval.expiration_date|date:"M d, Y" }}<br>
        <strong>Approved Quantity:</strong> {{ approval.approved_quantity }}
    </div>
    {% endwith %}
{% endif %}

Request Approval Button

{% if order.requires_approval %}
    <a href="{% url 'insurance_approvals:create' %}?order_id={{ order.id }}" 
       class="btn btn-primary">
        <i class="fa fa-file-medical"></i> Request Approval
    </a>
{% endif %}

📊 Approval Status Values

Status Meaning
NO_INSURANCE Patient has no insurance
APPROVAL_REQUIRED Needs approval but none exists
APPROVED Has valid, active approval
PENDING_SUBMISSION Request created but not submitted
SUBMITTED Request submitted to insurance
UNDER_REVIEW Being reviewed by insurance
MORE_INFO_REQUIRED Insurance needs more information
PARTIALLY_APPROVED Partially approved
DENIED Approval denied
EXPIRED Approval has expired
PRIOR_AUTH_REQUIRED Prior authorization required (Pharmacy)
PRIOR_AUTH_APPROVED Prior authorization approved (Pharmacy)
PRIOR_AUTH_EXPIRED Prior authorization expired (Pharmacy)
EMERGENCY_APPROVAL_REQUIRED Emergency approval needed (Surgery)

🔍 Querying Approvals

Get All Approvals for an Order

approvals = order.approval_requests.all()

Get Active Approvals

from django.utils import timezone

active_approvals = order.approval_requests.filter(
    status__in=['APPROVED', 'PARTIALLY_APPROVED'],
    expiration_date__gte=timezone.now().date()
)

Get Latest Approval

latest = order.approval_requests.order_by('-created_at').first()

Get Approvals by Status

pending = order.approval_requests.filter(status='PENDING_SUBMISSION')
approved = order.approval_requests.filter(status='APPROVED')
denied = order.approval_requests.filter(status='DENIED')

🔄 Reverse Queries

Get Order from Approval

approval = InsuranceApprovalRequest.objects.get(pk=1)
order = approval.content_object  # Returns LabOrder, ImagingOrder, etc.

Get All Lab Orders with Approvals

from django.contrib.contenttypes.models import ContentType
from laboratory.models import LabOrder

lab_order_ct = ContentType.objects.get_for_model(LabOrder)
approvals = InsuranceApprovalRequest.objects.filter(
    content_type=lab_order_ct
)

Filter Orders by Approval Status

# Orders needing approval
orders_needing_approval = [
    order for order in LabOrder.objects.all()
    if order.requires_approval()
]

# Orders with valid approval
orders_with_approval = [
    order for order in LabOrder.objects.all()
    if order.has_valid_approval()
]

Performance Tips

orders = LabOrder.objects.select_related(
    'patient',
    'patient__insurance_info'
).prefetch_related(
    'approval_requests'
)

Bulk Check Approval Status

from django.db.models import Prefetch

orders = LabOrder.objects.prefetch_related(
    Prefetch(
        'approval_requests',
        queryset=InsuranceApprovalRequest.objects.filter(
            status__in=['APPROVED', 'PARTIALLY_APPROVED']
        )
    )
)

🎯 Common Patterns

Pattern 1: Create Order with Approval Check

def create_order_with_approval(patient, **order_data):
    order = LabOrder.objects.create(patient=patient, **order_data)
    
    if order.requires_approval():
        return {
            'order': order,
            'needs_approval': True,
            'redirect': f'/insurance-approvals/create/?order_id={order.id}'
        }
    
    return {'order': order, 'needs_approval': False}

Pattern 2: Validate Before Processing

def process_order(order):
    if order.requires_approval() and not order.has_valid_approval():
        raise ValidationError("Order requires valid insurance approval")
    
    # Process order...

Pattern 3: Auto-Create Approval Request

def auto_request_approval(order):
    if not order.requires_approval():
        return None
    
    return InsuranceApprovalRequest.objects.create(
        tenant=order.tenant,
        patient=order.patient,
        insurance_info=order.patient.insurance_info.first(),
        request_type='LABORATORY',
        content_object=order,
        # ... other fields
    )

🚨 Error Handling

Check for Insurance

if not order.patient.insurance_info.exists():
    # No insurance - no approval needed
    pass

Handle Missing Approval

try:
    approval = order.get_active_approval()
    if not approval:
        # Create new approval request
        approval = create_approval_request(order)
except Exception as e:
    logger.error(f"Error getting approval: {e}")

Validate Expiration

from django.utils import timezone

approval = order.get_active_approval()
if approval and approval.expiration_date < timezone.now().date():
    # Approval expired - need new one
    pass

📱 API/DRF Integration

Serializer with Approval Status

from rest_framework import serializers

class LabOrderSerializer(serializers.ModelSerializer):
    approval_status = serializers.CharField(read_only=True)
    requires_approval = serializers.SerializerMethodField()
    active_approval = serializers.SerializerMethodField()
    
    def get_requires_approval(self, obj):
        return obj.requires_approval()
    
    def get_active_approval(self, obj):
        approval = obj.get_active_approval()
        return {
            'id': approval.id,
            'authorization_number': approval.authorization_number,
            'expiration_date': approval.expiration_date
        } if approval else None

  • Full Integration Guide: INSURANCE_APPROVAL_INTEGRATION.md
  • Migration Guide: INSURANCE_APPROVAL_MIGRATION_GUIDE.md
  • Module README: insurance_approvals/README.md

💡 Tips

  1. Always check requires_approval() before processing orders
  2. Use has_valid_approval() to verify approval is still valid
  3. Prefetch approval_requests for better performance
  4. Handle emergency cases differently (Surgery module)
  5. Check formulary status for medications (Pharmacy module)
  6. Use approval templates for consistency
  7. Track all status changes with ApprovalStatusHistory
  8. Log communications with insurance companies

🎉 Quick Checklist

  • Order created
  • Check if approval required
  • Create approval request if needed
  • Submit to insurance
  • Track status changes
  • Update when approved
  • Verify before processing
  • Handle expiration

Last Updated: 2025-01-03 Version: 1.0