Add rota-builder summary to detail view with weeks, shifts, and workers count

This commit is contained in:
Ross
2025-12-17 17:25:22 +00:00
parent 8458279e19
commit 023e345591
4 changed files with 140 additions and 3 deletions
+71
View File
@@ -441,6 +441,77 @@ class RotaScheduleForm(forms.ModelForm):
self.fields["end_date"].initial = end_date
return cleaned
def save(self, commit=True):
"""Save the RotaSchedule and persist dynamic `opt__*` fields into
`instance.options`.
This persists both typed constraint option fields (created from
RotaConstraintOptions) and the small set of builder-argument fields
(created in __init__). For structured fields we attempt to parse JSON
textareas into Python objects.
"""
instance = super().save(commit=False)
opts = instance.options or {}
# Persist typed constraint option fields using inferred defaults map
try:
defaults = getattr(self, "_constraint_defaults", {}) or {}
except Exception:
defaults = {}
for key, default in defaults.items():
field_name = f"opt__{key}"
if field_name in self.cleaned_data:
val = self.cleaned_data[field_name]
if isinstance(default, (list, dict)):
# JSON textarea
try:
parsed = json.loads(val) if val is not None and val != "" else []
except Exception:
parsed = val
opts[key] = parsed
else:
if val == "" or val is None:
opts[key] = None
else:
opts[key] = val
# Persist any remaining opt__ fields (builder args and others)
for fname, val in self.cleaned_data.items():
if not fname.startswith("opt__"):
continue
key = fname[5:]
if key in defaults:
# already handled
continue
v = val
# Try to parse JSON-like strings into structures
if isinstance(v, str):
s = v.strip()
if s.startswith("[") or s.startswith("{"):
try:
v = json.loads(v)
except Exception:
pass
opts[key] = v
# Persist the top-level 'weeks' value from the form into options so
# the builder can prefer this explicit value instead of deriving it
# from end_date. Do not persist end_date itself here.
try:
weeks_val = self.cleaned_data.get("weeks")
if weeks_val is not None:
opts["weeks"] = int(weeks_val)
except Exception:
pass
instance.options = opts
if commit:
instance.save()
return instance
class WorkerSelfServiceForm(forms.ModelForm):
"""Small form exposed to workers via tokenized links so they can set