505 lines
12 KiB
Markdown
505 lines
12 KiB
Markdown
# Insurance Approval Integration - Migration Guide
|
||
|
||
## Overview
|
||
|
||
This guide provides step-by-step instructions for applying the insurance approval integration to your hospital management system.
|
||
|
||
---
|
||
|
||
## Prerequisites
|
||
|
||
Before starting the migration:
|
||
|
||
1. ✅ Backup your database
|
||
2. ✅ Ensure all existing migrations are applied
|
||
3. ✅ Review the integration documentation (`INSURANCE_APPROVAL_INTEGRATION.md`)
|
||
4. ✅ Test in a development environment first
|
||
|
||
---
|
||
|
||
## Step 1: Verify Current State
|
||
|
||
### Check Existing Migrations
|
||
|
||
```bash
|
||
# Check migration status
|
||
python manage.py showmigrations
|
||
|
||
# Look for these apps:
|
||
# - insurance_approvals
|
||
# - laboratory
|
||
# - radiology
|
||
# - pharmacy
|
||
# - operating_theatre
|
||
```
|
||
|
||
### Verify Database Backup
|
||
|
||
```bash
|
||
# For SQLite (development)
|
||
cp db.sqlite3 db.sqlite3.backup
|
||
|
||
# For PostgreSQL (production)
|
||
pg_dump -U username -d database_name > backup_$(date +%Y%m%d_%H%M%S).sql
|
||
|
||
# For MySQL (production)
|
||
mysqldump -u username -p database_name > backup_$(date +%Y%m%d_%H%M%S).sql
|
||
```
|
||
|
||
---
|
||
|
||
## Step 2: Create Migrations
|
||
|
||
### Generate Migrations for All Modified Apps
|
||
|
||
```bash
|
||
# Create migrations for all integrated modules
|
||
python manage.py makemigrations laboratory radiology pharmacy operating_theatre
|
||
|
||
# Expected output:
|
||
# Migrations for 'laboratory':
|
||
# laboratory/migrations/0XXX_add_approval_integration.py
|
||
# - Add field approval_requests to laborder
|
||
# Migrations for 'radiology':
|
||
# radiology/migrations/0XXX_add_approval_integration.py
|
||
# - Add field approval_requests to imagingorder
|
||
# Migrations for 'pharmacy':
|
||
# pharmacy/migrations/0XXX_add_approval_integration.py
|
||
# - Add field approval_requests to prescription
|
||
# Migrations for 'operating_theatre':
|
||
# operating_theatre/migrations/0XXX_add_approval_integration.py
|
||
# - Add field approval_requests to surgicalcase
|
||
```
|
||
|
||
---
|
||
|
||
## Step 3: Review Generated Migrations
|
||
|
||
### Check Migration Files
|
||
|
||
Review each generated migration file to ensure it only adds the GenericRelation field:
|
||
|
||
```python
|
||
# Example: laboratory/migrations/0XXX_add_approval_integration.py
|
||
|
||
from django.db import migrations
|
||
import django.contrib.contenttypes.fields
|
||
|
||
class Migration(migrations.Migration):
|
||
dependencies = [
|
||
('laboratory', '0XXX_previous_migration'),
|
||
('contenttypes', '0002_remove_content_type_name'),
|
||
('insurance_approvals', '0001_initial'),
|
||
]
|
||
|
||
operations = [
|
||
# Note: GenericRelation doesn't create database fields
|
||
# This migration may be empty or just update model metadata
|
||
]
|
||
```
|
||
|
||
**Important:** GenericRelation fields don't create actual database columns. The migrations might be empty or only update model metadata.
|
||
|
||
---
|
||
|
||
## Step 4: Apply Migrations
|
||
|
||
### Run Migrations
|
||
|
||
```bash
|
||
# Apply all pending migrations
|
||
python manage.py migrate
|
||
|
||
# Expected output:
|
||
# Running migrations:
|
||
# Applying laboratory.0XXX_add_approval_integration... OK
|
||
# Applying radiology.0XXX_add_approval_integration... OK
|
||
# Applying pharmacy.0XXX_add_approval_integration... OK
|
||
# Applying operating_theatre.0XXX_add_approval_integration... OK
|
||
```
|
||
|
||
### Verify Migration Success
|
||
|
||
```bash
|
||
# Check migration status again
|
||
python manage.py showmigrations
|
||
|
||
# All migrations should show [X] (applied)
|
||
```
|
||
|
||
---
|
||
|
||
## Step 5: Test Integration
|
||
|
||
### Test in Django Shell
|
||
|
||
```python
|
||
python manage.py shell
|
||
|
||
# Test Laboratory Integration
|
||
from laboratory.models import LabOrder
|
||
from insurance_approvals.models import InsuranceApprovalRequest
|
||
|
||
# Get a lab order
|
||
order = LabOrder.objects.first()
|
||
|
||
# Test helper methods
|
||
print(f"Requires approval: {order.requires_approval()}")
|
||
print(f"Has valid approval: {order.has_valid_approval()}")
|
||
print(f"Approval status: {order.approval_status}")
|
||
|
||
# Test creating an approval
|
||
if order.patient.insurance_info.exists():
|
||
approval = InsuranceApprovalRequest.objects.create(
|
||
tenant=order.tenant,
|
||
patient=order.patient,
|
||
insurance_info=order.patient.insurance_info.first(),
|
||
request_type='LABORATORY',
|
||
content_object=order,
|
||
service_description='Test lab order',
|
||
requesting_provider=order.ordering_provider,
|
||
service_start_date=order.created_at.date(),
|
||
status='PENDING_SUBMISSION',
|
||
)
|
||
print(f"Created approval: {approval.approval_number}")
|
||
|
||
# Verify relationship
|
||
print(f"Order approvals: {order.approval_requests.count()}")
|
||
print(f"Approval content object: {approval.content_object}")
|
||
```
|
||
|
||
### Test Each Module
|
||
|
||
Repeat the above test for:
|
||
- ✅ Radiology (ImagingOrder)
|
||
- ✅ Pharmacy (Prescription)
|
||
- ✅ Operating Theatre (SurgicalCase)
|
||
|
||
---
|
||
|
||
## Step 6: Update Application Code
|
||
|
||
### Add Approval Checks to Views
|
||
|
||
#### Example: Laboratory Order Creation
|
||
|
||
```python
|
||
# laboratory/views.py
|
||
|
||
from django.contrib import messages
|
||
from django.shortcuts import redirect
|
||
from insurance_approvals.models import InsuranceApprovalRequest
|
||
|
||
class LabOrderCreateView(LoginRequiredMixin, CreateView):
|
||
model = LabOrder
|
||
form_class = LabOrderForm
|
||
|
||
def form_valid(self, form):
|
||
response = super().form_valid(form)
|
||
order = self.object
|
||
|
||
# Check if approval is required
|
||
if order.requires_approval():
|
||
messages.warning(
|
||
self.request,
|
||
f"Insurance approval required for order {order.order_number}. "
|
||
f"Please submit an approval request."
|
||
)
|
||
# Optionally redirect to approval creation
|
||
# return redirect('insurance_approvals:create', order_id=order.id)
|
||
|
||
return response
|
||
```
|
||
|
||
### Add Approval Status to Templates
|
||
|
||
#### Example: Order List Template
|
||
|
||
```django
|
||
<!-- laboratory/templates/laboratory/order_list.html -->
|
||
|
||
{% 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">
|
||
<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>
|
||
<a href="{% url 'insurance_approvals:create' %}?order_type=LAB&order_id={{ order.id }}"
|
||
class="btn btn-sm btn-primary ms-2">
|
||
Request Approval
|
||
</a>
|
||
{% 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 %}
|
||
</td>
|
||
</tr>
|
||
{% endfor %}
|
||
```
|
||
|
||
---
|
||
|
||
## Step 7: Generate Sample Data (Optional)
|
||
|
||
### Run Data Generation Script
|
||
|
||
```bash
|
||
# Generate sample approval data
|
||
python insurance_approvals_data.py
|
||
|
||
# Expected output:
|
||
# 🏥 Creating Insurance Approval Data
|
||
# 📋 Found X tenants
|
||
# 👥 Found X patients
|
||
#
|
||
# 1️⃣ Creating Approval Templates...
|
||
# Successfully created X approval templates.
|
||
#
|
||
# 2️⃣ Creating Approval Requests...
|
||
# Successfully created X approval requests.
|
||
#
|
||
# 3️⃣ Creating Status History...
|
||
# Successfully created X status history records.
|
||
#
|
||
# 4️⃣ Creating Communication Logs...
|
||
# Successfully created X communication logs.
|
||
#
|
||
# 🎉 Insurance Approval Data Creation Complete!
|
||
```
|
||
|
||
---
|
||
|
||
## Step 8: Configure URLs (If Not Already Done)
|
||
|
||
### Add Insurance Approvals URLs
|
||
|
||
```python
|
||
# hospital_management/urls.py
|
||
|
||
from django.urls import path, include
|
||
|
||
urlpatterns = [
|
||
# ... existing patterns ...
|
||
path('insurance-approvals/', include('insurance_approvals.urls')),
|
||
]
|
||
```
|
||
|
||
---
|
||
|
||
## Step 9: Test End-to-End Workflow
|
||
|
||
### Complete Workflow Test
|
||
|
||
1. **Create an Order**
|
||
```python
|
||
# Create a lab order for a patient with insurance
|
||
order = LabOrder.objects.create(
|
||
tenant=tenant,
|
||
patient=patient_with_insurance,
|
||
ordering_provider=provider,
|
||
# ... other fields
|
||
)
|
||
```
|
||
|
||
2. **Check Approval Requirement**
|
||
```python
|
||
if order.requires_approval():
|
||
print("✓ Approval requirement detected")
|
||
```
|
||
|
||
3. **Create Approval Request**
|
||
```python
|
||
approval = InsuranceApprovalRequest.objects.create(
|
||
tenant=order.tenant,
|
||
patient=order.patient,
|
||
insurance_info=order.patient.insurance_info.first(),
|
||
request_type='LABORATORY',
|
||
content_object=order,
|
||
# ... other fields
|
||
)
|
||
```
|
||
|
||
4. **Update Approval Status**
|
||
```python
|
||
approval.status = 'APPROVED'
|
||
approval.authorization_number = 'AUTH123456'
|
||
approval.expiration_date = timezone.now().date() + timedelta(days=90)
|
||
approval.save()
|
||
```
|
||
|
||
5. **Verify Approval**
|
||
```python
|
||
assert order.has_valid_approval()
|
||
assert order.approval_status == 'APPROVED'
|
||
print("✓ Approval workflow complete")
|
||
```
|
||
|
||
---
|
||
|
||
## Troubleshooting
|
||
|
||
### Common Issues
|
||
|
||
#### Issue 1: Migration Conflicts
|
||
|
||
**Problem:** Migration conflicts with existing migrations
|
||
|
||
**Solution:**
|
||
```bash
|
||
# Reset migrations (development only!)
|
||
python manage.py migrate laboratory zero
|
||
python manage.py migrate radiology zero
|
||
python manage.py migrate pharmacy zero
|
||
python manage.py migrate operating_theatre zero
|
||
|
||
# Delete migration files
|
||
rm laboratory/migrations/0XXX_*.py
|
||
rm radiology/migrations/0XXX_*.py
|
||
rm pharmacy/migrations/0XXX_*.py
|
||
rm operating_theatre/migrations/0XXX_*.py
|
||
|
||
# Recreate migrations
|
||
python manage.py makemigrations
|
||
python manage.py migrate
|
||
```
|
||
|
||
#### Issue 2: ContentType Not Found
|
||
|
||
**Problem:** `ContentType matching query does not exist`
|
||
|
||
**Solution:**
|
||
```python
|
||
# Run in Django shell
|
||
from django.contrib.contenttypes.models import ContentType
|
||
from laboratory.models import LabOrder
|
||
|
||
# Ensure ContentType exists
|
||
ct = ContentType.objects.get_for_model(LabOrder)
|
||
print(f"ContentType created: {ct}")
|
||
```
|
||
|
||
#### Issue 3: Circular Import
|
||
|
||
**Problem:** Circular import when accessing approval_requests
|
||
|
||
**Solution:**
|
||
```python
|
||
# In helper methods, import inside the function
|
||
def has_valid_approval(self):
|
||
from django.utils import timezone # Import inside method
|
||
return self.approval_requests.filter(
|
||
status__in=['APPROVED', 'PARTIALLY_APPROVED'],
|
||
expiration_date__gte=timezone.now().date()
|
||
).exists()
|
||
```
|
||
|
||
---
|
||
|
||
## Rollback Procedure
|
||
|
||
### If You Need to Rollback
|
||
|
||
```bash
|
||
# 1. Rollback migrations
|
||
python manage.py migrate laboratory 0XXX # Previous migration number
|
||
python manage.py migrate radiology 0XXX
|
||
python manage.py migrate pharmacy 0XXX
|
||
python manage.py migrate operating_theatre 0XXX
|
||
|
||
# 2. Restore database backup
|
||
# For SQLite
|
||
cp db.sqlite3.backup db.sqlite3
|
||
|
||
# For PostgreSQL
|
||
psql -U username -d database_name < backup_file.sql
|
||
|
||
# For MySQL
|
||
mysql -u username -p database_name < backup_file.sql
|
||
|
||
# 3. Remove migration files
|
||
rm laboratory/migrations/0XXX_add_approval_integration.py
|
||
rm radiology/migrations/0XXX_add_approval_integration.py
|
||
rm pharmacy/migrations/0XXX_add_approval_integration.py
|
||
rm operating_theatre/migrations/0XXX_add_approval_integration.py
|
||
```
|
||
|
||
---
|
||
|
||
## Post-Migration Checklist
|
||
|
||
- [ ] All migrations applied successfully
|
||
- [ ] Helper methods work correctly
|
||
- [ ] Approval requests can be created
|
||
- [ ] Approval status displays correctly
|
||
- [ ] No errors in application logs
|
||
- [ ] Templates updated with approval status
|
||
- [ ] Views updated with approval checks
|
||
- [ ] Sample data generated (if needed)
|
||
- [ ] End-to-end workflow tested
|
||
- [ ] Documentation reviewed
|
||
- [ ] Team trained on new features
|
||
|
||
---
|
||
|
||
## Performance Considerations
|
||
|
||
### Database Indexes
|
||
|
||
The integration uses GenericForeignKey which queries ContentType. Ensure these indexes exist:
|
||
|
||
```sql
|
||
-- These should already exist from insurance_approvals migrations
|
||
CREATE INDEX idx_approval_content_type ON insurance_approvals_insuranceapprovalrequest(content_type_id);
|
||
CREATE INDEX idx_approval_object_id ON insurance_approvals_insuranceapprovalrequest(object_id);
|
||
CREATE INDEX idx_approval_status ON insurance_approvals_insuranceapprovalrequest(status);
|
||
CREATE INDEX idx_approval_expiration ON insurance_approvals_insuranceapprovalrequest(expiration_date);
|
||
```
|
||
|
||
### Query Optimization
|
||
|
||
```python
|
||
# Use select_related for better performance
|
||
orders = LabOrder.objects.select_related(
|
||
'patient',
|
||
'patient__insurance_info'
|
||
).prefetch_related(
|
||
'approval_requests'
|
||
)
|
||
|
||
# Check approval status efficiently
|
||
for order in orders:
|
||
if order.requires_approval():
|
||
# Process...
|
||
```
|
||
|
||
---
|
||
|
||
## Support
|
||
|
||
For issues or questions:
|
||
1. Review `INSURANCE_APPROVAL_INTEGRATION.md`
|
||
2. Check this migration guide
|
||
3. Review the insurance_approvals README.md
|
||
4. Check Django logs for errors
|
||
|
||
---
|
||
|
||
## Summary
|
||
|
||
✅ **Migration Complete When:**
|
||
- All migrations applied
|
||
- Helper methods working
|
||
- Approval workflow tested
|
||
- Templates updated
|
||
- No errors in logs
|
||
|
||
🎉 **You're ready to use the insurance approval integration!**
|