172 lines
6.7 KiB
Python
172 lines
6.7 KiB
Python
"""
|
|
Organizations forms - Patient, Staff, Department management
|
|
"""
|
|
from django import forms
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
from apps.organizations.models import Patient, Staff, Department, Hospital
|
|
|
|
|
|
class PatientForm(forms.ModelForm):
|
|
"""Form for creating and editing patients"""
|
|
|
|
class Meta:
|
|
model = Patient
|
|
fields = [
|
|
'mrn', 'first_name', 'last_name', 'first_name_ar', 'last_name_ar',
|
|
'national_id', 'date_of_birth', 'gender',
|
|
'phone', 'email', 'address', 'city',
|
|
'primary_hospital', 'status'
|
|
]
|
|
widgets = {
|
|
'mrn': forms.TextInput(attrs={
|
|
'class': 'form-control',
|
|
'placeholder': 'e.g., PTN-20240101-123456'
|
|
}),
|
|
'first_name': forms.TextInput(attrs={
|
|
'class': 'form-control',
|
|
'placeholder': 'First name in English'
|
|
}),
|
|
'last_name': forms.TextInput(attrs={
|
|
'class': 'form-control',
|
|
'placeholder': 'Last name in English'
|
|
}),
|
|
'first_name_ar': forms.TextInput(attrs={
|
|
'class': 'form-control',
|
|
'placeholder': 'الاسم الأول',
|
|
'dir': 'rtl'
|
|
}),
|
|
'last_name_ar': forms.TextInput(attrs={
|
|
'class': 'form-control',
|
|
'placeholder': 'اسم العائلة',
|
|
'dir': 'rtl'
|
|
}),
|
|
'national_id': forms.TextInput(attrs={
|
|
'class': 'form-control',
|
|
'placeholder': 'National ID / Iqama number'
|
|
}),
|
|
'date_of_birth': forms.DateInput(attrs={
|
|
'class': 'form-control',
|
|
'type': 'date'
|
|
}),
|
|
'gender': forms.Select(attrs={
|
|
'class': 'form-select'
|
|
}),
|
|
'phone': forms.TextInput(attrs={
|
|
'class': 'form-control',
|
|
'placeholder': '+966501234567'
|
|
}),
|
|
'email': forms.EmailInput(attrs={
|
|
'class': 'form-control',
|
|
'placeholder': 'patient@example.com'
|
|
}),
|
|
'address': forms.Textarea(attrs={
|
|
'class': 'form-control',
|
|
'rows': 2,
|
|
'placeholder': 'Street address'
|
|
}),
|
|
'city': forms.TextInput(attrs={
|
|
'class': 'form-control',
|
|
'placeholder': 'City'
|
|
}),
|
|
'primary_hospital': forms.Select(attrs={
|
|
'class': 'form-select'
|
|
}),
|
|
'status': forms.Select(attrs={
|
|
'class': 'form-select'
|
|
}),
|
|
}
|
|
|
|
def __init__(self, user, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.user = user
|
|
|
|
# Filter hospital choices based on user permissions
|
|
if user.hospital and not user.is_px_admin():
|
|
self.fields['primary_hospital'].queryset = Hospital.objects.filter(
|
|
id=user.hospital.id,
|
|
status='active'
|
|
)
|
|
self.fields['primary_hospital'].initial = user.hospital
|
|
else:
|
|
self.fields['primary_hospital'].queryset = Hospital.objects.filter(status='active')
|
|
|
|
# Make MRN optional for creation (will auto-generate if empty)
|
|
if not self.instance.pk:
|
|
self.fields['mrn'].required = False
|
|
self.fields['mrn'].help_text = _('Leave blank to auto-generate')
|
|
|
|
def clean_mrn(self):
|
|
"""Validate MRN is unique"""
|
|
mrn = self.cleaned_data.get('mrn')
|
|
if not mrn:
|
|
return mrn
|
|
|
|
# Check uniqueness (excluding current instance)
|
|
queryset = Patient.objects.filter(mrn=mrn)
|
|
if self.instance.pk:
|
|
queryset = queryset.exclude(pk=self.instance.pk)
|
|
|
|
if queryset.exists():
|
|
raise forms.ValidationError(_('A patient with this MRN already exists.'))
|
|
|
|
return mrn
|
|
|
|
def clean_phone(self):
|
|
"""Normalize phone number"""
|
|
phone = self.cleaned_data.get('phone', '')
|
|
if phone:
|
|
# Remove spaces and dashes
|
|
phone = phone.replace(' ', '').replace('-', '')
|
|
return phone
|
|
|
|
def save(self, commit=True):
|
|
"""Auto-generate MRN if not provided"""
|
|
instance = super().save(commit=False)
|
|
|
|
if not instance.mrn:
|
|
instance.mrn = Patient.generate_mrn()
|
|
|
|
if commit:
|
|
instance.save()
|
|
|
|
return instance
|
|
|
|
|
|
class StaffForm(forms.ModelForm):
|
|
"""Form for creating and editing staff"""
|
|
|
|
class Meta:
|
|
model = Staff
|
|
fields = [
|
|
'employee_id', 'first_name', 'last_name', 'first_name_ar', 'last_name_ar',
|
|
'name', 'name_ar', 'staff_type', 'job_title', 'job_title_ar',
|
|
'specialization', 'license_number', 'email', 'phone',
|
|
'hospital', 'department', 'section_fk', 'subsection_fk',
|
|
'report_to', 'is_head', 'gender', 'status'
|
|
]
|
|
widgets = {
|
|
'employee_id': forms.TextInput(attrs={'class': 'form-control'}),
|
|
'first_name': forms.TextInput(attrs={'class': 'form-control'}),
|
|
'last_name': forms.TextInput(attrs={'class': 'form-control'}),
|
|
'first_name_ar': forms.TextInput(attrs={'class': 'form-control', 'dir': 'rtl'}),
|
|
'last_name_ar': forms.TextInput(attrs={'class': 'form-control', 'dir': 'rtl'}),
|
|
'name': forms.TextInput(attrs={'class': 'form-control'}),
|
|
'name_ar': forms.TextInput(attrs={'class': 'form-control', 'dir': 'rtl'}),
|
|
'staff_type': forms.Select(attrs={'class': 'form-select'}),
|
|
'job_title': forms.TextInput(attrs={'class': 'form-control'}),
|
|
'job_title_ar': forms.TextInput(attrs={'class': 'form-control', 'dir': 'rtl'}),
|
|
'specialization': forms.TextInput(attrs={'class': 'form-control'}),
|
|
'license_number': forms.TextInput(attrs={'class': 'form-control'}),
|
|
'email': forms.EmailInput(attrs={'class': 'form-control'}),
|
|
'phone': forms.TextInput(attrs={'class': 'form-control'}),
|
|
'hospital': forms.Select(attrs={'class': 'form-select'}),
|
|
'department': forms.Select(attrs={'class': 'form-select'}),
|
|
'section_fk': forms.Select(attrs={'class': 'form-select'}),
|
|
'subsection_fk': forms.Select(attrs={'class': 'form-select'}),
|
|
'report_to': forms.Select(attrs={'class': 'form-select'}),
|
|
'is_head': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
|
|
'gender': forms.Select(attrs={'class': 'form-select'}),
|
|
'status': forms.Select(attrs={'class': 'form-select'}),
|
|
}
|