diff --git a/shiftregister/app/admin.py b/shiftregister/app/admin.py index 3836276..564b7ee 100644 --- a/shiftregister/app/admin.py +++ b/shiftregister/app/admin.py @@ -18,7 +18,7 @@ class ShiftAdmin(admin.ModelAdmin): def free_slots(self, object): return ( object.required_helpers or object.room.required_helpers - ) - object.shiftregistration_set.count() + ) - object.registration_count() def send_login(modeladmin, request, queryset): @@ -39,6 +39,19 @@ class HelperAdmin(admin.ModelAdmin): 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(LoginToken) diff --git a/shiftregister/app/migrations/0007_shiftregistration_state.py b/shiftregister/app/migrations/0007_shiftregistration_state.py new file mode 100644 index 0000000..10c1bdc --- /dev/null +++ b/shiftregister/app/migrations/0007_shiftregistration_state.py @@ -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, + ), + ), + ] diff --git a/shiftregister/app/models.py b/shiftregister/app/models.py index be228ff..d6a529c 100644 --- a/shiftregister/app/models.py +++ b/shiftregister/app/models.py @@ -3,7 +3,7 @@ import secrets from django.shortcuts import reverse from datetime import timedelta 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 dynamic_preferences.registries import global_preferences_registry @@ -28,6 +28,22 @@ class Shift(models.Model): description = models.TextField(blank=True, default="") 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): return f"{self.room.name}: {self.start_at}" @@ -37,6 +53,11 @@ class Shift(models.Model): def is_running(self): 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): phone = PhoneNumberField(unique=True, editable=False) @@ -78,6 +99,26 @@ class ShiftRegistration(models.Model): helper = models.ForeignKey(Helper, on_delete=models.CASCADE) 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): return self.shift.start_at > ( timezone.now() diff --git a/shiftregister/app/templates/shiftlist.html b/shiftregister/app/templates/shiftlist.html index 28c593c..aedbbe4 100644 --- a/shiftregister/app/templates/shiftlist.html +++ b/shiftregister/app/templates/shiftlist.html @@ -8,10 +8,10 @@ {% include "partials/shift_listitem.html" with shift=current_shift registered=True %} {% endif %} -{% if my_shifts %} -

Meine Schichten

+{% if my_future_shifts %} +

Meine kommenden Schichten

-{% for shift in my_shifts %} +{% for shift in my_future_shifts %} {% include "partials/shift_listitem.html" with registered=True %} {% endfor %}
diff --git a/shiftregister/app/views.py b/shiftregister/app/views.py index 4366193..9f12119 100644 --- a/shiftregister/app/views.py +++ b/shiftregister/app/views.py @@ -24,10 +24,11 @@ def index(request): # currently only sorts by date context = {} if request.helper: - context["my_shifts"] = ( + context["my_future_shifts"] = ( reg.shift 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") ) @@ -39,7 +40,7 @@ def index(request): room__required_helpers__gt=F("reg_count") ) free_shifts = ( - Shift.objects.annotate(reg_count=Count("shiftregistration")) + Shift.with_reg_count() .filter( help_wanted, start_at__gt=timezone.now(), @@ -50,7 +51,7 @@ def index(request): if request.helper: free_shifts = ( - Shift.objects.annotate(reg_count=Count("shiftregistration")) + Shift.with_reg_count() .filter( help_wanted, start_at__gt=timezone.now(), @@ -165,9 +166,9 @@ def shift(request, shiftid): # this currently ignores date/time request.session["last_seen_shift"] = shiftid if ( - shift.required_helpers > shift.shiftregistration_set.count() + shift.required_helpers > shift.registration_count() 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 diff --git a/shiftregister/team/views.py b/shiftregister/team/views.py index 4cfc679..818001a 100644 --- a/shiftregister/team/views.py +++ b/shiftregister/team/views.py @@ -103,7 +103,7 @@ class FreeShiftList(ShiftList): help_wanted = Q(required_helpers__gt=F("reg_count")) | Q( required_helpers=0 ) & 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, start_at__gt=timezone.now(), )