""" Survey forms for CRUD operations """ from django import forms from django.utils.translation import gettext_lazy as _ from apps.organizations.models import Patient, Staff, Hospital from .models import SurveyInstance, SurveyTemplate, SurveyQuestion class SurveyTemplateForm(forms.ModelForm): """Form for creating/editing survey templates""" class Meta: model = SurveyTemplate fields = [ 'name', 'name_ar', 'hospital', 'survey_type', 'scoring_method', 'negative_threshold', 'is_active' ] widgets = { 'name': forms.TextInput(attrs={ 'class': 'form-control', 'placeholder': 'e.g., MD Consultation Feedback' }), 'name_ar': forms.TextInput(attrs={ 'class': 'form-control', 'placeholder': 'الاسم بالعربية' }), 'hospital': forms.Select(attrs={'class': 'form-select'}), 'survey_type': forms.Select(attrs={'class': 'form-select'}), 'scoring_method': forms.Select(attrs={'class': 'form-select'}), 'negative_threshold': forms.NumberInput(attrs={ 'class': 'form-control', 'step': '0.1', 'min': '1', 'max': '5' }), 'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'}), } class SurveyQuestionForm(forms.ModelForm): """Form for creating/editing survey questions""" class Meta: model = SurveyQuestion fields = [ 'text', 'text_ar', 'question_type', 'order', 'is_required', 'choices_json' ] widgets = { 'text': forms.Textarea(attrs={ 'class': 'form-control', 'rows': 2, 'placeholder': 'Enter question in English' }), 'text_ar': forms.Textarea(attrs={ 'class': 'form-control', 'rows': 2, 'placeholder': 'أدخل السؤال بالعربية' }), 'question_type': forms.Select(attrs={'class': 'form-select'}), 'order': forms.NumberInput(attrs={ 'class': 'form-control', 'min': '0' }), 'is_required': forms.CheckboxInput(attrs={'class': 'form-check-input'}), 'choices_json': forms.Textarea(attrs={ 'class': 'form-control', 'rows': 5, 'placeholder': '[{"value": "1", "label": "Option 1", "label_ar": "خيار 1"}]' }), } def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields['choices_json'].required = False self.fields['choices_json'].help_text = _( 'JSON array of choices for multiple choice questions. ' 'Format: [{"value": "1", "label": "Option 1", "label_ar": "خيار 1"}]' ) SurveyQuestionFormSet = forms.inlineformset_factory( SurveyTemplate, SurveyQuestion, form=SurveyQuestionForm, extra=1, can_delete=True, min_num=1, validate_min=True ) class ManualSurveySendForm(forms.Form): """Form for manually sending surveys to patients or staff""" RECIPIENT_TYPE_CHOICES = [ ('patient', _('Patient')), ('staff', _('Staff')), ] DELIVERY_CHANNEL_CHOICES = [ ('email', _('Email')), ('sms', _('SMS')), ] def __init__(self, user, *args, **kwargs): super().__init__(*args, **kwargs) self.user = user # Filter survey templates by user's hospital if user.hospital: self.fields['survey_template'].queryset = SurveyTemplate.objects.filter( hospital=user.hospital, is_active=True ) survey_template = forms.ModelChoiceField( queryset=SurveyTemplate.objects.filter(is_active=True), label=_('Survey Template'), widget=forms.Select(attrs={ 'class': 'form-select', 'data-placeholder': _('Select a survey template') }) ) recipient_type = forms.ChoiceField( choices=RECIPIENT_TYPE_CHOICES, label=_('Recipient Type'), widget=forms.RadioSelect(attrs={ 'class': 'form-check-input' }) ) recipient = forms.CharField( label=_('Recipient'), widget=forms.TextInput(attrs={ 'class': 'form-control', 'placeholder': _('Search by name or ID...'), 'data-search-url': '/api/recipients/search/' }), help_text=_('Start typing to search for patient or staff') ) delivery_channel = forms.ChoiceField( choices=DELIVERY_CHANNEL_CHOICES, label=_('Delivery Channel'), widget=forms.Select(attrs={ 'class': 'form-select' }) ) custom_message = forms.CharField( label=_('Custom Message (Optional)'), required=False, widget=forms.Textarea(attrs={ 'class': 'form-control', 'rows': 3, 'placeholder': _('Add a custom message to the survey invitation...') }) ) class ManualPhoneSurveySendForm(forms.Form): """Form for sending surveys to a manually entered phone number""" def __init__(self, user, *args, **kwargs): super().__init__(*args, **kwargs) self.user = user # Filter survey templates by user's hospital if user.hospital: self.fields['survey_template'].queryset = SurveyTemplate.objects.filter( hospital=user.hospital, is_active=True ) survey_template = forms.ModelChoiceField( queryset=SurveyTemplate.objects.filter(is_active=True), label=_('Survey Template'), widget=forms.Select(attrs={ 'class': 'form-select' }) ) phone_number = forms.CharField( label=_('Phone Number'), widget=forms.TextInput(attrs={ 'class': 'form-control', 'placeholder': _('+966501234567') }), help_text=_('Enter phone number with country code (e.g., +966...)') ) recipient_name = forms.CharField( label=_('Recipient Name (Optional)'), required=False, widget=forms.TextInput(attrs={ 'class': 'form-control', 'placeholder': _('Patient Name') }) ) custom_message = forms.CharField( label=_('Custom Message (Optional)'), required=False, widget=forms.Textarea(attrs={ 'class': 'form-control', 'rows': 3, 'placeholder': _('Add a custom message to the survey invitation...') }) ) def clean_phone_number(self): phone = self.cleaned_data['phone_number'].strip() # Remove spaces, dashes, parentheses phone = phone.replace(' ', '').replace('-', '').replace('(', '').replace(')', '') if not phone.startswith('+'): raise forms.ValidationError(_('Phone number must start with country code (e.g., +966)')) return phone class BulkCSVSurveySendForm(forms.Form): """Form for bulk sending surveys via CSV upload""" survey_template = forms.ModelChoiceField( queryset=SurveyTemplate.objects.filter(is_active=True), label=_('Survey Template'), widget=forms.Select(attrs={ 'class': 'form-select' }) ) csv_file = forms.FileField( label=_('CSV File'), widget=forms.FileInput(attrs={ 'class': 'form-control', 'accept': '.csv' }), help_text=_('Upload CSV with phone numbers. Format: phone_number,name(optional)') ) custom_message = forms.CharField( label=_('Custom Message (Optional)'), required=False, widget=forms.Textarea(attrs={ 'class': 'form-control', 'rows': 3, 'placeholder': _('Add a custom message to the survey invitation...') }) ) def __init__(self, user, *args, **kwargs): super().__init__(*args, **kwargs) self.user = user # Filter survey templates by user's hospital if user.hospital: self.fields['survey_template'].queryset = SurveyTemplate.objects.filter( hospital=user.hospital, is_active=True ) class HISPatientImportForm(forms.Form): """Form for importing patient data from HIS/MOH Statistics CSV""" hospital = forms.ModelChoiceField( queryset=Hospital.objects.filter(status='active'), label=_('Hospital'), widget=forms.Select(attrs={ 'class': 'form-select' }), help_text=_('Select the hospital for these patient records') ) csv_file = forms.FileField( label=_('HIS Statistics CSV File'), widget=forms.FileInput(attrs={ 'class': 'form-control', 'accept': '.csv' }), help_text=_('Upload MOH Statistics CSV with patient visit data') ) skip_header_rows = forms.IntegerField( label=_('Skip Header Rows'), initial=5, min_value=0, max_value=10, widget=forms.NumberInput(attrs={ 'class': 'form-control' }), help_text=_('Number of metadata/header rows to skip before data rows') ) def __init__(self, user, *args, **kwargs): super().__init__(*args, **kwargs) self.user = user # Filter hospitals by user's access if user.hospital and not user.is_px_admin(): self.fields['hospital'].queryset = Hospital.objects.filter( id=user.hospital.id, status='active' ) class HISSurveySendForm(forms.Form): """Form for sending surveys to imported HIS patients""" survey_template = forms.ModelChoiceField( queryset=SurveyTemplate.objects.filter(is_active=True), label=_('Survey Template'), widget=forms.Select(attrs={ 'class': 'form-select' }) ) delivery_channel = forms.ChoiceField( choices=[ ('sms', _('SMS')), ('email', _('Email')), ('both', _('Both SMS and Email')), ], label=_('Delivery Channel'), initial='sms', widget=forms.Select(attrs={ 'class': 'form-select' }) ) custom_message = forms.CharField( label=_('Custom Message (Optional)'), required=False, widget=forms.Textarea(attrs={ 'class': 'form-control', 'rows': 3, 'placeholder': _('Add a custom message to the survey invitation...') }) ) patient_ids = forms.CharField( widget=forms.HiddenInput(), required=True ) def __init__(self, user, *args, **kwargs): super().__init__(*args, **kwargs) self.user = user if user.hospital: self.fields['survey_template'].queryset = SurveyTemplate.objects.filter( hospital=user.hospital, is_active=True )