102 lines
3.6 KiB
Python
102 lines
3.6 KiB
Python
from django import forms
|
|
from django.forms import widgets
|
|
|
|
from .models import Worker, Leave, RotaSchedule
|
|
|
|
|
|
class WorkerForm(forms.ModelForm):
|
|
class Meta:
|
|
model = Worker
|
|
fields = ["name", "email", "site", "grade", "fte", "active"]
|
|
|
|
|
|
class LeaveForm(forms.ModelForm):
|
|
class Meta:
|
|
model = Leave
|
|
fields = ["start_date", "end_date", "reason"]
|
|
widgets = {
|
|
"start_date": widgets.DateInput(attrs={"class": "datepicker input", "autocomplete": "off"}),
|
|
"end_date": widgets.DateInput(attrs={"class": "datepicker input", "autocomplete": "off"}),
|
|
}
|
|
|
|
|
|
class RotaScheduleForm(forms.ModelForm):
|
|
class Meta:
|
|
model = RotaSchedule
|
|
# Do not expose end_date as editable: computed from start_date + weeks
|
|
fields = ["name", "start_date", "description"]
|
|
widgets = {
|
|
"start_date": widgets.DateInput(attrs={"class": "datepicker input", "autocomplete": "off"}),
|
|
}
|
|
|
|
weeks = forms.IntegerField(min_value=1, initial=4, help_text="Number of weeks to generate the rota for")
|
|
end_date = forms.DateField(required=False, disabled=True, widget=widgets.DateInput(attrs={"class": "datepicker input", "autocomplete": "off"}))
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
instance = kwargs.get("instance")
|
|
super().__init__(*args, **kwargs)
|
|
if instance and instance.start_date and instance.end_date:
|
|
delta = instance.end_date - instance.start_date
|
|
weeks = max(1, delta.days // 7)
|
|
self.fields["weeks"].initial = weeks
|
|
self.fields["end_date"].initial = instance.end_date
|
|
|
|
def clean_start_date(self):
|
|
start = self.cleaned_data.get("start_date")
|
|
if start is None:
|
|
return start
|
|
if start.weekday() != 0:
|
|
raise forms.ValidationError("Start date must be a Monday")
|
|
return start
|
|
|
|
def clean(self):
|
|
cleaned = super().clean()
|
|
start = cleaned.get("start_date")
|
|
weeks = cleaned.get("weeks")
|
|
if start and weeks:
|
|
import datetime
|
|
|
|
end_date = start + datetime.timedelta(days=weeks * 7)
|
|
cleaned["end_date"] = end_date
|
|
# update the form data/display
|
|
try:
|
|
self.data = self.data.copy()
|
|
self.data["end_date"] = end_date.isoformat()
|
|
except Exception:
|
|
pass
|
|
self.fields["end_date"].initial = end_date
|
|
return cleaned
|
|
|
|
def save(self, commit=True):
|
|
instance = super().save(commit=False)
|
|
end_date = self.cleaned_data.get("end_date")
|
|
if end_date:
|
|
instance.end_date = end_date
|
|
if commit:
|
|
instance.save()
|
|
try:
|
|
self.save_m2m()
|
|
except Exception:
|
|
pass
|
|
return instance
|
|
|
|
|
|
class ShiftForm(forms.Form):
|
|
name = forms.CharField(max_length=200)
|
|
sites = forms.CharField(
|
|
help_text="Comma separated list of sites (e.g. exeter,plymouth)",
|
|
required=True,
|
|
)
|
|
length = forms.DecimalField(max_digits=6, decimal_places=2, initial=12.5)
|
|
DAYS = [(d, d) for d in ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]]
|
|
days = forms.MultipleChoiceField(choices=DAYS, widget=forms.CheckboxSelectMultiple)
|
|
workers_required = forms.IntegerField(min_value=1, initial=1)
|
|
assign_as_block = forms.BooleanField(required=False, initial=False)
|
|
|
|
def clean_sites(self):
|
|
val = self.cleaned_data["sites"]
|
|
sites = [s.strip() for s in val.split(",") if s.strip()]
|
|
if not sites:
|
|
raise forms.ValidationError("At least one site is required")
|
|
return sites
|