shiftregister/shiftregister/signage/views.py

109 lines
3.3 KiB
Python

import datetime
from django.contrib import messages
from django.db import models
from django.db.models import Case, Count, ExpressionWrapper, F, Q, Sum, When
from django.shortcuts import render
from django.utils import timezone
from .models import Helper, Shift, ShiftRegistration
def public_dashboard(request):
facts = []
num_helpers = Helper.objects.count()
if num_helpers > 0:
facts.append(("Registrierte Helfis", num_helpers))
help_wanted = Q(required_helpers__gt=F("reg_count")) | Q(required_helpers=0) & Q(
room__required_helpers__gt=F("reg_count")
)
total_work_duration = ShiftRegistration.objects.filter(
state=ShiftRegistration.RegState.CHECKED_IN
).aggregate(sum=Sum("shift__duration"))["sum"]
if total_work_duration:
total_work_duration = round(total_work_duration.total_seconds() / 60.0)
facts.append(
(
"Geleistete Personenstunden",
f"{total_work_duration//60}h {total_work_duration%60}min",
)
)
num_free_shifts = (
Shift.with_reg_count()
.filter(help_wanted, deleted=False, start_at__gte=timezone.now())
.count()
)
if num_free_shifts > 0:
facts.append(("Zu übernehmende Schichten", num_free_shifts))
next_free_shifts = (
Shift.with_reg_count()
.filter(help_wanted, start_at__gt=timezone.now(), deleted=False)
.order_by("start_at")[:4]
)
context = {"facts": facts, "next_free_shifts": next_free_shifts}
return render(request, "public_dashboard.html", context)
def team_dashboard(request):
now = timezone.localtime()
today = now.date()
day = None
exclude_past_shifts = True
if date := request.GET.get("date"):
try:
day = datetime.date.fromisoformat(date)
exclude_past_shifts = False
except ValueError:
messages.add_message(request, messages.ERROR, "Ungültiges Datum")
changeover = datetime.datetime.combine(
day or today, datetime.time(hour=6), timezone.get_current_timezone()
)
if day is None and now.hour < changeover.hour:
day_end = changeover
day_start = day_end - datetime.timedelta(days=1)
day = today - datetime.timedelta(days=1)
else:
day_start = changeover
day_end = day_start + datetime.timedelta(days=1)
if day is None:
day = today
team_shifts = (
Shift.with_reg_count()
.annotate(
end_at=ExpressionWrapper(
F("start_at") + F("duration"), output_field=models.DateTimeField()
),
real_required_helpers=Case(
When(required_helpers=0, then=F("room__required_helpers")),
default=F("required_helpers"),
),
fallbackassignment_count=Count("fallbackassignment", distinct=True),
)
.filter(
deleted=False,
start_at__gte=day_start,
start_at__lt=day_end,
reg_count__lt=F("real_required_helpers"),
fallbackassignment_count__gt=0,
)
.order_by("start_at")
)
if exclude_past_shifts:
team_shifts = team_shifts.filter(end_at__gt=now)
return render(
request, "team_dashboard.html", {"today": day, "team_shifts": team_shifts}
)