291 lines
11 KiB
Python
291 lines
11 KiB
Python
"""
|
|
Forms for Insurance Approvals app.
|
|
"""
|
|
|
|
from django import forms
|
|
from django.contrib.contenttypes.models import ContentType
|
|
from .models import (
|
|
InsuranceApprovalRequest,
|
|
ApprovalDocument,
|
|
ApprovalCommunicationLog,
|
|
ApprovalTemplate
|
|
)
|
|
|
|
|
|
class InsuranceApprovalRequestForm(forms.ModelForm):
|
|
"""Form for creating/editing insurance approval requests."""
|
|
|
|
class Meta:
|
|
model = InsuranceApprovalRequest
|
|
fields = [
|
|
'patient',
|
|
'insurance_info',
|
|
'request_type',
|
|
'service_description',
|
|
'procedure_codes',
|
|
'diagnosis_codes',
|
|
'clinical_justification',
|
|
'medical_necessity',
|
|
'alternative_treatments_tried',
|
|
'requested_quantity',
|
|
'requested_visits',
|
|
'requested_units',
|
|
'service_start_date',
|
|
'service_end_date',
|
|
'priority',
|
|
'is_urgent',
|
|
'is_expedited',
|
|
'requires_peer_review',
|
|
'assigned_to',
|
|
'internal_notes',
|
|
]
|
|
widgets = {
|
|
'patient': forms.Select(attrs={'class': 'form-select form-select-sm'}),
|
|
'insurance_info': forms.Select(attrs={'class': 'form-select form-select-sm'}),
|
|
'request_type': forms.Select(attrs={'class': 'form-select form-select-sm'}),
|
|
'priority': forms.Select(attrs={'class': 'form-select form-select-sm'}),
|
|
'assigned_to': forms.Select(attrs={'class': 'form-select form-select-sm'}),
|
|
'procedure_codes': forms.Textarea(attrs={'class': 'form-control form-control-sm'}),
|
|
'diagnosis_codes': forms.Textarea(attrs={'class': 'form-control form-control-sm'}),
|
|
'service_start_date': forms.DateInput(attrs={'type': 'date', 'class': 'form-control form-control-sm'}),
|
|
'service_end_date': forms.DateInput(attrs={'type': 'date', 'class': 'form-control form-control-sm'}),
|
|
'clinical_justification': forms.Textarea(attrs={'rows': 4, 'class': 'form-control form-control-sm'}),
|
|
'medical_necessity': forms.Textarea(attrs={'rows': 3, 'class': 'form-control form-control-sm'}),
|
|
'alternative_treatments_tried': forms.Textarea(attrs={'rows': 3, 'class': 'form-control form-control-sm'}),
|
|
'internal_notes': forms.Textarea(attrs={'rows': 3, 'class': 'form-control form-control-sm'}),
|
|
'service_description': forms.TextInput(attrs={'class': 'form-control form-control-sm'}),
|
|
'requested_quantity': forms.NumberInput(attrs={'class': 'form-control form-control-sm', 'min': '1'}),
|
|
'requested_visits': forms.NumberInput(attrs={'class': 'form-control form-control-sm', 'min': '1'}),
|
|
'requested_units': forms.NumberInput(attrs={'class': 'form-control form-control-sm', 'min': '1'}),
|
|
}
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.tenant = kwargs.pop('tenant', None)
|
|
self.user = kwargs.pop('user', None)
|
|
self.order = kwargs.pop('order', None)
|
|
super().__init__(*args, **kwargs)
|
|
|
|
# Filter choices by tenant if provided
|
|
if self.tenant:
|
|
self.fields['patient'].queryset = self.fields['patient'].queryset.filter(tenant=self.tenant)
|
|
self.fields['assigned_to'].queryset = self.fields['assigned_to'].queryset.filter(tenant=self.tenant)
|
|
|
|
# Pre-populate from order if provided
|
|
if self.order and not self.instance.pk:
|
|
self._populate_from_order()
|
|
|
|
def _populate_from_order(self):
|
|
"""Pre-populate form fields from the related order."""
|
|
if hasattr(self.order, 'patient'):
|
|
self.initial['patient'] = self.order.patient
|
|
|
|
# Set request type based on order type
|
|
content_type = ContentType.objects.get_for_model(self.order)
|
|
if 'lab' in content_type.model.lower():
|
|
self.initial['request_type'] = 'LABORATORY'
|
|
elif 'imaging' in content_type.model.lower() or 'radiology' in content_type.model.lower():
|
|
self.initial['request_type'] = 'RADIOLOGY'
|
|
elif 'prescription' in content_type.model.lower() or 'pharmacy' in content_type.model.lower():
|
|
self.initial['request_type'] = 'PHARMACY'
|
|
|
|
def save(self, commit=True):
|
|
instance = super().save(commit=False)
|
|
|
|
# Set tenant and user if provided
|
|
if self.tenant:
|
|
instance.tenant = self.tenant
|
|
if self.user:
|
|
instance.requesting_provider = self.user
|
|
if not instance.pk:
|
|
instance.created_by = self.user
|
|
|
|
# Set content type and object id from order
|
|
if self.order:
|
|
instance.content_type = ContentType.objects.get_for_model(self.order)
|
|
instance.object_id = self.order.pk
|
|
|
|
if commit:
|
|
instance.save()
|
|
self.save_m2m()
|
|
|
|
return instance
|
|
|
|
|
|
class ApprovalStatusUpdateForm(forms.Form):
|
|
"""Form for updating approval request status."""
|
|
|
|
status = forms.ChoiceField(
|
|
choices=InsuranceApprovalRequest.ApprovalStatus.choices,
|
|
widget=forms.Select(attrs={'class': 'form-control'})
|
|
)
|
|
reason = forms.CharField(
|
|
required=False,
|
|
widget=forms.Textarea(attrs={'rows': 3, 'class': 'form-control', 'placeholder': 'Reason for status change'})
|
|
)
|
|
notes = forms.CharField(
|
|
required=False,
|
|
widget=forms.Textarea(attrs={'rows': 3, 'class': 'form-control', 'placeholder': 'Additional notes'})
|
|
)
|
|
|
|
# Fields for approval
|
|
authorization_number = forms.CharField(
|
|
required=False,
|
|
max_length=100,
|
|
widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Authorization number'})
|
|
)
|
|
approved_quantity = forms.IntegerField(
|
|
required=False,
|
|
min_value=1,
|
|
widget=forms.NumberInput(attrs={'class': 'form-control'})
|
|
)
|
|
effective_date = forms.DateField(
|
|
required=False,
|
|
widget=forms.DateInput(attrs={'type': 'date', 'class': 'form-control'})
|
|
)
|
|
expiration_date = forms.DateField(
|
|
required=False,
|
|
widget=forms.DateInput(attrs={'type': 'date', 'class': 'form-control'})
|
|
)
|
|
|
|
# Fields for denial
|
|
denial_reason = forms.CharField(
|
|
required=False,
|
|
widget=forms.Textarea(attrs={'rows': 3, 'class': 'form-control', 'placeholder': 'Reason for denial'})
|
|
)
|
|
denial_code = forms.CharField(
|
|
required=False,
|
|
max_length=50,
|
|
widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Denial code'})
|
|
)
|
|
|
|
|
|
class ApprovalDocumentForm(forms.ModelForm):
|
|
"""Form for uploading approval documents."""
|
|
|
|
class Meta:
|
|
model = ApprovalDocument
|
|
fields = ['document_type', 'title', 'description', 'file']
|
|
widgets = {
|
|
'document_type': forms.Select(attrs={'class': 'form-control'}),
|
|
'title': forms.TextInput(attrs={'class': 'form-control'}),
|
|
'description': forms.Textarea(attrs={'rows': 2, 'class': 'form-control'}),
|
|
'file': forms.FileInput(attrs={'class': 'form-control'}),
|
|
}
|
|
|
|
def save(self, commit=True):
|
|
instance = super().save(commit=False)
|
|
|
|
# Set file metadata
|
|
if instance.file:
|
|
instance.file_size = instance.file.size
|
|
instance.mime_type = instance.file.content_type or 'application/octet-stream'
|
|
|
|
if commit:
|
|
instance.save()
|
|
|
|
return instance
|
|
|
|
|
|
class ApprovalCommunicationForm(forms.ModelForm):
|
|
"""Form for logging communications with insurance."""
|
|
|
|
class Meta:
|
|
model = ApprovalCommunicationLog
|
|
fields = [
|
|
'communication_type',
|
|
'contact_person',
|
|
'contact_number',
|
|
'subject',
|
|
'message',
|
|
'response',
|
|
'outcome',
|
|
'follow_up_required',
|
|
'follow_up_date',
|
|
]
|
|
widgets = {
|
|
'communication_type': forms.Select(attrs={'class': 'form-control'}),
|
|
'contact_person': forms.TextInput(attrs={'class': 'form-control'}),
|
|
'contact_number': forms.TextInput(attrs={'class': 'form-control'}),
|
|
'subject': forms.TextInput(attrs={'class': 'form-control'}),
|
|
'message': forms.Textarea(attrs={'rows': 4, 'class': 'form-control'}),
|
|
'response': forms.Textarea(attrs={'rows': 3, 'class': 'form-control'}),
|
|
'outcome': forms.TextInput(attrs={'class': 'form-control'}),
|
|
'follow_up_required': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
|
|
'follow_up_date': forms.DateInput(attrs={'type': 'date', 'class': 'form-control'}),
|
|
}
|
|
|
|
|
|
class ApprovalTemplateForm(forms.ModelForm):
|
|
"""Form for creating/editing approval templates."""
|
|
|
|
class Meta:
|
|
model = ApprovalTemplate
|
|
fields = [
|
|
'name',
|
|
'description',
|
|
'request_type',
|
|
'insurance_company',
|
|
'clinical_justification_template',
|
|
'medical_necessity_template',
|
|
'required_documents',
|
|
'required_codes',
|
|
'is_active',
|
|
]
|
|
widgets = {
|
|
'name': forms.TextInput(attrs={'class': 'form-control'}),
|
|
'description': forms.Textarea(attrs={'rows': 2, 'class': 'form-control'}),
|
|
'request_type': forms.Select(attrs={'class': 'form-control'}),
|
|
'insurance_company': forms.TextInput(attrs={'class': 'form-control'}),
|
|
'clinical_justification_template': forms.Textarea(attrs={'rows': 4, 'class': 'form-control'}),
|
|
'medical_necessity_template': forms.Textarea(attrs={'rows': 3, 'class': 'form-control'}),
|
|
'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
|
|
}
|
|
|
|
|
|
class ApprovalSearchForm(forms.Form):
|
|
"""Form for searching/filtering approval requests."""
|
|
|
|
status = forms.MultipleChoiceField(
|
|
choices=InsuranceApprovalRequest.ApprovalStatus.choices,
|
|
required=False,
|
|
widget=forms.CheckboxSelectMultiple
|
|
)
|
|
priority = forms.MultipleChoiceField(
|
|
choices=InsuranceApprovalRequest.Priority.choices,
|
|
required=False,
|
|
widget=forms.CheckboxSelectMultiple
|
|
)
|
|
request_type = forms.MultipleChoiceField(
|
|
choices=InsuranceApprovalRequest.RequestType.choices,
|
|
required=False,
|
|
widget=forms.CheckboxSelectMultiple
|
|
)
|
|
patient_name = forms.CharField(
|
|
required=False,
|
|
widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Patient name'})
|
|
)
|
|
approval_number = forms.CharField(
|
|
required=False,
|
|
widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Approval number'})
|
|
)
|
|
authorization_number = forms.CharField(
|
|
required=False,
|
|
widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Authorization number'})
|
|
)
|
|
date_from = forms.DateField(
|
|
required=False,
|
|
widget=forms.DateInput(attrs={'type': 'date', 'class': 'form-control'})
|
|
)
|
|
date_to = forms.DateField(
|
|
required=False,
|
|
widget=forms.DateInput(attrs={'type': 'date', 'class': 'form-control'})
|
|
)
|
|
expiring_soon = forms.BooleanField(
|
|
required=False,
|
|
widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
|
|
)
|
|
assigned_to_me = forms.BooleanField(
|
|
required=False,
|
|
widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
|
|
)
|