""" References forms - Forms for Reference Section """ from django import forms from django.utils.translation import gettext_lazy as _ from apps.references.models import ReferenceFolder, ReferenceDocument class ReferenceFolderForm(forms.ModelForm): """Form for creating and editing reference folders""" class Meta: model = ReferenceFolder fields = [ 'name', 'name_ar', 'description', 'description_ar', 'parent', 'icon', 'color', 'order', 'access_roles', 'is_active' ] widgets = { 'name': forms.TextInput(attrs={ 'class': 'form-control', 'placeholder': _('Enter folder name (English)') }), 'name_ar': forms.TextInput(attrs={ 'class': 'form-control', 'placeholder': _('Enter folder name (Arabic)') }), 'description': forms.Textarea(attrs={ 'class': 'form-control', 'rows': 3, 'placeholder': _('Enter folder description (English)') }), 'description_ar': forms.Textarea(attrs={ 'class': 'form-control', 'rows': 3, 'placeholder': _('Enter folder description (Arabic)') }), 'parent': forms.Select(attrs={ 'class': 'form-select' }), 'icon': forms.TextInput(attrs={ 'class': 'form-control', 'placeholder': _('e.g., fa-folder, fa-file-pdf') }), 'color': forms.TextInput(attrs={ 'class': 'form-control', 'placeholder': _('e.g., #007bff') }), 'order': forms.NumberInput(attrs={ 'class': 'form-control', 'min': 0 }), 'access_roles': forms.CheckboxSelectMultiple(), 'is_active': forms.CheckboxInput(attrs={ 'class': 'form-check-input' }) } def __init__(self, *args, **kwargs): hospital = kwargs.pop('hospital', None) super().__init__(*args, **kwargs) # Filter parent folders by hospital if hospital: self.fields['parent'].queryset = ReferenceFolder.objects.filter( hospital=hospital, is_deleted=False ) # Filter access roles if hospital: from django.contrib.auth.models import Group self.fields['access_roles'].queryset = Group.objects.all() def clean_name(self): """Ensure name is provided in at least one language""" name = self.cleaned_data.get('name', '') name_ar = self.cleaned_data.get('name_ar', '') if not name and not name_ar: raise forms.ValidationError(_('Please provide a name in English or Arabic.')) return name class ReferenceDocumentForm(forms.ModelForm): """Form for uploading and editing reference documents""" new_version = forms.BooleanField( required=False, label=_('Upload as new version'), help_text=_('Check this to create a new version of an existing document') ) class Meta: model = ReferenceDocument fields = [ 'folder', 'title', 'title_ar', 'file', 'description', 'description_ar', 'access_roles', 'is_published', 'tags' ] widgets = { 'folder': forms.Select(attrs={ 'class': 'form-select' }), 'title': forms.TextInput(attrs={ 'class': 'form-control', 'placeholder': _('Enter document title (English)') }), 'title_ar': forms.TextInput(attrs={ 'class': 'form-control', 'placeholder': _('Enter document title (Arabic)') }), 'file': forms.FileInput(attrs={ 'class': 'form-control' }), 'description': forms.Textarea(attrs={ 'class': 'form-control', 'rows': 4, 'placeholder': _('Enter document description (English)') }), 'description_ar': forms.Textarea(attrs={ 'class': 'form-control', 'rows': 4, 'placeholder': _('Enter document description (Arabic)') }), 'access_roles': forms.CheckboxSelectMultiple(), 'is_published': forms.CheckboxInput(attrs={ 'class': 'form-check-input' }), 'tags': forms.TextInput(attrs={ 'class': 'form-control', 'placeholder': _('e.g., policy, procedure, handbook (comma-separated)') }) } def __init__(self, *args, **kwargs): hospital = kwargs.pop('hospital', None) folder = kwargs.pop('folder', None) super().__init__(*args, **kwargs) # Filter folders by hospital if hospital: self.fields['folder'].queryset = ReferenceFolder.objects.filter( hospital=hospital, is_active=True, is_deleted=False ) # Filter access roles if hospital: from django.contrib.auth.models import Group self.fields['access_roles'].queryset = Group.objects.all() # Make file required for new documents, optional for updates if self.instance and self.instance.pk: self.fields['file'].required = False else: self.fields['file'].required = True # Make folder optional when uploading from within a folder if folder: self.fields['folder'].required = False self.fields['folder'].initial = folder def clean_title(self): """Ensure title is provided in at least one language""" title = self.cleaned_data.get('title', '') title_ar = self.cleaned_data.get('title_ar', '') if not title and not title_ar: raise forms.ValidationError(_('Please provide a title in English or Arabic.')) return title def clean(self): """Custom validation for new version creation""" cleaned_data = super().clean() new_version = cleaned_data.get('new_version') file = cleaned_data.get('file') # If uploading as new version, file is required if new_version and not file and not (self.instance and self.instance.pk and self.instance.file): raise forms.ValidationError({ 'file': _('File is required when uploading a new version.') }) return cleaned_data class ReferenceDocumentSearchForm(forms.Form): """Form for searching and filtering documents""" search = forms.CharField( required=False, label=_('Search'), widget=forms.TextInput(attrs={ 'class': 'form-control', 'placeholder': _('Search by title, description, or tags...') }) ) folder = forms.ModelChoiceField( required=False, label=_('Folder'), queryset=ReferenceFolder.objects.none(), widget=forms.Select(attrs={ 'class': 'form-select' }) ) file_type = forms.ChoiceField( required=False, label=_('File Type'), choices=[ ('', _('All Types')), ('pdf', 'PDF'), ('doc', 'Word'), ('docx', 'Word'), ('xls', 'Excel'), ('xlsx', 'Excel'), ('ppt', 'PowerPoint'), ('pptx', 'PowerPoint'), ('jpg', 'Image'), ('jpeg', 'Image'), ('png', 'Image'), ('gif', 'Image'), ], widget=forms.Select(attrs={ 'class': 'form-select' }) ) tags = forms.CharField( required=False, label=_('Tags'), widget=forms.TextInput(attrs={ 'class': 'form-control', 'placeholder': _('Filter by tags...') }) ) def __init__(self, *args, **kwargs): hospital = kwargs.pop('hospital', None) super().__init__(*args, **kwargs) # Filter folders by hospital if hospital: self.fields['folder'].queryset = ReferenceFolder.objects.filter( hospital=hospital, is_active=True, is_deleted=False )