Add shift-specific 'required_helpers' field

pull/1/head
Luca 3 years ago
parent 7a08080604
commit 8437882b14

@ -16,7 +16,9 @@ class ShiftAdmin(admin.ModelAdmin):
# object.helpers.count() # object.helpers.count()
def free_slots(self, object): def free_slots(self, object):
return object.room.required_helpers - object.shiftregistration_set.count() return (
object.required_helpers or object.room.required_helpers
) - object.shiftregistration_set.count()
def send_login(modeladmin, request, queryset): def send_login(modeladmin, request, queryset):
@ -24,7 +26,7 @@ def send_login(modeladmin, request, queryset):
helper.send_confirmation() helper.send_confirmation()
class RegistationInline(admin.TabularInline): class RegistrationInline(admin.TabularInline):
model = ShiftRegistration model = ShiftRegistration
@ -33,7 +35,7 @@ class HelperAdmin(admin.ModelAdmin):
readonly_fields = ("phone",) readonly_fields = ("phone",)
fields = ("name", "phone", "number_validated") fields = ("name", "phone", "number_validated")
list_display = ("name",) list_display = ("name",)
inlines = (RegistationInline,) inlines = (RegistrationInline,)
actions = (send_login,) actions = (send_login,)

@ -0,0 +1,18 @@
# Generated by Django 4.0.4 on 2022-05-10 13:03
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("app", "0003_logintoken_send_count"),
]
operations = [
migrations.AddField(
model_name="shift",
name="required_helpers",
field=models.IntegerField(default=0),
),
]

@ -22,8 +22,10 @@ class Shift(models.Model):
room = models.ForeignKey(Room, on_delete=models.RESTRICT) room = models.ForeignKey(Room, on_delete=models.RESTRICT)
start_at = models.DateTimeField() start_at = models.DateTimeField()
duration = models.DurationField() duration = models.DurationField()
required_helpers = models.IntegerField(
default=0, help_text="When this is set to zero, the room value is used instead."
)
deleted = models.BooleanField(default=False) deleted = models.BooleanField(default=False)
# todo: add helper amount override field
def __str__(self): def __str__(self):
return f"{self.room.name}: {self.start_at}" return f"{self.room.name}: {self.start_at}"
@ -82,7 +84,7 @@ class ShiftRegistration(models.Model):
) )
def send_reminder(self): def send_reminder(self):
text = f"Deine Kontakt-Schicht begint um {self.shift.start_at.strftime('%H:%M')}, bitte komme eine halbe Stunde vorher an den Infopoint." text = f"Deine kontakt-Schicht beginnt um {self.shift.start_at.strftime('%H:%M')}, bitte komm eine halbe Stunde vorher an den Infopoint."
msg = Message(to=self.helper, text=text) msg = Message(to=self.helper, text=text)
msg.save() msg.save()
self.reminder_sent = True self.reminder_sent = True

@ -35,11 +35,14 @@ def index(request):
if imp_shift and imp_shift.is_running(): if imp_shift and imp_shift.is_running():
context["current_shift"] = imp_shift context["current_shift"] = imp_shift
help_wanted = Q(required_helpers__gt=F("reg_count")) | Q(required_helpers=0) & Q(
room__required_helpers__gt=F("reg_count")
)
free_shifts = ( free_shifts = (
Shift.objects.annotate(reg_count=Count("shiftregistration")) Shift.objects.annotate(reg_count=Count("shiftregistration"))
.filter( .filter(
help_wanted,
start_at__gt=timezone.now(), start_at__gt=timezone.now(),
room__required_helpers__gt=F("reg_count"),
deleted=False, deleted=False,
) )
.order_by("start_at") .order_by("start_at")
@ -49,8 +52,8 @@ def index(request):
free_shifts = ( free_shifts = (
Shift.objects.annotate(reg_count=Count("shiftregistration")) Shift.objects.annotate(reg_count=Count("shiftregistration"))
.filter( .filter(
help_wanted,
start_at__gt=timezone.now(), start_at__gt=timezone.now(),
room__required_helpers__gt=F("reg_count"),
deleted=False, deleted=False,
) )
.filter(~Q(shiftregistration__helper=request.helper)) .filter(~Q(shiftregistration__helper=request.helper))
@ -161,7 +164,11 @@ 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 shift.room.required_helpers > shift.shiftregistration_set.count(): if (
shift.required_helpers > shift.shiftregistration_set.count()
or shift.required_helpers == 0
and shift.room.required_helpers > shift.shiftregistration_set.count()
):
context["can_register"] = True context["can_register"] = True
if helper: if helper:

@ -25,11 +25,26 @@ def import_calendar(calendar):
events = {} events = {}
for event in cal.walk("vevent"): for event in cal.walk("vevent"):
uid = event.decoded("uid").decode() uid = event.decoded("uid").decode()
room = ( summary = event.decoded("summary").decode()
event.decoded("location", None) or event.decoded("summary")
).decode()
start = event.decoded("dtstart").astimezone(timezone.utc) start = event.decoded("dtstart").astimezone(timezone.utc)
end = event.decoded("dtend").astimezone(timezone.utc) end = event.decoded("dtend").astimezone(timezone.utc)
location = event.decoded("location", None)
if location is not None:
location = location.decode()
if location:
room = location
try:
required_helpers = int(summary)
except ValueError:
required_helpers = 0
else:
try:
room, required_helpers = tuple(summary.split())
required_helpers = int(required_helpers)
except ValueError:
room = summary
required_helpers = 0
if not uid or not room: if not uid or not room:
return False return False
@ -40,6 +55,7 @@ def import_calendar(calendar):
{ {
"start_at": start, "start_at": start,
"duration": end - start, "duration": end - start,
"required_helpers": required_helpers,
"uuid": uid, "uuid": uid,
"calendar": calendar, "calendar": calendar,
}, },
@ -52,7 +68,7 @@ def import_calendar(calendar):
if r == None: if r == None:
rooms[room] = Room( rooms[room] = Room(
name=room, required_helpers=0 name=room, required_helpers=0
) # required_helpers=0 ensures a shift in a new room is not displayed until the correct number of required helpers is set ) # required_helpers=0 ensures a shift in a new room is not displayed unless the correct number of required helpers is set or the shift itself specifies it
rooms[room].save() rooms[room].save()
for e in Event.objects.filter(calendar=calendar, uuid__in=events): for e in Event.objects.filter(calendar=calendar, uuid__in=events):
@ -62,6 +78,7 @@ def import_calendar(calendar):
e.room = rooms[room] e.room = rooms[room]
e.start_at = event["start_at"] e.start_at = event["start_at"]
e.duration = event["duration"] e.duration = event["duration"]
e.required_helpers = event["required_helpers"]
e.save() e.save()
events[uuid] = (room, e) events[uuid] = (room, e)

@ -6,7 +6,7 @@
<strong>Ort:</strong> {{ shift.room.name }}<br> <strong>Ort:</strong> {{ shift.room.name }}<br>
<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.shiftregistration_set.count }}/{{ shift.room.required_helpers }} <strong>Belegung:</strong> {{ shift.shiftregistration_set.count }}/{{ shift.required_helpers|default:shift.room.required_helpers }}
</div> </div>
<div class="is-flex is-justify-content-end"> <div class="is-flex is-justify-content-end">
<a class="button is-info is-small" href="{% url 'team:shift' shift.id %}">Details</a> <a class="button is-info is-small" href="{% url 'team:shift' shift.id %}">Details</a>

@ -2,7 +2,7 @@
{% block title %}Schichtdetails{% endblock %} {% block title %}Schichtdetails{% endblock %}
{% block content %} {% block content %}
<h3 class="title is-spaced">{% if shift.deleted %}(gelöscht) {% endif %}{{ shift.room.name }} {{ shift.start_at }} ({{ shift.shiftregistration_set.count }}/{{ shift.room.required_helpers }})</h3> <h3 class="title is-spaced">{% if shift.deleted %}(gelöscht) {% endif %}{{ shift.room.name }} {{ shift.start_at }} ({{ shift.shiftregistration_set.count }}/{{ shift.required_helpers|default:shift.room.required_helpers }})</h3>
{% if shift.shiftregistration_set.all %} {% if shift.shiftregistration_set.all %}
<h5 class="subtitle">Helfer*innen</h5> <h5 class="subtitle">Helfer*innen</h5>
<div class="columns is-multiline"> <div class="columns is-multiline">

@ -25,13 +25,13 @@ def shift_overview(request):
output_field=DateTimeField(), output_field=DateTimeField(),
) )
) )
.filter(start_at__lte=timezone.now(), end_at__gte=timezone.now()) .filter(start_at__lte=timezone.now(), end_at__gte=timezone.now(), deleted=False)
.order_by("start_at") .order_by("start_at")
] ]
# probably can do some distinct/group by stuff but not sure how tih django queries # probably can do some distinct/group by stuff but not sure how tih django queries
context["next_shifts"] = [ context["next_shifts"] = [
Shift.objects.filter(room=room, start_at__gt=timezone.now()) Shift.objects.filter(room=room, start_at__gt=timezone.now(), deleted=False)
.order_by("start_at") .order_by("start_at")
.first() .first()
for room in Room.objects.all() for room in Room.objects.all()
@ -97,6 +97,10 @@ class FreeShiftList(ShiftList):
title = "Freie Schichten" title = "Freie Schichten"
def get_queryset(self): def get_queryset(self):
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.objects.annotate(reg_count=Count("shiftregistration")).filter(
start_at__gt=timezone.now(), room__required_helpers__gt=F("reg_count") help_wanted,
start_at__gt=timezone.now(),
) )

Loading…
Cancel
Save