This commit is contained in:
Ross
2025-12-13 22:41:32 +00:00
parent d509922450
commit 249e09766d
10 changed files with 296 additions and 11 deletions
+57 -10
View File
@@ -304,7 +304,18 @@ def worker_detail(request, worker_id):
leave.save()
return redirect("rota:worker_detail", worker_id=worker.id)
else:
form = LeaveForm()
# Pre-fill dates when `date` query param is provided (ISO YYYY-MM-DD)
date_q = request.GET.get("date") or request.POST.get("date")
if date_q:
try:
import datetime
d = datetime.date.fromisoformat(date_q)
form = LeaveForm(initial={"start_date": d, "end_date": d})
except Exception:
form = LeaveForm()
else:
form = LeaveForm()
return render(request, "rota/worker_detail.html", {"worker": worker, "form": form})
@@ -340,12 +351,40 @@ def worker_edit(request, rota_id, worker_id):
form = WorkerForm(instance=worker)
modal_html = render_to_string(
"rota/partials/worker_form_modal.html",
{"form": form, "form_action": request.path, "rota": rota},
{"form": form, "form_action": request.path, "rota": rota, "worker": worker, "token_link": request.build_absolute_uri(reverse('rota:request_leave_token', args=[worker.request_token])) if worker and getattr(worker, 'request_token', None) else ''},
request=request,
)
return HttpResponse(modal_html)
@require_POST
def regenerate_worker_token(request, worker_id):
# Only allow staff users to regenerate tokens from the admin modal
if not (request.user and request.user.is_authenticated and request.user.is_staff):
return HttpResponseBadRequest("Permission denied")
worker = get_object_or_404(Worker, pk=worker_id)
# generate unique token
import uuid
new_token = uuid.uuid4()
# guard against collision
while Worker.objects.filter(request_token=new_token).exclude(pk=worker.pk).exists():
new_token = uuid.uuid4()
worker.request_token = new_token
worker.save(update_fields=["request_token"])
# render only the token area so HTMX can swap it
token_html = render_to_string(
"rota/partials/worker_token_area.html",
{"worker": worker, "token_link": request.build_absolute_uri(reverse('rota:request_leave_token', args=[worker.request_token])) if getattr(worker, 'request_token', None) else ''},
request=request,
)
response = HttpResponse(token_html)
response["HX-Trigger"] = "workerTokenRegenerated"
return response
@require_http_methods(["GET", "POST"])
def worker_delete(request, rota_id, worker_id):
rota = get_object_or_404(RotaSchedule, pk=rota_id)
@@ -421,7 +460,7 @@ def rota_options_update(request, rota_id):
@require_http_methods(["GET", "POST"])
def request_leave(request):
def request_leave(request, token=None):
"""Allow a worker to request leave for themselves.
Resolution strategy:
@@ -434,14 +473,22 @@ def request_leave(request):
is_hx = request.headers.get("HX-Request", "false").lower() == "true"
worker = None
# try authenticated user -> worker by email
try:
if request.user and request.user.is_authenticated and getattr(request.user, "email", None):
worker = Worker.objects.filter(email=request.user.email).first()
except Exception:
worker = None
# 1) token link (preferred for unauthenticated users)
if token:
try:
worker = get_object_or_404(Worker, request_token=token)
except Exception:
worker = None
# fallback to explicit worker_id
# 2) try authenticated user -> worker by email
if worker is None:
try:
if request.user and request.user.is_authenticated and getattr(request.user, "email", None):
worker = Worker.objects.filter(email=request.user.email).first()
except Exception:
worker = None
# 3) fallback to explicit worker_id param
if worker is None:
worker_id = request.GET.get("worker_id") or request.POST.get("worker_id")
if worker_id: