Marwan Alwali 4ca3f7159a update
2025-09-22 01:37:55 +03:00

1616 lines
61 KiB
Python

"""
Forms for Appointments app CRUD operations.
"""
from django import forms
from django.core.exceptions import ValidationError
from django.utils import timezone
from datetime import datetime, time, timedelta, date
from .models import *
from patients.models import PatientProfile
from accounts.models import User
from hr.models import Employee, Department
class AppointmentRequestForm(forms.ModelForm):
"""
Form for appointment request management.
Patient is set automatically in the view; it is NOT exposed here.
"""
class Meta:
model = AppointmentRequest
# do not include 'patient' so it cannot be tampered with
exclude = ['patient','status']
fields = [
'provider', 'appointment_type', 'specialty', 'preferred_date',
'preferred_time', 'duration_minutes', 'priority', 'chief_complaint',
'clinical_notes', 'is_telemedicine', 'location', 'room_number'
]
widgets = {
'provider': forms.Select(attrs={'class': 'form-select'}),
'appointment_type': forms.Select(attrs={'class': 'form-select'}),
'specialty': forms.Select(attrs={'class': 'form-select'}),
'preferred_date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}),
'preferred_time': forms.TimeInput(attrs={'class': 'form-control', 'type': 'time'}),
'duration_minutes': forms.NumberInput(attrs={'class': 'form-control', 'min': '15', 'step': '15'}),
'priority': forms.Select(attrs={'class': 'form-select'}),
'chief_complaint': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
'clinical_notes': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
'is_telemedicine': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
'location': forms.TextInput(attrs={'class': 'form-control'}),
'room_number': forms.TextInput(attrs={'class': 'form-control'}),
}
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
# patient is optional to receive; we don't render it, but can use if needed
# self._patient = kwargs.pop('patient', None)
super().__init__(*args, **kwargs)
# Scope provider list to tenant
if user and hasattr(user, 'tenant'):
self.fields['provider'].queryset = User.objects.filter(
tenant=user.tenant,
is_active=True,
employee_profile__role__in=['PHYSICIAN', 'NURSE', 'NURSE_PRACTITIONER', 'PHYSICIAN_ASSISTANT']
).order_by('last_name', 'first_name')
def clean_preferred_date(self):
preferred_date = self.cleaned_data.get('preferred_date')
if preferred_date and preferred_date < timezone.now().date():
raise ValidationError('Appointment cannot be scheduled in the past.')
return preferred_date
def clean_duration_minutes(self):
duration = self.cleaned_data.get('duration_minutes')
if duration and duration < 15:
raise ValidationError('Appointment duration must be at least 15 minutes.')
if duration and duration > 480: # 8 hours
raise ValidationError('Appointment duration cannot exceed 8 hours.')
return duration
class SlotAvailabilityForm(forms.ModelForm):
"""
Form for slot availability management.
"""
class Meta:
model = SlotAvailability
fields = [
'provider', 'date', 'start_time', 'end_time', 'duration_minutes',
'max_appointments', 'location', 'room_number', 'specialty',
'availability_type', 'is_active', 'supports_telemedicine'
]
widgets = {
'provider': forms.Select(attrs={'class': 'form-select'}),
'date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}),
'start_time': forms.TimeInput(attrs={'class': 'form-control', 'type': 'time'}),
'end_time': forms.TimeInput(attrs={'class': 'form-control', 'type': 'time'}),
'duration_minutes': forms.NumberInput(attrs={'class': 'form-control', 'min': '15', 'step': '15'}),
'max_appointments': forms.NumberInput(attrs={'class': 'form-control', 'min': '1'}),
'location': forms.TextInput(attrs={'class': 'form-control'}),
'room_number': forms.TextInput(attrs={'class': 'form-control'}),
'specialty': forms.TextInput(attrs={'class': 'form-control'}),
'availability_type': forms.Select(attrs={'class': 'form-select'}),
'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
'supports_telemedicine': 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['provider'].queryset = User.objects.filter(
tenant=user.tenant,
is_active=True,
role__in=['PHYSICIAN', 'NURSE', 'NURSE_PRACTITIONER', 'PHYSICIAN_ASSISTANT']
).order_by('last_name', 'first_name')
def clean(self):
cleaned_data = super().clean()
date = cleaned_data.get('date')
start_time = cleaned_data.get('start_time')
end_time = cleaned_data.get('end_time')
if date and date < timezone.now().date():
raise ValidationError('Availability date cannot be in the past.')
if start_time and end_time and start_time >= end_time:
raise ValidationError('Start time must be before end time.')
return cleaned_data
class WaitingQueueForm(forms.ModelForm):
"""
Form for waiting queue management.
"""
class Meta:
model = WaitingQueue
fields = [
'name', 'description', 'queue_type', 'location', 'specialty',
'max_queue_size', 'average_service_time_minutes', 'is_active'
]
widgets = {
'name': forms.TextInput(attrs={'class': 'form-control'}),
'description': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
'queue_type': forms.Select(attrs={'class': 'form-select'}),
'location': forms.TextInput(attrs={'class': 'form-control'}),
'specialty': forms.TextInput(attrs={'class': 'form-control'}),
'max_queue_size': forms.NumberInput(attrs={'class': 'form-control', 'min': '1'}),
'average_service_time_minutes': forms.NumberInput(attrs={'class': 'form-control', 'min': '0'}),
'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
}
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
tenant = kwargs.pop('tenant', None)
super().__init__(*args, **kwargs)
if user and tenant:
self.fields['provider'].queryset = User.objects.filter(
tenant=tenant,
is_active=True,
role__in=['PHYSICIAN', 'NURSE', 'NURSE_PRACTITIONER', 'PHYSICIAN_ASSISTANT']
).order_by('last_name', 'first_name')
class QueueEntryForm(forms.ModelForm):
"""
Form for queue entry management.
"""
class Meta:
model = QueueEntry
fields = [
'queue', 'patient', 'appointment', 'priority_score', 'assigned_provider',
'status', 'notes'
]
widgets = {
'queue': forms.Select(attrs={'class': 'form-select'}),
'patient': forms.Select(attrs={'class': 'form-select'}),
'appointment': forms.Select(attrs={'class': 'form-select'}),
'priority_score': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.1', 'min': '0'}),
'assigned_provider': forms.Select(attrs={'class': 'form-select'}),
'status': forms.Select(attrs={'class': 'form-select'}),
'notes': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
}
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
super().__init__(*args, **kwargs)
if user and hasattr(user, 'tenant'):
self.fields['queue'].queryset = WaitingQueue.objects.filter(
tenant=user.tenant,
is_active=True
).order_by('name')
self.fields['patient'].queryset = PatientProfile.objects.filter(
tenant=user.tenant,
is_active=True
).order_by('last_name', 'first_name')
self.fields['appointment'].queryset = AppointmentRequest.objects.filter(
tenant=user.tenant,
status__in=['SCHEDULED', 'CONFIRMED']
).order_by('-preferred_date')
class TelemedicineSessionForm(forms.ModelForm):
"""
Form for telemedicine session management.
"""
class Meta:
model = TelemedicineSession
fields = [
'appointment', 'platform', 'meeting_url', 'meeting_id', 'meeting_password',
'scheduled_start', 'scheduled_end', 'status', 'waiting_room_enabled',
'recording_enabled', 'recording_consent'
]
widgets = {
'appointment': forms.Select(attrs={'class': 'form-select'}),
'platform': forms.Select(attrs={'class': 'form-select'}),
'meeting_url': forms.URLInput(attrs={'class': 'form-control'}),
'meeting_id': forms.TextInput(attrs={'class': 'form-control'}),
'meeting_password': forms.PasswordInput(attrs={'class': 'form-control'}),
'scheduled_start': forms.DateTimeInput(attrs={'class': 'form-control', 'type': 'datetime-local'}),
'scheduled_end': forms.DateTimeInput(attrs={'class': 'form-control', 'type': 'datetime-local'}),
'status': forms.Select(attrs={'class': 'form-select'}),
'waiting_room_enabled': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
'recording_enabled': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
'recording_consent': 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['appointment'].queryset = AppointmentRequest.objects.filter(
tenant=user.tenant,
is_telemedicine=True,
status__in=['SCHEDULED', 'CONFIRMED', 'IN_PROGRESS']
).order_by('-preferred_date')
def clean(self):
cleaned_data = super().clean()
start_time = cleaned_data.get('session_start_time')
end_time = cleaned_data.get('session_end_time')
if start_time and end_time and start_time >= end_time:
raise ValidationError('Start time must be before end time.')
return cleaned_data
class AppointmentTemplateForm(forms.ModelForm):
"""
Form for appointment template management.
"""
class Meta:
model = AppointmentTemplate
fields = [
'name', 'description', 'appointment_type', 'duration_minutes',
'specialty', 'advance_booking_days', 'minimum_notice_hours',
'pre_appointment_instructions', 'post_appointment_instructions',
'is_active'
]
widgets = {
'name': forms.TextInput(attrs={'class': 'form-control'}),
'description': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
'appointment_type': forms.TextInput(attrs={'class': 'form-control'}),
'duration_minutes': forms.NumberInput(attrs={'class': 'form-control', 'min': '15', 'step': '15'}),
'specialty': forms.TextInput(attrs={'class': 'form-control'}),
'advance_booking_days': forms.NumberInput(attrs={'class': 'form-control', 'min': '1'}),
'minimum_notice_hours': forms.NumberInput(attrs={'class': 'form-control', 'min': '1'}),
'pre_appointment_instructions': forms.Textarea(attrs={'class': 'form-control', 'rows': 4}),
'post_appointment_instructions': forms.Textarea(attrs={'class': 'form-control', 'rows': 4}),
'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['provider'].queryset = User.objects.filter(
tenant=user.tenant,
is_active=True,
role__in=['PHYSICIAN', 'NURSE', 'NURSE_PRACTITIONER', 'PHYSICIAN_ASSISTANT']
).order_by('last_name', 'first_name')
class AppointmentSearchForm(forms.Form):
"""
Form for searching appointment data.
"""
search = forms.CharField(
max_length=255,
required=False,
widget=forms.TextInput(attrs={
'class': 'form-control',
'placeholder': 'Search appointments, patients, providers...'
})
)
appointment_type = forms.ChoiceField(
choices=[('', 'All Types')] + list(AppointmentRequest._meta.get_field('appointment_type').choices),
required=False,
widget=forms.Select(attrs={'class': 'form-select'})
)
status = forms.ChoiceField(
choices=[('', 'All Status')] + list(AppointmentRequest._meta.get_field('status').choices),
required=False,
widget=forms.Select(attrs={'class': 'form-select'})
)
priority = forms.ChoiceField(
choices=[('', 'All Priorities')] + list(AppointmentRequest._meta.get_field('priority').choices),
required=False,
widget=forms.Select(attrs={'class': 'form-select'})
)
provider = forms.ModelChoiceField(
queryset=User.objects.none(),
required=False,
empty_label='All Providers',
widget=forms.Select(attrs={'class': 'form-select'})
)
specialty = forms.CharField(
max_length=100,
required=False,
widget=forms.TextInput(attrs={
'class': 'form-control',
'placeholder': 'Specialty'
})
)
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'
})
)
is_telemedicine = forms.ChoiceField(
choices=[
('', 'All Appointments'),
('true', 'Telemedicine Only'),
('false', 'In-Person Only')
],
required=False,
widget=forms.Select(attrs={'class': 'form-select'})
)
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
super().__init__(*args, **kwargs)
if user and hasattr(user, 'tenant'):
self.fields['provider'].queryset = User.objects.filter(
tenant=user.tenant,
is_active=True,
employee_profile__role__in=['PHYSICIAN', 'NURSE', 'NURSE_PRACTITIONER', 'PHYSICIAN_ASSISTANT']
).order_by('last_name', 'first_name')
class QueueSearchForm(forms.Form):
"""
Form for searching queues.
"""
search = forms.CharField(
max_length=200,
required=False,
widget=forms.TextInput(attrs={
'class': 'form-control',
'placeholder': 'Search queues...'
})
)
queue_type = forms.ChoiceField(
choices=[('', 'All Types')] + [
('PROVIDER', 'Provider Queue'),
('SPECIALTY', 'Specialty Queue'),
('LOCATION', 'Location Queue'),
('PROCEDURE', 'Procedure Queue'),
('EMERGENCY', 'Emergency Queue'),
],
required=False,
widget=forms.Select(attrs={'class': 'form-select'})
)
is_active = forms.ChoiceField(
choices=[('', 'All'), ('true', 'Active'), ('false', 'Inactive')],
required=False,
widget=forms.Select(attrs={'class': 'form-select'})
)
class SlotSearchForm(forms.Form):
"""
Form for searching appointment slots.
"""
search = forms.CharField(
max_length=200,
required=False,
widget=forms.TextInput(attrs={
'class': 'form-control',
'placeholder': 'Search slots...'
})
)
provider = forms.ModelChoiceField(
queryset=User.objects.none(),
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'
})
)
is_available = forms.ChoiceField(
choices=[('', 'All'), ('true', 'Available'), ('false', 'Booked')],
required=False,
widget=forms.Select(attrs={'class': 'form-select'})
)
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
super().__init__(*args, **kwargs)
if user:
self.fields['provider'].queryset = User.objects.filter(
tenant=user.tenant,
role__in=['PHYSICIAN', 'NURSE', 'NURSE_PRACTITIONER', 'PHYSICIAN_ASSISTANT']
).order_by('last_name', 'first_name')
class WaitingListForm(forms.ModelForm):
"""
Form for creating and updating waiting list entries.
"""
class Meta:
model = WaitingList
fields = [
'patient', 'department', 'provider', 'appointment_type', 'specialty',
'priority', 'urgency_score', 'clinical_indication', 'diagnosis_codes',
'preferred_date', 'preferred_time', 'flexible_scheduling',
'earliest_acceptable_date', 'latest_acceptable_date',
'acceptable_days', 'acceptable_times',
'contact_method', 'contact_phone', 'contact_email',
'requires_interpreter', 'interpreter_language',
'accessibility_requirements', 'transportation_needed',
'insurance_verified', 'authorization_required',
'referring_provider', 'referral_date', 'referral_urgency',
'notes'
]
widgets = {
'patient': forms.Select(attrs={
'class': 'form-select',
'required': True
}),
'department': forms.Select(attrs={
'class': 'form-select',
'required': True
}),
'provider': forms.Select(attrs={
'class': 'form-select'
}),
'appointment_type': forms.Select(attrs={
'class': 'form-select',
'required': True
}),
'specialty': forms.Select(attrs={
'class': 'form-select',
'required': True
}),
'priority': forms.Select(attrs={
'class': 'form-select',
'required': True
}),
'urgency_score': forms.NumberInput(attrs={
'class': 'form-control',
'min': 1,
'max': 10,
'required': True
}),
'clinical_indication': forms.Textarea(attrs={
'class': 'form-control',
'rows': 4,
'required': True,
'placeholder': 'Describe the clinical reason for this appointment request...'
}),
'diagnosis_codes': forms.Textarea(attrs={
'class': 'form-control',
'rows': 2,
'placeholder': 'Enter ICD-10 codes separated by commas'
}),
'preferred_date': forms.DateInput(attrs={
'class': 'form-control',
'type': 'date',
'min': date.today().isoformat()
}),
'preferred_time': forms.TimeInput(attrs={
'class': 'form-control',
'type': 'time'
}),
'flexible_scheduling': forms.CheckboxInput(attrs={
'class': 'form-check-input'
}),
'earliest_acceptable_date': forms.DateInput(attrs={
'class': 'form-control',
'type': 'date',
'min': date.today().isoformat()
}),
'latest_acceptable_date': forms.DateInput(attrs={
'class': 'form-control',
'type': 'date'
}),
'acceptable_days': forms.CheckboxSelectMultiple(attrs={
'class': 'form-check-input'
}),
'contact_method': forms.Select(attrs={
'class': 'form-select',
'required': True
}),
'contact_phone': forms.TextInput(attrs={
'class': 'form-control',
'placeholder': '(555) 123-4567'
}),
'contact_email': forms.EmailInput(attrs={
'class': 'form-control',
'placeholder': 'patient@example.com'
}),
'requires_interpreter': forms.CheckboxInput(attrs={
'class': 'form-check-input'
}),
'interpreter_language': forms.TextInput(attrs={
'class': 'form-control',
'placeholder': 'e.g., Spanish, Mandarin, ASL'
}),
'accessibility_requirements': forms.Textarea(attrs={
'class': 'form-control',
'rows': 3,
'placeholder': 'Describe any accessibility needs...'
}),
'transportation_needed': forms.CheckboxInput(attrs={
'class': 'form-check-input'
}),
'insurance_verified': forms.CheckboxInput(attrs={
'class': 'form-check-input'
}),
'authorization_required': forms.CheckboxInput(attrs={
'class': 'form-check-input'
}),
'referring_provider': forms.TextInput(attrs={
'class': 'form-control',
'placeholder': 'Dr. Smith, Internal Medicine'
}),
'referral_date': forms.DateInput(attrs={
'class': 'form-control',
'type': 'date'
}),
'referral_urgency': forms.Select(attrs={
'class': 'form-select'
}),
'notes': forms.Textarea(attrs={
'class': 'form-control',
'rows': 4,
'placeholder': 'Additional notes and comments...'
}),
}
def __init__(self, *args, **kwargs):
self.tenant = kwargs.pop('tenant', None)
super().__init__(*args, **kwargs)
# Filter choices based on tenant
if self.tenant:
self.fields['patient'].queryset = self.fields['patient'].queryset.filter(
tenant=self.tenant
)
self.fields['department'].queryset = self.fields['department'].queryset.filter(
tenant=self.tenant
)
if 'provider' in self.fields:
self.fields['provider'].queryset = self.fields['provider'].queryset.filter(
tenant=self.tenant
)
def clean(self):
cleaned_data = super().clean()
# Validate date ranges
preferred_date = cleaned_data.get('preferred_date')
earliest_date = cleaned_data.get('earliest_acceptable_date')
latest_date = cleaned_data.get('latest_acceptable_date')
if preferred_date and preferred_date < date.today():
raise ValidationError("Preferred date cannot be in the past.")
if earliest_date and latest_date and earliest_date > latest_date:
raise ValidationError("Earliest acceptable date must be before latest acceptable date.")
if preferred_date and earliest_date and preferred_date < earliest_date:
raise ValidationError("Preferred date must be within acceptable date range.")
if preferred_date and latest_date and preferred_date > latest_date:
raise ValidationError("Preferred date must be within acceptable date range.")
# Validate contact information
contact_method = cleaned_data.get('contact_method')
contact_phone = cleaned_data.get('contact_phone')
contact_email = cleaned_data.get('contact_email')
if contact_method == 'PHONE' and not contact_phone:
raise ValidationError("Phone number is required when phone is selected as contact method.")
if contact_method == 'EMAIL' and not contact_email:
raise ValidationError("Email address is required when email is selected as contact method.")
# Validate interpreter requirements
requires_interpreter = cleaned_data.get('requires_interpreter')
interpreter_language = cleaned_data.get('interpreter_language')
if requires_interpreter and not interpreter_language:
raise ValidationError("Interpreter language is required when interpreter services are needed.")
return cleaned_data
class WaitingListContactLogForm(forms.ModelForm):
"""
Form for logging contact attempts with waiting list patients.
"""
class Meta:
model = WaitingListContactLog
fields = [
'contact_method', 'contact_outcome', 'appointment_offered',
'offered_date', 'offered_time', 'patient_response',
'notes', 'next_contact_date'
]
widgets = {
'contact_method': forms.Select(attrs={
'class': 'form-select form-select-sm',
'required': True
}),
'contact_outcome': forms.Select(attrs={
'class': 'form-select form-select-sm',
'required': True
}),
'appointment_offered': forms.CheckboxInput(attrs={
'class': 'form-check-input'
}),
'offered_date': forms.DateInput(attrs={
'class': 'form-control form-control-sm',
'type': 'date'
}),
'offered_time': forms.TimeInput(attrs={
'class': 'form-control form-control-sm',
'type': 'time'
}),
'patient_response': forms.Select(attrs={
'class': 'form-select form-select-sm'
}),
'notes': forms.Textarea(attrs={
'class': 'form-control form-control-sm',
'rows': 4,
'placeholder': 'Notes from contact attempt...'
}),
'next_contact_date': forms.DateInput(attrs={
'class': 'form-control form-control-sm',
'type': 'date',
'min': date.today().isoformat()
}),
}
def clean(self):
cleaned_data = super().clean()
appointment_offered = cleaned_data.get('appointment_offered')
offered_date = cleaned_data.get('offered_date')
offered_time = cleaned_data.get('offered_time')
patient_response = cleaned_data.get('patient_response')
if appointment_offered:
if not offered_date:
raise ValidationError("Offered date is required when appointment is offered.")
if not offered_time:
raise ValidationError("Offered time is required when appointment is offered.")
if not patient_response:
raise ValidationError("Patient response is required when appointment is offered.")
next_contact_date = cleaned_data.get('next_contact_date')
if next_contact_date and next_contact_date < date.today():
raise ValidationError("Next contact date cannot be in the past.")
return cleaned_data
class WaitingListFilterForm(forms.Form):
"""
Form for filtering waiting list entries.
"""
PRIORITY_CHOICES = [
('', 'All Priorities'),
('EMERGENCY', 'Emergency'),
('STAT', 'STAT'),
('URGENT', 'Urgent'),
('ROUTINE', 'Routine'),
]
STATUS_CHOICES = [
('', 'All Status'),
('ACTIVE', 'Active'),
('CONTACTED', 'Contacted'),
('OFFERED', 'Appointment Offered'),
('SCHEDULED', 'Scheduled'),
('CANCELLED', 'Cancelled'),
('EXPIRED', 'Expired'),
]
department = forms.ModelChoiceField(
queryset=None,
required=False,
empty_label="All Departments",
widget=forms.Select(attrs={'class': 'form-select'})
)
specialty = forms.ChoiceField(
choices=[('', 'All Specialties')] + WaitingList._meta.get_field('specialty').choices,
required=False,
widget=forms.Select(attrs={'class': 'form-select'})
)
priority = forms.ChoiceField(
choices=PRIORITY_CHOICES,
required=False,
widget=forms.Select(attrs={'class': 'form-select'})
)
status = forms.ChoiceField(
choices=STATUS_CHOICES,
required=False,
widget=forms.Select(attrs={'class': 'form-select'})
)
provider = forms.ModelChoiceField(
queryset=None,
required=False,
empty_label="All Providers",
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'
})
)
urgency_min = forms.IntegerField(
required=False,
min_value=1,
max_value=10,
widget=forms.NumberInput(attrs={
'class': 'form-control',
'placeholder': 'Min urgency (1-10)'
})
)
urgency_max = forms.IntegerField(
required=False,
min_value=1,
max_value=10,
widget=forms.NumberInput(attrs={
'class': 'form-control',
'placeholder': 'Max urgency (1-10)'
})
)
def __init__(self, *args, **kwargs):
tenant = kwargs.pop('tenant', None)
super().__init__(*args, **kwargs)
if tenant:
self.fields['department'].queryset = Department.objects.filter(tenant=tenant)
self.fields['provider'].queryset = User.objects.filter(
tenant=tenant
)
class WaitingListBulkActionForm(forms.Form):
"""
Form for bulk actions on waiting list entries.
"""
ACTION_CHOICES = [
('', 'Select Action'),
('contact', 'Mark as Contacted'),
('cancel', 'Cancel Entries'),
('update_priority', 'Update Priority'),
('transfer_provider', 'Transfer to Provider'),
('export', 'Export Selected'),
]
action = forms.ChoiceField(
choices=ACTION_CHOICES,
required=True,
widget=forms.Select(attrs={'class': 'form-select'})
)
# Fields for specific actions
new_priority = forms.ChoiceField(
choices=WaitingList._meta.get_field('priority').choices,
required=False,
widget=forms.Select(attrs={'class': 'form-select'})
)
transfer_provider = forms.ModelChoiceField(
queryset=None,
required=False,
widget=forms.Select(attrs={'class': 'form-select'})
)
contact_notes = forms.CharField(
required=False,
widget=forms.Textarea(attrs={
'class': 'form-control',
'rows': 3,
'placeholder': 'Notes for contact action...'
})
)
cancellation_reason = forms.CharField(
required=False,
widget=forms.Textarea(attrs={
'class': 'form-control',
'rows': 3,
'placeholder': 'Reason for cancellation...'
})
)
def __init__(self, *args, **kwargs):
tenant = kwargs.pop('tenant', None)
super().__init__(*args, **kwargs)
if tenant:
from django.contrib.auth import get_user_model
User = get_user_model()
self.fields['transfer_provider'].queryset = User.objects.filter(
tenant=tenant
)
# from django import forms
# from django.core.exceptions import ValidationError
# from django.utils import timezone
# from django.contrib.auth.models import User
# from crispy_forms.helper import FormHelper
# from crispy_forms.layout import Layout, Fieldset, Submit, Row, Column, HTML, Div
# from crispy_forms.bootstrap import FormActions
# from datetime import datetime, timedelta
#
# from .models import Appointment, AppointmentConfirmation, Queue, TelemedicineSession
# from patients.models import Patient
# from core.models import Department
#
#
# class AppointmentSchedulingForm(forms.ModelForm):
# """
# Form for appointment scheduling
# """
# patient_search = forms.CharField(
# required=False,
# widget=forms.TextInput(attrs={
# 'class': 'form-control',
# 'placeholder': 'Search patient by name, ID, or phone...',
# 'data-toggle': 'patient-search'
# })
# )
# preferred_time_1 = forms.TimeField(
# required=False,
# widget=forms.TimeInput(attrs={'class': 'form-control', 'type': 'time'})
# )
# preferred_time_2 = forms.TimeField(
# required=False,
# widget=forms.TimeInput(attrs={'class': 'form-control', 'type': 'time'})
# )
# preferred_time_3 = forms.TimeField(
# required=False,
# widget=forms.TimeInput(attrs={'class': 'form-control', 'type': 'time'})
# )
# special_instructions = forms.CharField(
# required=False,
# widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 3})
# )
# send_confirmation = forms.BooleanField(
# required=False,
# initial=True,
# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
# )
# send_reminder = forms.BooleanField(
# required=False,
# initial=True,
# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
# )
#
# class Meta:
# model = Appointment
# fields = [
# 'patient', 'provider', 'department', 'appointment_type',
# 'appointment_date', 'appointment_time', 'duration',
# 'urgency', 'reason', 'notes', 'special_instructions',
# 'send_confirmation', 'send_reminder'
# ]
# widgets = {
# 'patient': forms.Select(attrs={'class': 'form-control'}),
# 'provider': forms.Select(attrs={'class': 'form-control'}),
# 'department': forms.Select(attrs={'class': 'form-control'}),
# 'appointment_type': forms.Select(attrs={'class': 'form-control'}),
# 'appointment_date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}),
# 'appointment_time': forms.TimeInput(attrs={'class': 'form-control', 'type': 'time'}),
# 'duration': forms.NumberInput(attrs={'class': 'form-control'}),
# 'urgency': forms.Select(attrs={'class': 'form-control'}),
# 'reason': forms.TextInput(attrs={'class': 'form-control'}),
# 'notes': forms.Textarea(attrs={'class': 'form-control', 'rows': 3})
# }
#
# def __init__(self, *args, **kwargs):
# tenant = kwargs.pop('tenant', None)
# super().__init__(*args, **kwargs)
#
# if tenant:
# self.fields['patient'].queryset = Patient.objects.filter(tenant=tenant)
# self.fields['provider'].queryset = User.objects.filter(
# tenant=tenant,
# groups__name__in=['Doctors', 'Nurses', 'Specialists']
# )
# self.fields['department'].queryset = Department.objects.filter(tenant=tenant)
#
# # Set minimum date to today
# self.fields['appointment_date'].widget.attrs['min'] = timezone.now().date().isoformat()
#
# self.helper = FormHelper()
# self.helper.layout = Layout(
# Fieldset(
# 'Patient Information',
# 'patient_search',
# 'patient'
# ),
# Fieldset(
# 'Appointment Details',
# Row(
# Column('provider', css_class='form-group col-md-6 mb-0'),
# Column('department', css_class='form-group col-md-6 mb-0'),
# css_class='form-row'
# ),
# Row(
# Column('appointment_type', css_class='form-group col-md-6 mb-0'),
# Column('urgency', css_class='form-group col-md-6 mb-0'),
# css_class='form-row'
# ),
# Row(
# Column('appointment_date', css_class='form-group col-md-4 mb-0'),
# Column('appointment_time', css_class='form-group col-md-4 mb-0'),
# Column('duration', css_class='form-group col-md-4 mb-0'),
# css_class='form-row'
# ),
# 'reason',
# 'notes',
# 'special_instructions'
# ),
# Fieldset(
# 'Preferred Times (Alternative Options)',
# Row(
# Column('preferred_time_1', css_class='form-group col-md-4 mb-0'),
# Column('preferred_time_2', css_class='form-group col-md-4 mb-0'),
# Column('preferred_time_3', css_class='form-group col-md-4 mb-0'),
# css_class='form-row'
# )
# ),
# Fieldset(
# 'Notifications',
# HTML('<div class="form-check">'),
# 'send_confirmation',
# HTML(
# '<label class="form-check-label" for="id_send_confirmation">Send appointment confirmation</label>'),
# HTML('</div>'),
# HTML('<div class="form-check">'),
# 'send_reminder',
# HTML('<label class="form-check-label" for="id_send_reminder">Send appointment reminder</label>'),
# HTML('</div>')
# ),
# FormActions(
# Submit('submit', 'Schedule Appointment', css_class='btn btn-primary'),
# HTML('<a href="{% url \'appointments:appointment_list\' %}" class="btn btn-secondary">Cancel</a>')
# )
# )
#
# def clean(self):
# cleaned_data = super().clean()
# appointment_date = cleaned_data.get('appointment_date')
# appointment_time = cleaned_data.get('appointment_time')
# provider = cleaned_data.get('provider')
#
# if appointment_date and appointment_time:
# appointment_datetime = datetime.combine(appointment_date, appointment_time)
#
# # Check if appointment is in the past
# if appointment_datetime < timezone.now():
# raise ValidationError('Appointment cannot be scheduled in the past.')
#
# # Check provider availability
# if provider and self.check_provider_conflict(provider, appointment_datetime):
# raise ValidationError('Provider is not available at the selected time.')
#
# return cleaned_data
#
# def check_provider_conflict(self, provider, appointment_datetime):
# """Check if provider has conflicting appointments"""
# duration = self.cleaned_data.get('duration', 30)
# end_time = appointment_datetime + timedelta(minutes=duration)
#
# conflicts = Appointment.objects.filter(
# provider=provider,
# appointment_date=appointment_datetime.date(),
# status__in=['scheduled', 'confirmed', 'in_progress']
# ).exclude(id=self.instance.id if self.instance else None)
#
# for conflict in conflicts:
# conflict_start = datetime.combine(conflict.appointment_date, conflict.appointment_time)
# conflict_end = conflict_start + timedelta(minutes=conflict.duration)
#
# if (appointment_datetime < conflict_end and end_time > conflict_start):
# return True
#
# return False
#
#
# class AppointmentConfirmationForm(forms.ModelForm):
# """
# Form for appointment confirmation
# """
# confirmation_method = forms.ChoiceField(
# choices=[
# ('phone', 'Phone Call'),
# ('email', 'Email'),
# ('sms', 'SMS'),
# ('in_person', 'In Person'),
# ('online', 'Online Portal')
# ],
# required=True,
# widget=forms.Select(attrs={'class': 'form-control'})
# )
# contact_attempts = forms.IntegerField(
# initial=1,
# min_value=1,
# max_value=5,
# widget=forms.NumberInput(attrs={'class': 'form-control'})
# )
# confirmation_notes = forms.CharField(
# required=False,
# widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 3})
# )
# reschedule_requested = forms.BooleanField(
# required=False,
# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
# )
# new_preferred_date = forms.DateField(
# required=False,
# widget=forms.DateInput(attrs={'class': 'form-control', 'type': 'date'})
# )
# new_preferred_time = forms.TimeField(
# required=False,
# widget=forms.TimeInput(attrs={'class': 'form-control', 'type': 'time'})
# )
#
# class Meta:
# model = AppointmentConfirmation
# fields = [
# 'confirmation_method', 'contact_attempts', 'confirmation_notes',
# 'reschedule_requested', 'new_preferred_date', 'new_preferred_time'
# ]
#
# def __init__(self, *args, **kwargs):
# appointment = kwargs.pop('appointment', None)
# super().__init__(*args, **kwargs)
#
# self.appointment = appointment
#
# self.helper = FormHelper()
# self.helper.layout = Layout(
# Fieldset(
# 'Confirmation Details',
# Row(
# Column('confirmation_method', css_class='form-group col-md-6 mb-0'),
# Column('contact_attempts', css_class='form-group col-md-6 mb-0'),
# css_class='form-row'
# ),
# 'confirmation_notes'
# ),
# Fieldset(
# 'Reschedule Request',
# HTML('<div class="form-check">'),
# 'reschedule_requested',
# HTML(
# '<label class="form-check-label" for="id_reschedule_requested">Patient requested reschedule</label>'),
# HTML('</div>'),
# Row(
# Column('new_preferred_date', css_class='form-group col-md-6 mb-0'),
# Column('new_preferred_time', css_class='form-group col-md-6 mb-0'),
# css_class='form-row'
# )
# ),
# FormActions(
# Submit('submit', 'Confirm Appointment', css_class='btn btn-primary'),
# HTML(
# '<a href="{% url \'appointments:appointment_detail\' appointment.id %}" class="btn btn-secondary">Cancel</a>')
# )
# )
#
# def clean(self):
# cleaned_data = super().clean()
# reschedule_requested = cleaned_data.get('reschedule_requested')
# new_preferred_date = cleaned_data.get('new_preferred_date')
# new_preferred_time = cleaned_data.get('new_preferred_time')
#
# if reschedule_requested:
# if not new_preferred_date:
# raise ValidationError('New preferred date is required when reschedule is requested.')
# if not new_preferred_time:
# raise ValidationError('New preferred time is required when reschedule is requested.')
#
# return cleaned_data
#
#
# class QueueManagementForm(forms.ModelForm):
# """
# Form for queue management
# """
# estimated_wait_time = forms.IntegerField(
# required=False,
# widget=forms.NumberInput(attrs={'class': 'form-control'})
# )
# priority_adjustment = forms.ChoiceField(
# choices=[
# ('none', 'No Change'),
# ('increase', 'Increase Priority'),
# ('decrease', 'Decrease Priority')
# ],
# required=False,
# widget=forms.Select(attrs={'class': 'form-control'})
# )
# queue_notes = forms.CharField(
# required=False,
# widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 3})
# )
# notify_patient = forms.BooleanField(
# required=False,
# initial=True,
# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
# )
#
# class Meta:
# model = Queue
# fields = [
# 'queue_type', 'priority', 'estimated_wait_time',
# 'priority_adjustment', 'queue_notes', 'notify_patient'
# ]
# widgets = {
# 'queue_type': forms.Select(attrs={'class': 'form-control'}),
# 'priority': forms.Select(attrs={'class': 'form-control'})
# }
#
# def __init__(self, *args, **kwargs):
# super().__init__(*args, **kwargs)
#
# self.helper = FormHelper()
# self.helper.layout = Layout(
# Fieldset(
# 'Queue Configuration',
# Row(
# Column('queue_type', css_class='form-group col-md-6 mb-0'),
# Column('priority', css_class='form-group col-md-6 mb-0'),
# css_class='form-row'
# ),
# Row(
# Column('estimated_wait_time', css_class='form-group col-md-6 mb-0'),
# Column('priority_adjustment', css_class='form-group col-md-6 mb-0'),
# css_class='form-row'
# ),
# 'queue_notes'
# ),
# Fieldset(
# 'Notifications',
# HTML('<div class="form-check">'),
# 'notify_patient',
# HTML('<label class="form-check-label" for="id_notify_patient">Notify patient of queue status</label>'),
# HTML('</div>')
# ),
# FormActions(
# Submit('submit', 'Update Queue', css_class='btn btn-primary'),
# HTML('<a href="{% url \'appointments:queue_list\' %}" class="btn btn-secondary">Cancel</a>')
# )
# )
#
#
# class TelemedicineSetupForm(forms.ModelForm):
# """
# Form for telemedicine session setup
# """
# platform = forms.ChoiceField(
# choices=[
# ('zoom', 'Zoom'),
# ('teams', 'Microsoft Teams'),
# ('webex', 'Cisco Webex'),
# ('meet', 'Google Meet'),
# ('custom', 'Custom Platform')
# ],
# required=True,
# widget=forms.Select(attrs={'class': 'form-control'})
# )
# test_connection = forms.BooleanField(
# required=False,
# initial=True,
# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
# )
# send_instructions = forms.BooleanField(
# required=False,
# initial=True,
# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
# )
# backup_phone = forms.CharField(
# required=False,
# widget=forms.TextInput(attrs={'class': 'form-control'})
# )
# technical_support_contact = forms.CharField(
# required=False,
# widget=forms.TextInput(attrs={'class': 'form-control'})
# )
# session_recording = forms.BooleanField(
# required=False,
# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
# )
#
# class Meta:
# model = TelemedicineSession
# fields = [
# 'platform', 'meeting_url', 'meeting_id', 'meeting_password',
# 'test_connection', 'send_instructions', 'backup_phone',
# 'technical_support_contact', 'session_recording'
# ]
# widgets = {
# 'meeting_url': forms.URLInput(attrs={'class': 'form-control'}),
# 'meeting_id': forms.TextInput(attrs={'class': 'form-control'}),
# 'meeting_password': forms.TextInput(attrs={'class': 'form-control'})
# }
#
# def __init__(self, *args, **kwargs):
# appointment = kwargs.pop('appointment', None)
# super().__init__(*args, **kwargs)
#
# self.appointment = appointment
#
# self.helper = FormHelper()
# self.helper.layout = Layout(
# Fieldset(
# 'Platform Configuration',
# 'platform',
# 'meeting_url',
# Row(
# Column('meeting_id', css_class='form-group col-md-6 mb-0'),
# Column('meeting_password', css_class='form-group col-md-6 mb-0'),
# css_class='form-row'
# )
# ),
# Fieldset(
# 'Support Information',
# Row(
# Column('backup_phone', css_class='form-group col-md-6 mb-0'),
# Column('technical_support_contact', css_class='form-group col-md-6 mb-0'),
# css_class='form-row'
# )
# ),
# Fieldset(
# 'Session Options',
# HTML('<div class="form-check">'),
# 'test_connection',
# HTML(
# '<label class="form-check-label" for="id_test_connection">Test connection before appointment</label>'),
# HTML('</div>'),
# HTML('<div class="form-check">'),
# 'send_instructions',
# HTML(
# '<label class="form-check-label" for="id_send_instructions">Send setup instructions to patient</label>'),
# HTML('</div>'),
# HTML('<div class="form-check">'),
# 'session_recording',
# HTML(
# '<label class="form-check-label" for="id_session_recording">Record session (with consent)</label>'),
# HTML('</div>')
# ),
# FormActions(
# Submit('submit', 'Setup Telemedicine', css_class='btn btn-primary'),
# HTML(
# '<a href="{% url \'appointments:appointment_detail\' appointment.id %}" class="btn btn-secondary">Cancel</a>')
# )
# )
#
# def clean_meeting_url(self):
# meeting_url = self.cleaned_data.get('meeting_url')
# platform = self.cleaned_data.get('platform')
#
# if platform and meeting_url:
# # Validate URL format based on platform
# if platform == 'zoom' and 'zoom.us' not in meeting_url:
# raise ValidationError('Invalid Zoom meeting URL format.')
# elif platform == 'teams' and 'teams.microsoft.com' not in meeting_url:
# raise ValidationError('Invalid Microsoft Teams meeting URL format.')
# elif platform == 'webex' and 'webex.com' not in meeting_url:
# raise ValidationError('Invalid Webex meeting URL format.')
# elif platform == 'meet' and 'meet.google.com' not in meeting_url:
# raise ValidationError('Invalid Google Meet URL format.')
#
# return meeting_url
#
#
# class AppointmentRescheduleForm(forms.Form):
# """
# Form for appointment rescheduling
# """
# new_date = forms.DateField(
# required=True,
# widget=forms.DateInput(attrs={'class': 'form-control', 'type': 'date'})
# )
# new_time = forms.TimeField(
# required=True,
# widget=forms.TimeInput(attrs={'class': 'form-control', 'type': 'time'})
# )
# new_provider = forms.ModelChoiceField(
# queryset=None,
# required=False,
# widget=forms.Select(attrs={'class': 'form-control'})
# )
# reschedule_reason = forms.ChoiceField(
# choices=[
# ('patient_request', 'Patient Request'),
# ('provider_unavailable', 'Provider Unavailable'),
# ('emergency', 'Emergency'),
# ('equipment_issue', 'Equipment Issue'),
# ('other', 'Other')
# ],
# required=True,
# widget=forms.Select(attrs={'class': 'form-control'})
# )
# notes = forms.CharField(
# required=False,
# widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 3})
# )
# notify_patient = forms.BooleanField(
# required=False,
# initial=True,
# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
# )
#
# def __init__(self, *args, **kwargs):
# tenant = kwargs.pop('tenant', None)
# appointment = kwargs.pop('appointment', None)
# super().__init__(*args, **kwargs)
#
# if tenant:
# self.fields['new_provider'].queryset = User.objects.filter(
# tenant=tenant,
# groups__name__in=['Doctors', 'Nurses', 'Specialists']
# )
#
# # Set minimum date to today
# self.fields['new_date'].widget.attrs['min'] = timezone.now().date().isoformat()
#
# self.helper = FormHelper()
# self.helper.layout = Layout(
# Fieldset(
# 'New Appointment Details',
# Row(
# Column('new_date', css_class='form-group col-md-6 mb-0'),
# Column('new_time', css_class='form-group col-md-6 mb-0'),
# css_class='form-row'
# ),
# 'new_provider'
# ),
# Fieldset(
# 'Reschedule Information',
# 'reschedule_reason',
# 'notes'
# ),
# Fieldset(
# 'Notifications',
# HTML('<div class="form-check">'),
# 'notify_patient',
# HTML('<label class="form-check-label" for="id_notify_patient">Notify patient of reschedule</label>'),
# HTML('</div>')
# ),
# FormActions(
# Submit('submit', 'Reschedule Appointment', css_class='btn btn-primary'),
# HTML(
# '<a href="{% url \'appointments:appointment_detail\' appointment.id %}" class="btn btn-secondary">Cancel</a>')
# )
# )
#
#
# class AppointmentCancellationForm(forms.Form):
# """
# Form for appointment cancellation
# """
# cancellation_reason = forms.ChoiceField(
# choices=[
# ('patient_request', 'Patient Request'),
# ('provider_unavailable', 'Provider Unavailable'),
# ('patient_no_show', 'Patient No Show'),
# ('emergency', 'Emergency'),
# ('equipment_failure', 'Equipment Failure'),
# ('other', 'Other')
# ],
# required=True,
# widget=forms.Select(attrs={'class': 'form-control'})
# )
# cancellation_notes = forms.CharField(
# required=False,
# widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 3})
# )
# offer_reschedule = forms.BooleanField(
# required=False,
# initial=True,
# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
# )
# notify_patient = forms.BooleanField(
# required=False,
# initial=True,
# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
# )
# refund_required = forms.BooleanField(
# required=False,
# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
# )
#
# def __init__(self, *args, **kwargs):
# super().__init__(*args, **kwargs)
#
# self.helper = FormHelper()
# self.helper.layout = Layout(
# Fieldset(
# 'Cancellation Details',
# 'cancellation_reason',
# 'cancellation_notes'
# ),
# Fieldset(
# 'Follow-up Actions',
# HTML('<div class="form-check">'),
# 'offer_reschedule',
# HTML(
# '<label class="form-check-label" for="id_offer_reschedule">Offer to reschedule appointment</label>'),
# HTML('</div>'),
# HTML('<div class="form-check">'),
# 'notify_patient',
# HTML('<label class="form-check-label" for="id_notify_patient">Notify patient of cancellation</label>'),
# HTML('</div>'),
# HTML('<div class="form-check">'),
# 'refund_required',
# HTML('<label class="form-check-label" for="id_refund_required">Refund required</label>'),
# HTML('</div>')
# ),
# FormActions(
# Submit('submit', 'Cancel Appointment', css_class='btn btn-danger'),
# HTML(
# '<a href="{% url \'appointments:appointment_detail\' appointment.id %}" class="btn btn-secondary">Back</a>')
# )
# )
#
#
# class AppointmentCheckInForm(forms.Form):
# """
# Form for appointment check-in
# """
# arrival_time = forms.TimeField(
# initial=timezone.now().time(),
# widget=forms.TimeInput(attrs={'class': 'form-control', 'type': 'time'})
# )
# insurance_verified = forms.BooleanField(
# required=False,
# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
# )
# copay_collected = forms.BooleanField(
# required=False,
# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
# )
# forms_completed = forms.BooleanField(
# required=False,
# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
# )
# vitals_required = forms.BooleanField(
# required=False,
# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
# )
# special_needs = forms.CharField(
# required=False,
# widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 2})
# )
#
# def __init__(self, *args, **kwargs):
# super().__init__(*args, **kwargs)
#
# self.helper = FormHelper()
# self.helper.layout = Layout(
# Fieldset(
# 'Check-in Information',
# 'arrival_time',
# 'special_needs'
# ),
# Fieldset(
# 'Pre-visit Tasks',
# HTML('<div class="form-check">'),
# 'insurance_verified',
# HTML('<label class="form-check-label" for="id_insurance_verified">Insurance verified</label>'),
# HTML('</div>'),
# HTML('<div class="form-check">'),
# 'copay_collected',
# HTML('<label class="form-check-label" for="id_copay_collected">Copay collected</label>'),
# HTML('</div>'),
# HTML('<div class="form-check">'),
# 'forms_completed',
# HTML('<label class="form-check-label" for="id_forms_completed">Forms completed</label>'),
# HTML('</div>'),
# HTML('<div class="form-check">'),
# 'vitals_required',
# HTML('<label class="form-check-label" for="id_vitals_required">Vitals required</label>'),
# HTML('</div>')
# ),
# FormActions(
# Submit('submit', 'Check In Patient', css_class='btn btn-primary'),
# HTML(
# '<a href="{% url \'appointments:appointment_detail\' appointment.id %}" class="btn btn-secondary">Cancel</a>')
# )
# )
#
#
# class BulkAppointmentForm(forms.Form):
# """
# Form for bulk appointment operations
# """
# action = forms.ChoiceField(
# choices=[
# ('confirm', 'Confirm Appointments'),
# ('reschedule', 'Reschedule Appointments'),
# ('cancel', 'Cancel Appointments'),
# ('send_reminders', 'Send Reminders')
# ],
# required=True,
# widget=forms.Select(attrs={'class': 'form-control'})
# )
# appointment_ids = forms.CharField(
# widget=forms.HiddenInput()
# )
# bulk_date = forms.DateField(
# required=False,
# widget=forms.DateInput(attrs={'class': 'form-control', 'type': 'date'})
# )
# bulk_reason = forms.CharField(
# required=False,
# widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 3})
# )
# notify_patients = forms.BooleanField(
# required=False,
# initial=True,
# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
# )
#
# def __init__(self, *args, **kwargs):
# super().__init__(*args, **kwargs)
#
# self.helper = FormHelper()
# self.helper.layout = Layout(
# 'appointment_ids',
# Fieldset(
# 'Bulk Operation',
# 'action',
# 'bulk_date',
# 'bulk_reason'
# ),
# Fieldset(
# 'Notifications',
# HTML('<div class="form-check">'),
# 'notify_patients',
# HTML('<label class="form-check-label" for="id_notify_patients">Notify patients</label>'),
# HTML('</div>')
# ),
# FormActions(
# Submit('submit', 'Execute Bulk Operation', css_class='btn btn-primary'),
# HTML('<a href="{% url \'appointments:appointment_list\' %}" class="btn btn-secondary">Cancel</a>')
# )
# )
#