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