This commit is contained in:
Ross
2025-12-09 12:57:19 +00:00
parent 3feb5fc7a3
commit ae52d80f98
3 changed files with 176 additions and 1 deletions
+59
View File
@@ -2,6 +2,8 @@ from django import forms
from django.forms import widgets
from .models import Worker, Leave, RotaSchedule
import importlib
import json
class WorkerForm(forms.ModelForm):
@@ -40,6 +42,38 @@ class RotaScheduleForm(forms.ModelForm):
weeks = max(1, delta.days // 7)
self.fields["weeks"].initial = weeks
self.fields["end_date"].initial = instance.end_date
# Dynamically add RotaBuilder constraint option fields so these can be edited
try:
mod = importlib.import_module("rota_generator.shifts")
RotaBuilder = getattr(mod, "RotaBuilder")
try:
rb = RotaBuilder()
constraint_defaults = getattr(rb, "constraint_options", {})
except Exception:
constraint_defaults = {}
except Exception:
constraint_defaults = {}
self._constraint_defaults = constraint_defaults
# Load existing options from instance if present
existing_opts = {}
if instance and getattr(instance, "options", None):
existing_opts = instance.options or {}
for key, default in constraint_defaults.items():
field_name = f"opt__{key}"
initial = existing_opts.get(key, default)
if isinstance(default, bool):
self.fields[field_name] = forms.BooleanField(required=False, initial=bool(initial), label=key.replace("_", " "))
elif isinstance(default, int):
self.fields[field_name] = forms.IntegerField(required=False, initial=initial, label=key.replace("_", " "))
elif isinstance(default, float):
self.fields[field_name] = forms.FloatField(required=False, initial=initial, label=key.replace("_", " "))
elif isinstance(default, (list, dict)):
self.fields[field_name] = forms.CharField(required=False, initial=json.dumps(initial), widget=forms.Textarea, label=key.replace("_", " "), help_text="Enter JSON")
else:
self.fields[field_name] = forms.CharField(required=False, initial=initial, label=key.replace("_", " "))
def clean_start_date(self):
start = self.cleaned_data.get("start_date")
@@ -72,6 +106,23 @@ class RotaScheduleForm(forms.ModelForm):
end_date = self.cleaned_data.get("end_date")
if end_date:
instance.end_date = end_date
# Collect option fields and persist into instance.options
opts = instance.options or {}
for key in getattr(self, "_constraint_defaults", {}).keys():
field_name = f"opt__{key}"
if field_name in self.cleaned_data:
val = self.cleaned_data[field_name]
default = self._constraint_defaults.get(key)
# Parse JSON for list/dict fields
if isinstance(default, (list, dict)):
try:
parsed = json.loads(val) if val is not None and val != "" else []
except Exception:
parsed = val
opts[key] = parsed
else:
opts[key] = val
instance.options = opts
if commit:
instance.save()
try:
@@ -81,6 +132,14 @@ class RotaScheduleForm(forms.ModelForm):
return instance
class RotaOptionsForm(forms.Form):
options_json = forms.CharField(
widget=forms.Textarea(attrs={"rows": 10, "class": "textarea"}),
required=False,
help_text="Edit rota options as JSON. See available constraint keys below.",
)
class ShiftForm(forms.Form):
name = forms.CharField(max_length=200)
sites = forms.CharField(