Refactor Assignment model to enforce single rota assignment per worker and update related view logic to prevent multiple assignments

This commit is contained in:
Ross
2025-12-19 21:10:43 +00:00
parent f4ab0be347
commit 5cf2480602
3 changed files with 59 additions and 8 deletions
+36 -6
View File
@@ -334,12 +334,19 @@ def worker_create(request):
# If we created a worker and a rota_id was provided, create Assignment
if rota is not None:
from .models import Assignment
# Only assign if the worker is not already assigned to any rota.
try:
Assignment.objects.create(worker=worker, rota=rota)
if not worker.rotas.exists():
Assignment.objects.create(worker=worker, rota=rota)
else:
# skip assigning; worker already assigned elsewhere
pass
except Exception:
# best-effort: try using the M2M add as fallback
# best-effort: try using the M2M add as fallback but still
# respect single-rota constraint
try:
rota.workers.add(worker)
if not worker.rotas.exists():
rota.workers.add(worker)
except Exception:
pass
@@ -454,14 +461,37 @@ def worker_import(request, rota_id=None):
except Exception:
fte = 1.0
w = Worker.objects.create(name=name.strip(), email=email.strip(), site=site.strip(), grade=grade, fte=fte)
# If an email is provided, try to find an existing worker to
# avoid duplicates; otherwise create a new record.
existing = None
if email:
try:
existing = Worker.objects.filter(email__iexact=email.strip()).first()
except Exception:
existing = None
if existing is not None:
w = existing
else:
w = Worker.objects.create(name=name.strip(), email=email.strip(), site=site.strip(), grade=grade, fte=fte)
created.append(w)
# Assignment: only assign if the worker is not already assigned
# to another rota. If already assigned, record an error and
# skip assignment.
if assign_to_rota and rota is not None:
try:
Assignment.objects.create(worker=w, rota=rota)
if not w.rotas.exists():
Assignment.objects.create(worker=w, rota=rota)
else:
# If already assigned to this rota, nothing to do.
assigned_rota = w.rotas.first()
if assigned_rota and assigned_rota.pk != rota.pk:
errors.append(f"Row {i+1}: worker '{w.name}' already assigned to rota '{assigned_rota.name}'")
except Exception:
try:
rota.workers.add(w)
if not w.rotas.exists():
rota.workers.add(w)
except Exception:
pass
except Exception as exc: