257 lines
8.3 KiB
Python
257 lines
8.3 KiB
Python
"""
|
|
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
|
|
)
|