2
0
Fork 0

Show checkin state for running shifts/shifts in the next 30 minutes

This commit is contained in:
Luca 2023-05-14 14:27:13 +02:00
parent 00d5dfe22d
commit 0347adc267
4 changed files with 56 additions and 14 deletions

View File

@ -7,8 +7,12 @@
<strong>Beginn:</strong> {{ shift.start_at }}<br> <strong>Beginn:</strong> {{ shift.start_at }}<br>
<strong>Dauer:</strong> {{ shift.duration }}<br> <strong>Dauer:</strong> {{ shift.duration }}<br>
<strong>Belegung:</strong> {{ shift.registration_count }}/{{ shift.required_helpers|default:shift.room.required_helpers }} <strong>Belegung:</strong> {{ shift.registration_count }}/{{ shift.required_helpers|default:shift.room.required_helpers }}
{% if shift.checkin_count is not None %}
<br>
<strong>Checkin-Status:</strong> {% if shift.checkin_count == shift.required_helpers|default:shift.room.required_helpers %}<span class="tag is-rounded is-success">vollständig</span>{% elif shift.checkin_count > 0 %}<span class="tag is-rounded is-warning">teilweise</span>{% else %}<span class="tag is-rounded is-danger">kein Checkin</span>{% endif %}
{% endif %}
</div> </div>
<div class="is-flex is-justify-content-end"> <div class="buttons is-right mt-3">
<a class="button is-info is-small" href="{% url 'team:shift' shift.id %}">Details</a> <a class="button is-info is-small mr-0" href="{% url 'team:shift' shift.id %}">Details</a>
</div> </div>
</div> </div>

View File

@ -12,12 +12,20 @@
</div> </div>
<hr> <hr>
{% endif %} {% endif %}
<h3 class="title is-spaced">Nächste Schichten pro Raum</h3> {% if next_shifts %}
<h3 class="title is-spaced">Nächste Schichten</h3>
<div class="columns is-multiline"> <div class="columns is-multiline">
{% for shift in next_shifts %} {% for shift in next_shifts %}
{% include "partials/shift_list_item.html" %}
{% endfor %}
</div>
{% endif %}
<h3 class="title is-spaced">Nächste Schichten pro Raum</h3>
<div class="columns is-multiline">
{% for shift in next_shifts_per_room %}
<div class="column is-one-quarter"> <div class="column is-one-quarter">
<h5 class="subtitle"><a href="{% url 'team:shift_room' shift.room.name %}">{{ shift.room.name }}</a></h5> <h5 class="subtitle"><a href="{% url 'team:shift_room' shift.room.name %}">{{ shift.room.name }}</a></h5>
<a class="" href="{% url 'team:shift' shift.id %}"> <a href="{% url 'team:shift' shift.id %}">
{% include "partials/shift_box.html" %} {% include "partials/shift_box.html" %}
</a> </a>
</div> </div>

View File

@ -4,7 +4,7 @@ from . import views
app_name = "team" app_name = "team"
urlpatterns = [ urlpatterns = [
path("", views.shift_overview, name="index"), path("", views.index, name="index"),
path("overview/", views.shift_overview, name="shift_overview"), path("overview/", views.shift_overview, name="shift_overview"),
path("shifts/", views.ShiftList.as_view(), name="shift_all"), path("shifts/", views.ShiftList.as_view(), name="shift_all"),
path("room_shifts/<path:pk>", views.RoomShiftList.as_view(), name="shift_room"), path("room_shifts/<path:pk>", views.RoomShiftList.as_view(), name="shift_room"),

View File

@ -11,31 +11,61 @@ from django.contrib import messages
from django.db import models from django.db import models
from django.core.paginator import Paginator from django.core.paginator import Paginator
from .forms import BulkMessage, HelperShift, HelperMessage from .forms import BulkMessage, HelperShift, HelperMessage
from datetime import timedelta
# Create your views here. # Create your views here.
def index(request): def index(request):
pass return redirect("team:shift_overview")
@login_required @login_required
def shift_overview(request): def shift_overview(request):
checkin_count = Count(
Case(
When(
shiftregistration__state=ShiftRegistration.RegState.CHECKED_IN, then=1
),
output_field=models.IntegerField(),
)
)
context = {} context = {}
context["running_shifts"] = [ context["running_shifts"] = (
shift Shift.with_reg_count()
for shift in Shift.with_reg_count()
.annotate( .annotate(
checkin_count=Count(
Case(
When(
shiftregistration__state=ShiftRegistration.RegState.CHECKED_IN,
then=1,
),
output_field=models.IntegerField(),
)
),
end_at=ExpressionWrapper( end_at=ExpressionWrapper(
F("start_at") + F("duration"), F("start_at") + F("duration"), output_field=DateTimeField()
output_field=DateTimeField(), ),
)
) )
.filter(start_at__lte=timezone.now(), end_at__gte=timezone.now(), deleted=False) .filter(start_at__lte=timezone.now(), end_at__gte=timezone.now(), deleted=False)
.order_by("start_at") .order_by("start_at")
] )
context["next_shifts"] = (
Shift.with_reg_count()
.annotate(checkin_count=checkin_count)
.filter(
start_at__gt=timezone.now(),
start_at__lte=timezone.now() + timedelta(minutes=30),
deleted=False,
)
.order_by("start_at")
)
# only Postgres supports DISTINCT on specific columns, SQLite does not support aggregates on datetime fields # only Postgres supports DISTINCT on specific columns, SQLite does not support aggregates on datetime fields
context["next_shifts"] = filter( context["next_shifts_per_room"] = filter(
lambda x: x is not None, lambda x: x is not None,
( (
Shift.with_reg_count() Shift.with_reg_count()