""" Forms for Patients app CRUD operations. """ from django import forms from django.core.exceptions import ValidationError from django.utils import timezone from .models import ( PatientProfile, EmergencyContact, InsuranceInfo, ConsentTemplate, ConsentForm, PatientNote ) class PatientProfileForm(forms.ModelForm): """ Form for patient profile management. """ class Meta: model = PatientProfile fields = [ 'first_name', 'last_name', 'middle_name', 'preferred_name', 'suffix', 'id_number', 'date_of_birth', 'gender', 'phone_number', 'mobile_number', 'email', 'address_line_1', 'address_line_2', 'city', 'state', 'zip_code', 'country', 'marital_status', 'occupation', 'is_active' ] widgets = { 'first_name': forms.TextInput(attrs={'class': 'form-control'}), 'last_name': forms.TextInput(attrs={'class': 'form-control'}), 'middle_name': forms.TextInput(attrs={'class': 'form-control'}), 'preferred_name': forms.TextInput(attrs={'class': 'form-control'}), 'suffix': forms.TextInput(attrs={'class': 'form-control'}), 'id_number': forms.TextInput(attrs={'class': 'form-control'}), 'date_of_birth': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}), 'gender': forms.Select(attrs={'class': 'form-select'}), 'phone_number': forms.TextInput(attrs={'class': 'form-control'}), 'mobile_number': forms.TextInput(attrs={'class': 'form-control'}), 'email': forms.EmailInput(attrs={'class': 'form-control'}), 'address_line_1': forms.TextInput(attrs={'class': 'form-control'}), 'address_line_2': forms.TextInput(attrs={'class': 'form-control'}), 'city': forms.TextInput(attrs={'class': 'form-control'}), 'state': forms.TextInput(attrs={'class': 'form-control'}), 'zip_code': forms.TextInput(attrs={'class': 'form-control'}), 'country': forms.TextInput(attrs={'class': 'form-control'}), 'marital_status': forms.Select(attrs={'class': 'form-select'}), 'occupation': forms.TextInput(attrs={'class': 'form-control'}), 'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'}), } def clean_date_of_birth(self): date_of_birth = self.cleaned_data.get('date_of_birth') if date_of_birth and date_of_birth > timezone.now().date(): raise ValidationError('Date of birth cannot be in the future.') return date_of_birth def clean_email(self): email = self.cleaned_data.get('email') if email: # Check for duplicate email within tenant tenant = getattr(self.instance, 'tenant', None) if tenant: existing = PatientProfile.objects.filter( tenant=tenant, email=email ).exclude(pk=self.instance.pk if self.instance.pk else None) if existing.exists(): raise ValidationError('A patient with this email already exists.') return email class EmergencyContactForm(forms.ModelForm): """ Form for emergency contact management. """ class Meta: model = EmergencyContact exclude = ["patient"] fields = [ 'first_name', 'last_name', 'relationship', 'phone_number', 'mobile_number', 'email', 'address_line_1', 'address_line_2', 'city', 'state', 'zip_code', 'priority', 'is_authorized_for_medical_decisions' ] widgets = { # 'patient': forms.Select(attrs={'class': 'form-select'}), 'first_name': forms.TextInput(attrs={'class': 'form-control'}), 'last_name': forms.TextInput(attrs={'class': 'form-control'}), 'relationship': forms.Select(attrs={'class': 'form-select'}), 'phone_number': forms.TextInput(attrs={'class': 'form-control'}), 'mobile_number': forms.TextInput(attrs={'class': 'form-control'}), 'email': forms.EmailInput(attrs={'class': 'form-control'}), 'address_line_1': forms.TextInput(attrs={'class': 'form-control'}), 'address_line_2': forms.TextInput(attrs={'class': 'form-control'}), 'city': forms.TextInput(attrs={'class': 'form-control'}), 'state': forms.TextInput(attrs={'class': 'form-control'}), 'zip_code': forms.TextInput(attrs={'class': 'form-control'}), 'priority': forms.NumberInput(attrs={'class': 'form-control'}), 'is_authorized_for_medical_decisions': forms.CheckboxInput(attrs={'class': 'form-check-input'}), } def __init__(self, *args, **kwargs): user = kwargs.pop('user', None) super().__init__(*args, **kwargs) # if user and hasattr(user, 'tenant'): # self.fields['patient'].queryset = PatientProfile.objects.filter( # tenant=user.tenant, # is_active=True # ).order_by('last_name', 'first_name') class InsuranceInfoForm(forms.ModelForm): """ Form for insurance information management. """ class Meta: model = InsuranceInfo exclude = ["patient"] fields = [ 'insurance_type', 'insurance_company', 'plan_name', 'plan_type', 'policy_number', 'group_number', 'subscriber_name', 'subscriber_relationship', 'subscriber_dob', 'subscriber_id_number', 'effective_date', 'termination_date', 'copay_amount', 'deductible_amount', 'out_of_pocket_max', 'is_verified', 'requires_authorization' ] widgets = { 'insurance_type': forms.Select(attrs={'class': 'form-select'}), 'insurance_company': forms.TextInput(attrs={'class': 'form-control'}), 'plan_name': forms.TextInput(attrs={'class': 'form-control'}), 'plan_type': forms.Select(attrs={'class': 'form-select'}), 'policy_number': forms.TextInput(attrs={'class': 'form-control'}), 'group_number': forms.TextInput(attrs={'class': 'form-control'}), 'subscriber_name': forms.TextInput(attrs={'class': 'form-control'}), 'subscriber_relationship': forms.Select(attrs={'class': 'form-select'}), 'subscriber_dob': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}), 'subscriber_id_number': forms.TextInput(attrs={'class': 'form-control'}), 'effective_date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}), 'termination_date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}), 'copay_amount': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01'}), 'deductible_amount': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01'}), 'out_of_pocket_max': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01'}), 'is_verified': forms.CheckboxInput(attrs={'class': 'form-check-input'}), 'requires_authorization': forms.CheckboxInput(attrs={'class': 'form-check-input'}), } def __init__(self, *args, **kwargs): user = kwargs.pop('user', None) super().__init__(*args, **kwargs) # if user and hasattr(user, 'tenant'): # self.fields['patient'].queryset = PatientProfile.objects.filter( # tenant=user.tenant, # is_active=True # ).order_by('last_name', 'first_name') class ConsentTemplateForm(forms.ModelForm): """ Form for consent template management. """ class Meta: model = ConsentTemplate fields = [ 'name', 'description', 'category', 'content', 'version', 'is_active', 'requires_signature', 'requires_witness', 'requires_guardian', 'effective_date', 'expiry_date', ] widgets = { 'name': forms.TextInput(attrs={'class': 'form-control'}), 'description': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}), 'category': forms.Select(attrs={'class': 'form-select'}), 'content': forms.Textarea(attrs={'class': 'form-control', 'rows': 10}), 'version': forms.TextInput(attrs={'class': 'form-control'}), 'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'}), 'requires_signature': forms.CheckboxInput(attrs={'class': 'form-check-input'}), 'requires_witness': forms.CheckboxInput(attrs={'class': 'form-check-input'}), 'requires_guardian': forms.CheckboxInput(attrs={'class': 'form-check-input'}), 'effective_date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}), 'expiry_date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}), } class ConsentFormForm(forms.ModelForm): """ Form for consent form management. """ class Meta: model = ConsentForm fields = [ 'patient', 'template', 'status', 'patient_signature', 'patient_signed_at', 'guardian_signature', 'guardian_signed_at', 'guardian_name', 'guardian_relationship', 'witness_signature', 'witness_signed_at', 'witness_name', 'notes' ] widgets = { 'patient': forms.Select(attrs={'class': 'form-select'}), 'template': forms.Select(attrs={'class': 'form-select'}), 'status': forms.Select(attrs={'class': 'form-select'}), 'patient_signature': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}), 'patient_signed_at': forms.DateTimeInput(attrs={'class': 'form-control', 'type': 'datetime-local'}), 'guardian_signature': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}), 'guardian_signed_at': forms.DateTimeInput(attrs={'class': 'form-control', 'type': 'datetime-local'}), 'guardian_name': forms.TextInput(attrs={'class': 'form-control'}), 'guardian_relationship': forms.TextInput(attrs={'class': 'form-control'}), 'witness_signature': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}), 'witness_signed_at': forms.DateTimeInput(attrs={'class': 'form-control', 'type': 'datetime-local'}), 'witness_name': forms.TextInput(attrs={'class': 'form-control'}), 'notes': forms.Textarea(attrs={'class': 'form-control', 'rows': 4}), } def __init__(self, *args, **kwargs): user = kwargs.pop('user', None) super().__init__(*args, **kwargs) if user and hasattr(user, 'tenant'): self.fields['patient'].queryset = PatientProfile.objects.filter( tenant=user.tenant, is_active=True ).order_by('last_name', 'first_name') self.fields['template'].queryset = ConsentTemplate.objects.filter( tenant=user.tenant, is_active=True ).order_by('name') class PatientNoteForm(forms.ModelForm): """ Form for patient note management. """ class Meta: model = PatientNote exclude = ["patient"] fields = [ 'title', 'content', 'category', 'priority', 'is_confidential', 'is_alert', 'is_active' ] widgets = { # 'patient': forms.Select(attrs={'class': 'form-select'}), 'title': forms.TextInput(attrs={'class': 'form-control'}), 'content': forms.Textarea(attrs={'class': 'form-control', 'rows': 6}), 'category': forms.Select(attrs={'class': 'form-select'}), 'priority': forms.Select(attrs={'class': 'form-select'}), 'is_confidential': forms.CheckboxInput(attrs={'class': 'form-check-input'}), 'is_alert': forms.CheckboxInput(attrs={'class': 'form-check-input'}), 'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'}), } def __init__(self, *args, **kwargs): user = kwargs.pop('user', None) super().__init__(*args, **kwargs) # if user and hasattr(user, 'tenant'): # self.fields['patient'].queryset = PatientProfile.objects.filter( # tenant=user.tenant, # is_active=True # ).order_by('last_name', 'first_name') class PatientsSearchForm(forms.Form): """ Form for searching patient data. """ search = forms.CharField( max_length=255, required=False, widget=forms.TextInput(attrs={ 'class': 'form-control', 'placeholder': 'Search patients, contacts, insurance...' }) ) gender = forms.ChoiceField( choices=[('', 'All Genders')] + list(PatientProfile._meta.get_field('gender').choices), required=False, widget=forms.Select(attrs={'class': 'form-select'}) ) status = forms.ChoiceField( choices=[ ('', 'All Statuses'), ('active', 'Active'), ('inactive', 'Inactive'), ], required=False, widget=forms.Select(attrs={'class': 'form-select'}) ) date_from = forms.DateField( required=False, widget=forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}) ) date_to = forms.DateField( required=False, widget=forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}) )