add state to shiftregistration
This commit is contained in:
parent
74481b0bda
commit
19623fdb92
|
@ -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)
|
||||||
|
|
|
@ -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,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
|
@ -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()
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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(),
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue