-
Carlos Vega authoredCarlos Vega authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
forms.py 9.17 KiB
import datetime
import logging
from django import forms
from django.forms import ModelForm, Form
from django.utils.dates import MONTHS
from web.models import Appointment, AppointmentType, AppointmentTypeLink, \
Availability, ContactAttempt, FlyingTeam, Holiday, Item, \
StudySubject, Room, Worker, Visit, VoucherType, VoucherTypePrice
from web.models.constants import SUBJECT_TYPE_CHOICES
"""
Possible redundancy, but if need arises, contents of forms can be easily customized
"""
DATE_FORMAT_TIME = "%H:%M"
CURRENT_YEAR = datetime.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',
}
TIMEPICKER_DATE_ATTRS = {
'class': 'datetimepicker',
'data-date-format': 'HH:mm',
'data-date-stepping': 15,
}
START_YEAR_STATISTICS = 2015
APPOINTMENT_TYPES_FIELD_POSITION = 1
logger = logging.getLogger(__name__)
def get_worker_from_args(kwargs):
user = kwargs.pop('user', None)
if user is None:
raise TypeError("User not defined")
result = Worker.get_by_user(user)
if result is None:
raise TypeError("Worker not defined for: " + user.username)
return result
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', 'visit_number']
class VisitAddForm(ModelForm):
subject = forms.ModelChoiceField(
queryset=StudySubject.objects.order_by('subject__last_name', 'subject__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', 'visit_number']
def clean(self):
super(VisitAddForm, self).clean()
if 'datetime_begin' not in self.cleaned_data or 'datetime_end' not in self.cleaned_data:
return
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', "End date must be after start 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.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")
class AvailabilityAddForm(ModelForm):
def __init__(self, *args, **kwargs):
super(AvailabilityAddForm, self).__init__(*args, **kwargs)
self.fields['person'].widget.attrs['readonly'] = True
available_from = forms.TimeField(label="Available from",
widget=forms.TimeInput(TIMEPICKER_DATE_ATTRS),
initial="8:00",
)
available_till = forms.TimeField(label="Available until",
widget=forms.TimeInput(TIMEPICKER_DATE_ATTRS),
initial="17:00",
)
class Meta:
model = Availability
fields = '__all__'
def clean(self):
worker = Worker.objects.get(id=self.cleaned_data["person"].id)
availabilities = worker.availability_set.all()
for availability in availabilities:
validate_availability_conflict(self, self.cleaned_data, availability)
class AvailabilityEditForm(ModelForm):
available_from = forms.TimeField(label="Available from",
widget=forms.TimeInput(TIMEPICKER_DATE_ATTRS),
)
available_till = forms.TimeField(label="Available until",
widget=forms.TimeInput(TIMEPICKER_DATE_ATTRS),
)
class Meta:
model = Availability
fields = '__all__'
def __init__(self, *args, **kwargs):
super(ModelForm, self).__init__(*args, **kwargs)
instance = getattr(self, 'instance', None)
if instance is not None:
self.availability_id = instance.id
self.fields['person'].disabled = True
def clean(self):
worker = Worker.objects.get(id=self.cleaned_data["person"].id)
availabilities = worker.availability_set.all()
for availability in availabilities:
if availability.id != self.availability_id:
validate_availability_conflict(self, self.cleaned_data, availability)
def validate_availability_conflict(self, cleaned_data, availability):
start_hour = self.cleaned_data.get("available_from", None)
end_hour = self.cleaned_data.get("available_till", None)
if availability.day_number == self.cleaned_data.get("day_number", None) and \
((start_hour <= availability.available_from < end_hour) or
(start_hour < availability.available_till <= end_hour) or
(availability.available_from <= start_hour < availability.available_till) or
(availability.available_from < end_hour <= availability.available_till)):
error = "User has defined availability for this day that overlaps: " + availability.available_from.strftime(
DATE_FORMAT_TIME) + ", " + availability.available_till.strftime(DATE_FORMAT_TIME)
self.add_error('day_number', error)
self.add_error('available_from', error)
self.add_error('available_till', error)
class ItemForm(ModelForm):
class Meta:
model = Item
fields = "__all__"
class FlyingTeamAddForm(ModelForm):
class Meta:
model = FlyingTeam
fields = "__all__"
class FlyingTeamEditForm(ModelForm):
class Meta:
model = FlyingTeam
fields = "__all__"
class HolidayAddForm(ModelForm):
def __init__(self, *args, **kwargs):
super(HolidayAddForm, self).__init__(*args, **kwargs)
self.fields['person'].widget.attrs['readonly'] = True
datetime_start = forms.DateTimeField(widget=forms.DateTimeInput(DATETIMEPICKER_DATE_ATTRS),
initial=datetime.datetime.now().replace(hour=8, minute=0),
)
datetime_end = forms.DateTimeField(widget=forms.DateTimeInput(DATETIMEPICKER_DATE_ATTRS),
initial=datetime.datetime.now().replace(hour=17, minute=0),
)
class Meta:
model = Holiday
fields = '__all__'
def clean(self):
worker = Worker.objects.get(id=self.cleaned_data["person"].id)
availabilities = worker.availability_set.all()
for availability in availabilities:
validate_availability_conflict(self, self.cleaned_data, availability)
class RoomForm(ModelForm):
class Meta:
model = Room
fields = '__all__'