Add rota-builder summary to detail view with weeks, shifts, and workers count
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user