From 36560e76068991ea002e231dcb391de8d4403cc6 Mon Sep 17 00:00:00 2001 From: Sebastien Renard Date: Sun, 10 Nov 2024 16:32:23 +0100 Subject: [PATCH] check that staffing mission boundaries are not changed in an inconsistent way with current staffing --- staffing/forms.py | 6 +++++- staffing/models.py | 11 ++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/staffing/forms.py b/staffing/forms.py index 7c2bb056..2fdeffdd 100644 --- a/staffing/forms.py +++ b/staffing/forms.py @@ -173,7 +173,7 @@ def add_fields(self, form, index): if self.instance.end_date: maxDate = self.instance.end_date.replace(day=1) else: - maxDate = None + maxDate = self.instance.staffing_end_date() form.fields["consultant"] = ModelChoiceField(widget=ConsultantChoices(attrs={'data-placeholder':_("Select a consultant to add forecast...")}), queryset=Consultant.objects) form.fields["staffing_date"] = StaffingDateChoicesField(minDate=minDate, maxDate=maxDate) form.fields["charge"].widget.attrs["class"] = "numberinput form-control" @@ -410,9 +410,13 @@ def _clean_start_end_date(self, field): return self.cleaned_data[field] def clean_start_date(self): + if self.cleaned_data.get("start_date") and self.cleaned_data.get("start_date") > self.instance.staffing_start_date(): + raise ValidationError(_("start date must be before staffing start date (%s)" % self.instance.staffing_start_date())) return self._clean_start_end_date("start_date") def clean_end_date(self): + if self.cleaned_data.get("end_date") and self.cleaned_data.get("end_date") < self.instance.staffing_end_date(): + raise ValidationError(_("end date must be after staffing end date (%s)" % self.instance.staffing_end_date())) return self._clean_start_end_date("end_date") def clean(self): diff --git a/staffing/models.py b/staffing/models.py index 111975a5..cddeaf94 100644 --- a/staffing/models.py +++ b/staffing/models.py @@ -411,13 +411,22 @@ def objectiveMargin(self, startDate=None, endDate=None): @cacheable("Mission.staffing_start_date%(id)s", 10) def staffing_start_date(self): - """Starting date (=oldiest) staffing date of this mission. None if no staffing""" + """Starting date (=oldest) staffing date of this mission. None if no staffing""" start_dates = self.staffing_set.all().aggregate(Min("staffing_date")).values() if start_dates: return list(start_dates)[0] else: return None + @cacheable("Mission.staffing_end_date%(id)s", 10) + def staffing_end_date(self): + """End date (=latest) staffing date of this mission. None if no staffing""" + end_dates = self.staffing_set.all().aggregate(Max("staffing_date")).values() + if end_dates: + return list(end_dates)[0] + else: + return None + def pivotable_data(self, startDate=None, endDate=None): """Compute raw data for pivot table on that mission""" #TODO: factorize with staffing.views.mission_timesheet