main #1

Merged
xAndy merged 12 commits from main into live 2025-05-15 23:25:56 +02:00
5 changed files with 86 additions and 25 deletions
Showing only changes of commit 6e45b1543b - Show all commits

View File

@ -30,7 +30,7 @@ class FallbackAssignmentInline(admin.TabularInline):
@admin.register(TeamMember)
class TeamMemberAdmin(admin.ModelAdmin):
fields = ("id", "name", "comment", "url")
fields = ("id", "name", "comment", "url", "pin")
readonly_fields = ("id", "url")
list_display = ("name", "comment", "shift_count")
ordering = ("name",)

View File

@ -0,0 +1,22 @@
# Generated by Django 5.0.4 on 2025-05-14 11:55
from django.db import migrations, models
import shiftregister.fallback.models
class Migration(migrations.Migration):
dependencies = [
("fallback", "0009_fallbackassignment_traded_to"),
]
operations = [
migrations.AddField(
model_name="teammember",
name="pin",
field=models.IntegerField(
default=shiftregister.fallback.models.generate_pin
),
),
]

View File

@ -2,7 +2,7 @@ import math
import secrets
from base64 import urlsafe_b64encode
from datetime import datetime, time
from random import random
from random import randint, random
import sentry_sdk
from django.db.models import Count, Exists, ExpressionWrapper, Max, OuterRef, Sum
@ -17,10 +17,15 @@ def generate_id():
return int.from_bytes(secrets.token_bytes(3), byteorder="big")
def generate_pin():
return randint(1000, 9999)
class TeamMember(models.Model):
id = models.IntegerField(default=generate_id, editable=False, primary_key=True)
name = models.CharField(max_length=100)
comment = models.CharField(max_length=100, blank=True, default="")
pin = models.IntegerField(default=generate_pin)
fallback_shifts = models.ManyToManyField(
Shift, through="FallbackAssignment", through_fields=("team_member", "shift")
)

View File

@ -16,12 +16,24 @@
{% csrf_token %}
<div class="field has-addons">
<div class="control">
<input class="input" type="number" name="assignment_id" placeholder="Assignment ID" required>
{{ trade_form.assignment_id }}
</div>
<div class="control">
{{ trade_form.pin }}
</div>
<div class="control">
<button type="submit" name="take_shift" class="button is-info">Übernehmen/Entfernen</button>
</div>
</div>
{% if form.errors %}
<div class="field">
{% for field in trade_form %}
{% for error in field.errors %}
<p class="help is-danger">{{ error }}</p>
{% endfor %}
{% endfor %}
</div>
{% endif %}
</form>
</div>
@ -31,6 +43,8 @@
{{ team_member.url }}
Deine PIN um Schichten zu übernehmen ist {{ team_member.pin }}
Deine Schichten werden in den nächsten Tagen weniger werden, wenn wir alle Schichten unter mehr Teammitgliedern verteilen.
Du kannst unter dem Link immer nachschauen, welche Schichten du noch hast und welche schon von Helfis belegt sind.
Bei Schichten mit mehreren Personen, bei denen nicht alle von Helfis belegt sind, koordiniere dich bitte mit den anderen Teammitgliedern, wer von euch die Schicht übernimmt.

View File

@ -1,5 +1,6 @@
from base64 import urlsafe_b64decode
from django import forms
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.db.models import Count, Q
@ -9,7 +10,14 @@ from django.urls import reverse
from shiftregister.fallback.models import FallbackAssignment, TeamMember
# Create your views here.
class TradeForm(forms.Form):
assignment_id = forms.IntegerField(
widget=forms.NumberInput(attrs={"class": "input", "placeholder": "Schicht-ID"})
)
pin = forms.IntegerField(
widget=forms.NumberInput(attrs={"class": "input", "placeholder": "Deine PIN"})
)
def my_fallback_shifts(request, team_member_id):
@ -23,32 +31,43 @@ def my_fallback_shifts(request, team_member_id):
team_member = get_object_or_404(TeamMember, pk=team_member_id)
is_draw = False
trade_form = TradeForm(
request.POST
if request.method == "POST" and "take_shift" in request.POST
else None
)
if request.method == "POST":
if "draw_shifts" in request.POST:
team_member.assign_random_shifts()
is_draw = True
elif "take_shift" in request.POST:
assignment_id = request.POST.get("assignment_id")
try:
assignment = FallbackAssignment.objects.get(pk=assignment_id)
if assignment.team_member == team_member:
assignment.traded_to = None
messages.success(request, f"Schicht erfolgreich zurückgenommen")
elif assignment.traded_to == team_member:
assignment.traded_to = None
messages.success(request, f"Schicht erfolgreich zurückgegeben")
else:
assignment.traded_to = team_member
messages.success(request, f"Schicht erfolgreich übernommen")
assignment.save()
return redirect(
reverse(
"my_fallback_shifts",
kwargs={"team_member_id": team_member.url_id()},
elif "take_shift" in request.POST and trade_form.is_valid():
assignment_id = trade_form.cleaned_data["assignment_id"]
pin = trade_form.cleaned_data["pin"]
if pin != team_member.pin:
messages.error(request, "Ungültige PIN")
else:
try:
assignment = FallbackAssignment.objects.get(pk=assignment_id)
if assignment.team_member == team_member:
assignment.traded_to = None
messages.success(request, f"Schicht erfolgreich zurückgenommen")
elif assignment.traded_to == team_member:
assignment.traded_to = None
messages.success(request, f"Schicht erfolgreich zurückgegeben")
else:
assignment.traded_to = team_member
messages.success(request, f"Schicht erfolgreich übernommen")
assignment.save()
return redirect(
reverse(
"my_fallback_shifts",
kwargs={"team_member_id": team_member.url_id()},
)
)
)
except FallbackAssignment.DoesNotExist:
messages.error(request, "Ungültige Schicht-ID")
except FallbackAssignment.DoesNotExist:
messages.error(request, "Ungültige Schicht-ID")
assignments = (
FallbackAssignment.objects.filter(
@ -63,6 +82,7 @@ def my_fallback_shifts(request, team_member_id):
"team_member": team_member,
"assignments": assignments,
"is_draw": is_draw,
"trade_form": trade_form,
}
return render(request, "my_fallback_shifts.html", context)