Compare commits

..

No commits in common. "f55b653ccda9aefc7ef98ce4e436614e08cd30b8" and "dd3bf01529bde4b137ab730c903334baa5558d56" have entirely different histories.

9 changed files with 22 additions and 128 deletions

View File

@ -1,6 +1,5 @@
from datetime import timedelta
from django.test import TestCase from django.test import TestCase
from datetime import timedelta
from django.utils import timezone from django.utils import timezone
from .models import Helper, Room, Shift, ShiftRegistration from .models import Helper, Room, Shift, ShiftRegistration

View File

@ -25,7 +25,6 @@ class FallbackAssignmentInline(admin.TabularInline):
model = FallbackAssignment model = FallbackAssignment
ordering = ("shift__start_at",) ordering = ("shift__start_at",)
readonly_fields = ("shift",) readonly_fields = ("shift",)
fk_name = "team_member"
@admin.register(TeamMember) @admin.register(TeamMember)

View File

@ -1,25 +0,0 @@
# Generated by Django 5.0.4 on 2025-05-14 11:39
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("fallback", "0008_alter_teammember_comment"),
]
operations = [
migrations.AddField(
model_name="fallbackassignment",
name="traded_to",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="received_trades",
to="fallback.teammember",
),
),
]

View File

@ -21,19 +21,18 @@ class TeamMember(models.Model):
id = models.IntegerField(default=generate_id, editable=False, primary_key=True) id = models.IntegerField(default=generate_id, editable=False, primary_key=True)
name = models.CharField(max_length=100) name = models.CharField(max_length=100)
comment = models.CharField(max_length=100, blank=True, default="") comment = models.CharField(max_length=100, blank=True, default="")
fallback_shifts = models.ManyToManyField( fallback_shifts = models.ManyToManyField(Shift, through="FallbackAssignment")
Shift, through="FallbackAssignment", through_fields=("team_member", "shift")
)
def url(self): def url(self):
return "https://helfen.kntkt.de" + reverse( return "https://helfen.kntkt.de" + reverse(
"my_fallback_shifts", "my_fallback_shifts",
kwargs={"team_member_id": self.url_id()}, kwargs={
"team_member_id": urlsafe_b64encode(
self.id.to_bytes(3, byteorder="big")
).decode("utf-8")
},
) )
def url_id(self):
return urlsafe_b64encode(self.id.to_bytes(3, byteorder="big")).decode("utf-8")
def assign_random_shifts(self): def assign_random_shifts(self):
needs_fallback = Q(deleted=False, calendar__needs_fallback=True) needs_fallback = Q(deleted=False, calendar__needs_fallback=True)
@ -200,15 +199,6 @@ class FallbackAssignment(models.Model):
shift = models.ForeignKey(Shift, on_delete=models.CASCADE) shift = models.ForeignKey(Shift, on_delete=models.CASCADE)
team_member = models.ForeignKey(TeamMember, on_delete=models.CASCADE) team_member = models.ForeignKey(TeamMember, on_delete=models.CASCADE)
was_full = models.BooleanField(default=False) was_full = models.BooleanField(default=False)
traded_to = models.ForeignKey(
TeamMember,
on_delete=models.CASCADE,
null=True,
blank=True,
related_name="received_trades",
)
def __str__(self): def __str__(self):
if self.traded_to:
return f"{self.shift} {self.team_member.name} -> {self.traded_to.name}"
return f"{self.shift} {self.team_member.name}" return f"{self.shift} {self.team_member.name}"

View File

@ -9,22 +9,6 @@
<div class="content"> <div class="content">
<a href="{% url 'pages:view' 'team_faq' %}">Häufig gestellte Fragen zu Teamschichten</a> <a href="{% url 'pages:view' 'team_faq' %}">Häufig gestellte Fragen zu Teamschichten</a>
</div> </div>
<div class="box">
<h4 class="subtitle">Schicht übernehmen</h4>
<form method="POST">
{% csrf_token %}
<div class="field has-addons">
<div class="control">
<input class="input" type="number" name="assignment_id" placeholder="Assignment ID" required>
</div>
<div class="control">
<button type="submit" name="take_shift" class="button is-info">Übernehmen/Entfernen</button>
</div>
</div>
</form>
</div>
{% if assignments %} {% if assignments %}
{% if is_draw %} {% if is_draw %}
<pre class="mb-5 select_all">Hallo {{ team_member.name }}, hier deine Teamschichten für das Festival: <pre class="mb-5 select_all">Hallo {{ team_member.name }}, hier deine Teamschichten für das Festival:
@ -42,7 +26,6 @@ Diese Schichtzuteilung wurde maschinell erstellt und ist auch ohne Unterschrift
<table class="table"> <table class="table">
<thead> <thead>
<tr> <tr>
<th>Tausch-ID</th>
<th>Wann</th> <th>Wann</th>
<th>Wie lange</th> <th>Wie lange</th>
<th>Wo</th> <th>Wo</th>
@ -55,19 +38,13 @@ Diese Schichtzuteilung wurde maschinell erstellt und ist auch ohne Unterschrift
{% for assignment in assignments %} {% for assignment in assignments %}
{% with assignment.shift as shift %} {% with assignment.shift as shift %}
<tr{% if shift.registration_count == shift.required_helpers|default:shift.room.required_helpers or assignment.was_full %} class="has-text-grey" style="text-decoration: line-through;"{% endif %}> <tr{% if shift.registration_count == shift.required_helpers|default:shift.room.required_helpers or assignment.was_full %} class="has-text-grey" style="text-decoration: line-through;"{% endif %}>
<td>{{ assignment.id }} {% if assignment.traded_to %}*{% endif %}</td>
<td>{{ shift.start_at }}</td> <td>{{ shift.start_at }}</td>
<td>{{ shift.duration|duration }}</td> <td>{{ shift.duration|duration }}</td>
<td>{{ shift.room.name }} </td> <td>{{ shift.room.name }} </td>
<td>{{ shift.registration_count }}/{{ shift.required_helpers|default:shift.room.required_helpers }}</td> <td>{{ shift.registration_count }}/{{ shift.required_helpers|default:shift.room.required_helpers }}</td>
<td> <td>
{% for fa in shift.fallbackassignment_set.all %} {% for assignment in shift.fallbackassignment_set.all %}
{% if fa.traded_to %} {{ assignment.team_member.name }}{% if not forloop.last %}, {% endif %}
{{ fa.traded_to.name }}
{% else %}
{{ fa.team_member.name }}
{% endif %}
{% if not forloop.last %}, {% endif %}
{% endfor %} {% endfor %}
</td> </td>
<td> <td>
@ -84,7 +61,7 @@ Diese Schichtzuteilung wurde maschinell erstellt und ist auch ohne Unterschrift
{% if user.is_authenticated %} {% if user.is_authenticated %}
<form method="POST"> <form method="POST">
{% csrf_token %} {% csrf_token %}
<button class="button is-success" type="submit" name="draw_shifts">Schichten zulosen</button> <button class="button is-success" type="submit">Schichten zulosen</button>
</form> </form>
{% else %} {% else %}
Noch keine Schichten zugewiesen, bitte wende dich an den Infopoint. Noch keine Schichten zugewiesen, bitte wende dich an den Infopoint.

View File

@ -1,13 +1,11 @@
from base64 import urlsafe_b64decode from base64 import urlsafe_b64decode
from django.contrib import messages
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.db.models import Count, Q from django.db.models import Count
from django.http import HttpResponse from django.http import HttpResponse
from django.shortcuts import get_object_or_404, redirect, render from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from shiftregister.fallback.models import FallbackAssignment, TeamMember from shiftregister.fallback.models import TeamMember
# Create your views here. # Create your views here.
@ -24,44 +22,15 @@ def my_fallback_shifts(request, team_member_id):
is_draw = False is_draw = False
if request.method == "POST": if request.method == "POST":
if "draw_shifts" in request.POST: team_member.assign_random_shifts()
team_member.assign_random_shifts() is_draw = True
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()},
)
)
except FallbackAssignment.DoesNotExist:
messages.error(request, "Ungültige Schicht-ID")
assignments = (
FallbackAssignment.objects.filter(
Q(team_member=team_member, traded_to__isnull=True)
| Q(traded_to=team_member)
)
.prefetch_related("shift", "traded_to", "team_member")
.order_by("shift__start_at")
)
context = { context = {
"team_member": team_member, "team_member": team_member,
"assignments": assignments, "assignments": team_member.fallbackassignment_set.order_by(
"shift__start_at"
).all(),
# "shifts": team_member.fallback_shifts.order_by("start_at").all(),
"is_draw": is_draw, "is_draw": is_draw,
} }
return render(request, "my_fallback_shifts.html", context) return render(request, "my_fallback_shifts.html", context)

View File

@ -18,18 +18,7 @@
<tr> <tr>
<td>{{ shift.room.name }}</td> <td>{{ shift.room.name }}</td>
<td>{{ shift.start_at }}</td> <td>{{ shift.start_at }}</td>
<td> <td>{% for fa in shift.fallbackassignment_set.all %}{% if not fa.was_full %}{{ fa.team_member.name }}{% if not forloop.last %}, {% endif %}{% endif %}{% endfor %}</td>
{% for fa in shift.fallbackassignment_set.all %}
{% if not fa.was_full %}
{% if fa.traded_to %}
{{ fa.traded_to.name }} ({{ fa.id }})
{% else %}
{{ fa.team_member.name }} ({{ fa.id }})
{% endif %}
{% if not forloop.last %}, {% endif %}
{% endif %}
{% endfor %}
</td>
</tr> </tr>
{% empty %} {% empty %}
<tr> <tr>

View File

@ -59,11 +59,7 @@
{% for fallback in shift.event.fallbackassignment_set.all %} {% for fallback in shift.event.fallbackassignment_set.all %}
<div class="column is-one-quarter"> <div class="column is-one-quarter">
<div class="box{% if fallback.was_full %} has-text-grey" style="text-decoration: line-through;{% endif %}"> <div class="box{% if fallback.was_full %} has-text-grey" style="text-decoration: line-through;{% endif %}">
{% if fallback.traded_to %} {{ fallback.team_member.name }}
{{ fallback.traded_to.name }}
{% else %}
{{ fallback.team_member.name }}
{% endif %}
</div> </div>
</div> </div>
{% endfor %} {% endfor %}

View File

@ -14,9 +14,9 @@ Including another URLconf
2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
""" """
from django.conf import settings
from django.contrib import admin from django.contrib import admin
from django.urls import include, path from django.urls import include, path
from django.conf import settings
urlpatterns = [ urlpatterns = [
path("", include("shiftregister.metrics.urls")), path("", include("shiftregister.metrics.urls")),