2
0
Fork 0

add state to shiftregistration

This commit is contained in:
Andreas (@xAndy) Zimmermann 2022-05-10 20:58:02 +02:00
parent 74481b0bda
commit 19623fdb92
6 changed files with 95 additions and 13 deletions

View File

@ -18,7 +18,7 @@ class ShiftAdmin(admin.ModelAdmin):
def free_slots(self, object): def free_slots(self, object):
return ( return (
object.required_helpers or object.room.required_helpers object.required_helpers or object.room.required_helpers
) - object.shiftregistration_set.count() ) - object.registration_count()
def send_login(modeladmin, request, queryset): def send_login(modeladmin, request, queryset):
@ -39,6 +39,19 @@ class HelperAdmin(admin.ModelAdmin):
actions = (send_login,) actions = (send_login,)
admin.site.register(ShiftRegistration) @admin.register(ShiftRegistration)
class ShiftRegistrationAdmin(admin.ModelAdmin):
list_display = ("start_at", "room", "helper_name", "state")
def room(self, obj):
return obj.shift.room.name
def start_at(self, obj):
return obj.shift.start_at
def helper_name(self, obj):
return obj.helper.name
admin.site.register(Message) admin.site.register(Message)
admin.site.register(LoginToken) admin.site.register(LoginToken)

View File

@ -0,0 +1,27 @@
# Generated by Django 4.0.4 on 2022-05-10 18:02
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("app", "0006_alter_shift_description"),
]
operations = [
migrations.AddField(
model_name="shiftregistration",
name="state",
field=models.CharField(
choices=[
("REG", "registriert"),
("CHECK", "checkin"),
("CANCEL", "abgemeldet"),
("FAIL", "nicht angetreten"),
],
default="REG",
max_length=7,
),
),
]

View File

@ -3,7 +3,7 @@ import secrets
from django.shortcuts import reverse from django.shortcuts import reverse
from datetime import timedelta from datetime import timedelta
from django.utils import timezone from django.utils import timezone
from django.db.models import F, Count, Q, ExpressionWrapper from django.db.models import F, Count, Q, ExpressionWrapper, Case, When
from phonenumber_field.modelfields import PhoneNumberField from phonenumber_field.modelfields import PhoneNumberField
from dynamic_preferences.registries import global_preferences_registry from dynamic_preferences.registries import global_preferences_registry
@ -28,6 +28,22 @@ class Shift(models.Model):
description = models.TextField(blank=True, default="") description = models.TextField(blank=True, default="")
deleted = models.BooleanField(default=False) deleted = models.BooleanField(default=False)
def with_reg_count():
return Shift.objects.annotate(
reg_count=Count(
Case(
When(
shiftregistration__state__in=[
ShiftRegistration.REGISTERED,
ShiftRegistration.CHECKED_IN,
],
then=1,
),
output_field=models.IntegerField(),
)
)
)
def __str__(self): def __str__(self):
return f"{self.room.name}: {self.start_at}" return f"{self.room.name}: {self.start_at}"
@ -37,6 +53,11 @@ class Shift(models.Model):
def is_running(self): def is_running(self):
return (self.start_at <= timezone.now()) and (not self.has_ended()) return (self.start_at <= timezone.now()) and (not self.has_ended())
def registration_count(self):
return self.shiftregistration_set.filter(
state__in=[ShiftRegistration.REGISTERED, ShiftRegistration.CHECKED_IN]
).count()
class Helper(models.Model): class Helper(models.Model):
phone = PhoneNumberField(unique=True, editable=False) phone = PhoneNumberField(unique=True, editable=False)
@ -78,6 +99,26 @@ class ShiftRegistration(models.Model):
helper = models.ForeignKey(Helper, on_delete=models.CASCADE) helper = models.ForeignKey(Helper, on_delete=models.CASCADE)
reminder_sent = models.BooleanField(default=False) reminder_sent = models.BooleanField(default=False)
# default is registered
REGISTERED = "REG"
CHECKED_IN = "CHECK"
# cancel via infopoint
CANCELED = "CANCEL"
# did not attend shift
FAILED = "FAIL"
STATE_CHOICES = [
(REGISTERED, "registriert"),
(CHECKED_IN, "checkin"),
(CANCELED, "abgemeldet"),
(FAILED, "nicht angetreten"),
]
state = models.CharField(
max_length=7,
choices=STATE_CHOICES,
default=REGISTERED,
)
def can_cancel(self): def can_cancel(self):
return self.shift.start_at > ( return self.shift.start_at > (
timezone.now() timezone.now()

View File

@ -8,10 +8,10 @@
{% include "partials/shift_listitem.html" with shift=current_shift registered=True %} {% include "partials/shift_listitem.html" with shift=current_shift registered=True %}
</div> </div>
{% endif %} {% endif %}
{% if my_shifts %} {% if my_future_shifts %}
<h3 class="title">Meine Schichten</h3> <h3 class="title">Meine kommenden Schichten</h3>
<div class="columns is-multiline"> <div class="columns is-multiline">
{% for shift in my_shifts %} {% for shift in my_future_shifts %}
{% include "partials/shift_listitem.html" with registered=True %} {% include "partials/shift_listitem.html" with registered=True %}
{% endfor %} {% endfor %}
</div> </div>

View File

@ -24,10 +24,11 @@ def index(request):
# currently only sorts by date # currently only sorts by date
context = {} context = {}
if request.helper: if request.helper:
context["my_shifts"] = ( context["my_future_shifts"] = (
reg.shift reg.shift
for reg in request.helper.shiftregistration_set.filter( for reg in request.helper.shiftregistration_set.filter(
shift__start_at__gt=timezone.now() shift__start_at__gt=timezone.now(),
state__in=[ShiftRegistration.REGISTERED, ShiftRegistration.CHECKED_IN],
).order_by("shift__start_at") ).order_by("shift__start_at")
) )
@ -39,7 +40,7 @@ def index(request):
room__required_helpers__gt=F("reg_count") room__required_helpers__gt=F("reg_count")
) )
free_shifts = ( free_shifts = (
Shift.objects.annotate(reg_count=Count("shiftregistration")) Shift.with_reg_count()
.filter( .filter(
help_wanted, help_wanted,
start_at__gt=timezone.now(), start_at__gt=timezone.now(),
@ -50,7 +51,7 @@ def index(request):
if request.helper: if request.helper:
free_shifts = ( free_shifts = (
Shift.objects.annotate(reg_count=Count("shiftregistration")) Shift.with_reg_count()
.filter( .filter(
help_wanted, help_wanted,
start_at__gt=timezone.now(), start_at__gt=timezone.now(),
@ -165,9 +166,9 @@ def shift(request, shiftid):
# this currently ignores date/time # this currently ignores date/time
request.session["last_seen_shift"] = shiftid request.session["last_seen_shift"] = shiftid
if ( if (
shift.required_helpers > shift.shiftregistration_set.count() shift.required_helpers > shift.registration_count()
or shift.required_helpers == 0 or shift.required_helpers == 0
and shift.room.required_helpers > shift.shiftregistration_set.count() and shift.room.required_helpers > shift.registration_count()
): ):
context["can_register"] = True context["can_register"] = True

View File

@ -103,7 +103,7 @@ class FreeShiftList(ShiftList):
help_wanted = Q(required_helpers__gt=F("reg_count")) | Q( help_wanted = Q(required_helpers__gt=F("reg_count")) | Q(
required_helpers=0 required_helpers=0
) & Q(room__required_helpers__gt=F("reg_count")) ) & Q(room__required_helpers__gt=F("reg_count"))
return Shift.objects.annotate(reg_count=Count("shiftregistration")).filter( return Shift.with_reg_count().filter(
help_wanted, help_wanted,
start_at__gt=timezone.now(), start_at__gt=timezone.now(),
) )