from datetime import datetime from django import forms from django.forms import ModelForm, Form from django.utils.dates import MONTHS from models import Subject, Worker, Appointment, Visit, AppointmentType from models.constants import SUBJECT_TYPE_CHOICES """ Possible redundancy, but if need arises, contents of forms can be easily customized """ CURRENT_YEAR = datetime.now().year YEAR_CHOICES = tuple(range(CURRENT_YEAR, CURRENT_YEAR - 120, -1)) FUTURE_YEAR_CHOICES = tuple(range(CURRENT_YEAR, CURRENT_YEAR + 5, 1)) DATEPICKER_DATE_ATTRS = { 'class': 'datepicker', 'data-date-format': 'yyyy-mm-dd', 'data-date-orientation': 'bottom' } DATETIMEPICKER_DATE_ATTRS = { 'class': 'datetimepicker', 'data-date-format': 'Y-MM-DD HH:mm', } START_YEAR_STATISTICS = 2015 def validate_subject_nd_number(self): subject = self.cleaned_data if subject['nd_number'] != "": subjects_from_db = Subject.objects.filter(nd_number=subject['nd_number']) if subjects_from_db: if subjects_from_db[0].screening_number != subject.get('screening_number', ''): self.add_error('nd_number', "ND number already in use") class SubjectAddForm(ModelForm): date_born = forms.DateField(label="Date of birth", widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d"), required=False ) datetime_contact_reminder = forms.DateField(label="Contact on", widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d"), required=False ) class Meta: model = Subject fields = '__all__' def clean(self): subject = self.cleaned_data subjects_from_db = Subject.objects.filter(screening_number=subject.get('screening_number', '')) if len(subjects_from_db) > 0: self.add_error('screening_number', "Screening number already in use") validate_subject_nd_number(self) class SubjectDetailForm(ModelForm): class Meta: model = Subject fields = '__all__' class SubjectEditForm(ModelForm): datetime_contact_reminder = forms.DateField(label="Contact on", widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d"), required=False ) date_born = forms.DateField(label="Date of birth", widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d"), required=False ) def __init__(self, *args, **kwargs): super(SubjectEditForm, self).__init__(*args, **kwargs) instance = getattr(self, 'instance', None) if instance and instance.id: self.fields['screening_number'].widget.attrs['readonly'] = True def clean_screening_number(self): instance = getattr(self, 'instance', None) if instance and instance.id: return instance.screening_number else: return self.cleaned_data['screening_number'] def clean(self): validate_subject_nd_number(self) class Meta: model = Subject fields = '__all__' class WorkerAddForm(ModelForm): class Meta: model = Worker exclude = ['appointments'] class WorkerDetailForm(ModelForm): class Meta: model = Worker fields = '__all__' class WorkerEditForm(ModelForm): class Meta: model = Worker fields = '__all__' class AppointmentDetailForm(ModelForm): class Meta: model = Appointment fields = '__all__' datetime_when = forms.DateTimeField(label='Appointment on (YYYY-MM-DD HH:MM)', widget=forms.DateTimeInput(DATETIMEPICKER_DATE_ATTRS) ) class AppointmentEditForm(ModelForm): class Meta: model = Appointment fields = '__all__' datetime_when = forms.DateTimeField(label='Appointment on (YYYY-MM-DD HH:MM)', widget=forms.DateTimeInput(DATETIMEPICKER_DATE_ATTRS) ) appointment_types = forms.ModelMultipleChoiceField(required=False, widget=forms.CheckboxSelectMultiple, queryset=AppointmentType.objects.all()) def __init__(self, *args, **kwargs): user = kwargs.pop('user', None) if user is None: raise TypeError("User not defined") self.user = Worker.get_by_user(user) if self.user is None: raise TypeError("Worker not defined for: " + user.username) super(ModelForm, self).__init__(*args, **kwargs) def clean_location(self): location = self.cleaned_data['location'] if self.user.locations.filter(id=location.id).count() == 0: self.add_error('location', "You cannot create appointment for this location") else: return location class AppointmentAddForm(ModelForm): class Meta: model = Appointment exclude = ['status'] datetime_when = forms.DateTimeField(label='Appointment on (YYYY-MM-DD HH:MM)', widget=forms.DateTimeInput(DATETIMEPICKER_DATE_ATTRS) ) appointment_types = forms.ModelMultipleChoiceField(required=False, widget=forms.CheckboxSelectMultiple, queryset=AppointmentType.objects.all()) def __init__(self, *args, **kwargs): user = kwargs.pop('user', None) if user is None: raise TypeError("User not defined") self.user = Worker.get_by_user(user) if self.user is None: raise TypeError("Worker not defined for: " + user.username) super(ModelForm, self).__init__(*args, **kwargs) def clean_location(self): location = self.cleaned_data['location'] if self.user.locations.filter(id=location.id).count() == 0: self.add_error('location', "You cannot create appointment for this location") else: return location class VisitDetailForm(ModelForm): datetime_begin = forms.DateField(label="Visit begins on", widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d") ) datetime_end = forms.DateField(label="Visit ends on", widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d") ) post_mail_sent = forms.RadioSelect() appointment_types = forms.ModelMultipleChoiceField(required=False, widget=forms.CheckboxSelectMultiple, queryset=AppointmentType.objects.all()) class Meta: model = Visit exclude = ['is_finished'] class VisitAddForm(ModelForm): subject = forms.ModelChoiceField(queryset=Subject.objects.order_by('last_name', 'first_name')) datetime_begin = forms.DateField(label="Visit begins on", widget=forms.TextInput(attrs=DATEPICKER_DATE_ATTRS) ) datetime_end = forms.DateField(label="Visit ends on", widget=forms.TextInput(attrs=DATEPICKER_DATE_ATTRS) ) appointment_types = forms.ModelMultipleChoiceField(required=False, widget=forms.CheckboxSelectMultiple, queryset=AppointmentType.objects.all()) class Meta: model = Visit exclude = ['is_finished'] def clean(self): if self.cleaned_data['datetime_begin'] >= self.cleaned_data['datetime_end']: self.add_error('datetime_begin', "Start date must be before end date") self.add_error('datetime_end', "Start date must be before end date") class KitRequestForm(Form): start_date = forms.DateField(label="From date", widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d"), required=False ) end_date = forms.DateField(label="End date", widget=forms.DateInput(DATEPICKER_DATE_ATTRS, "%Y-%m-%d"), required=False ) class StatisticsForm(Form): def __init__(self, *args, **kwargs): super(StatisticsForm, self).__init__(*args) visit_choices = kwargs['visit_choices'] month = kwargs['month'] year = kwargs['year'] now = datetime.now() year_now = now.year number_of_years_for_statistics = year_now - START_YEAR_STATISTICS + 2 year_choices = [(START_YEAR_STATISTICS + i, START_YEAR_STATISTICS + i) for i in range(0, number_of_years_for_statistics + 1)] self.fields['month'] = forms.ChoiceField(choices=MONTHS.items(), initial=month) self.fields['year'] = forms.ChoiceField(choices=year_choices, initial=year) choices = [(-1, "all")] choices.extend(SUBJECT_TYPE_CHOICES.items()) self.fields['subject_type'] = forms.ChoiceField(choices=choices, initial="-1") self.fields['visit'] = forms.ChoiceField(choices=visit_choices, initial="-1")