This commit is contained in:
Ross
2025-12-12 22:31:07 +00:00
parent 00f09d5e5b
commit f6dd9285a5
3 changed files with 190 additions and 0 deletions
+23
View File
@@ -334,9 +334,32 @@ class ShiftForm(forms.Form):
help_text="Maximum allowed difference in allocated shifts for this shift (leave blank for default)",
)
# Allow entering shift-specific constraints as JSON. This should be a
# list of constraint dicts compatible with the scheduler's SingleShift
# `constraints` field. Example: `[{"name": "night", "options": {...}}]`
constraints = forms.CharField(
required=False,
widget=forms.Textarea(attrs={"rows": 4, "class": "textarea"}),
help_text="Optional JSON list of constraint objects for this shift (e.g. [{'name':'night','options':{}}])",
)
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
def clean_constraints(self):
val = self.cleaned_data.get("constraints")
if not val:
return []
try:
parsed = json.loads(val)
if not isinstance(parsed, list):
raise forms.ValidationError("Constraints must be a JSON list of constraint objects")
return parsed
except forms.ValidationError:
raise
except Exception as exc:
raise forms.ValidationError(f"Invalid JSON for constraints: {exc}")
+3
View File
@@ -882,6 +882,7 @@ def shift_add(request, rota_id):
"workers_required": int(data["workers_required"]),
"assign_as_block": bool(data["assign_as_block"]),
"balance_offset": data.get("balance_offset"),
"constraints": data.get("constraints", []),
}
current = rota.shifts or []
@@ -930,6 +931,7 @@ def shift_edit(request, rota_id, idx):
"days": data["days"],
"workers_required": int(data["workers_required"]),
"assign_as_block": bool(data["assign_as_block"]),
"constraints": data.get("constraints", []),
}
current = rota.shifts or []
current[idx] = shift_dict
@@ -958,6 +960,7 @@ def shift_edit(request, rota_id, idx):
"workers_required": shift.get("workers_required"),
"assign_as_block": shift.get("assign_as_block", False),
"balance_offset": shift.get("balance_offset", None),
"constraints": json.dumps(shift.get("constraints", [])) if shift.get("constraints") is not None else "",
}
form = ShiftForm(initial=initial)
modal_html = render_to_string("rota/partials/shift_form_modal.html", {"form": form, "rota": rota, "form_action": request.path}, request=request)