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

461 lines
12 KiB
Markdown

# Insurance Approval Integration - Quick Reference Card
## 🚀 Quick Start
### Check if Order Needs Approval
```python
if order.requires_approval():
# Create approval request
```
### Get Approval Status
```python
status = order.approval_status
# Returns: 'APPROVED', 'APPROVAL_REQUIRED', 'NO_INSURANCE', etc.
```
### Check if Has Valid Approval
```python
if order.has_valid_approval():
# Proceed with order
```
### Get Active Approval
```python
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
```python
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
```python
if imaging_order.has_valid_approval():
# Can proceed with imaging
```
### `get_active_approval()` → InsuranceApprovalRequest | None
Returns the active approval or None
```python
approval = prescription.get_active_approval()
if approval:
auth_number = approval.authorization_number
```
### `approval_status` → str (property)
Returns current approval status as string
```python
status = surgical_case.approval_status
# 'APPROVED', 'APPROVAL_REQUIRED', 'NO_INSURANCE', etc.
```
---
## 📝 Creating Approval Requests
### Laboratory Order
```python
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
```python
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
```python
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
```python
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
```django
{% 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
```django
{% 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
```django
{% 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
```python
approvals = order.approval_requests.all()
```
### Get Active Approvals
```python
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
```python
latest = order.approval_requests.order_by('-created_at').first()
```
### Get Approvals by Status
```python
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
```python
approval = InsuranceApprovalRequest.objects.get(pk=1)
order = approval.content_object # Returns LabOrder, ImagingOrder, etc.
```
### Get All Lab Orders with Approvals
```python
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
```python
# 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
### Use select_related and prefetch_related
```python
orders = LabOrder.objects.select_related(
'patient',
'patient__insurance_info'
).prefetch_related(
'approval_requests'
)
```
### Bulk Check Approval Status
```python
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
```python
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
```python
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
```python
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
```python
if not order.patient.insurance_info.exists():
# No insurance - no approval needed
pass
```
### Handle Missing Approval
```python
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
```python
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
```python
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
```
---
## 📚 Related Documentation
- **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