deactivate shift backup assignments if full
This commit is contained in:
parent
12f8c77b80
commit
450556592b
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 4.0.4 on 2023-05-19 16:24
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("fallback", "0005_alter_teammember_id"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="fallbackassignment",
|
||||||
|
name="was_full",
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
]
|
|
@ -170,6 +170,7 @@ class TeamMember(models.Model):
|
||||||
class FallbackAssignment(models.Model):
|
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)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.shift} {self.team_member.name}"
|
return f"{self.shift} {self.team_member.name}"
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
from celery import shared_task
|
||||||
|
from .models import FallbackAssignment
|
||||||
|
from shiftregister.app.models import ShiftRegistration
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import transaction
|
||||||
|
from django.utils import timezone
|
||||||
|
from dynamic_preferences.registries import global_preferences_registry
|
||||||
|
from django.db.models import F, Count, Q, ExpressionWrapper, Case, When
|
||||||
|
from datetime import datetime
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
|
|
||||||
|
global_preferences = global_preferences_registry.manager()
|
||||||
|
|
||||||
|
|
||||||
|
# cron task to send normal messages(reminders,changes) in batches
|
||||||
|
@shared_task
|
||||||
|
def deactivate_fallbacks():
|
||||||
|
for f in FallbackAssignment.objects.annotate(
|
||||||
|
reg_count=Count(
|
||||||
|
"shift__shiftregistration",
|
||||||
|
distinct=True,
|
||||||
|
filter=Q(
|
||||||
|
shift__shiftregistration__state__in=(
|
||||||
|
ShiftRegistration.RegState.REGISTERED,
|
||||||
|
ShiftRegistration.RegState.CHECKED_IN,
|
||||||
|
)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
).filter(
|
||||||
|
was_full=False,
|
||||||
|
shift__start_at__lte=timezone.now()
|
||||||
|
+ global_preferences["helper__min_cancel_time"],
|
||||||
|
shift__required_helpers__lte=F("reg_count"),
|
||||||
|
):
|
||||||
|
f.was_full = True
|
||||||
|
f.save()
|
|
@ -9,7 +9,7 @@
|
||||||
<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>
|
||||||
{% if shifts %}
|
{% 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:
|
||||||
|
|
||||||
|
@ -35,8 +35,9 @@ Diese Schichtzuteilung wurde maschinell erstellt und ist auch ohne Unterschrift
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for shift in shifts %}
|
{% for assignment in assignments %}
|
||||||
<tr{% if shift.registration_count == shift.required_helpers|default:shift.room.required_helpers %} class="has-text-grey" style="text-decoration: line-through;"{% endif %}>
|
{% 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 %}>
|
||||||
<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>
|
||||||
|
@ -52,6 +53,7 @@ Diese Schichtzuteilung wurde maschinell erstellt und ist auch ohne Unterschrift
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
{% endwith %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -25,7 +25,10 @@ def my_fallback_shifts(request, team_member_id):
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
"team_member": team_member,
|
"team_member": team_member,
|
||||||
"shifts": team_member.fallback_shifts.order_by("start_at").all(),
|
"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)
|
||||||
|
|
|
@ -175,6 +175,10 @@ CELERY_BEAT_SCHEDULE = {
|
||||||
"task": "shiftregister.team.tasks.receive_messages",
|
"task": "shiftregister.team.tasks.receive_messages",
|
||||||
"schedule": float(getenv("MESSAGE_RECEIVE_INTERVAL", 300.0)), # seconds
|
"schedule": float(getenv("MESSAGE_RECEIVE_INTERVAL", 300.0)), # seconds
|
||||||
},
|
},
|
||||||
|
"deactivate-fallbacks-every-300-seconds": {
|
||||||
|
"task": "shiftregister.fallback.tasks.deactivate_fallbacks",
|
||||||
|
"schedule": float(getenv("FALLBACK_DEACTIVAtE_INTERVAL", 300.0)), # seconds
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
CELERY_BEAT_SCHEDULE_FILENAME = str(BASE_DIR / "storage" / "celerybeat-schedule")
|
CELERY_BEAT_SCHEDULE_FILENAME = str(BASE_DIR / "storage" / "celerybeat-schedule")
|
||||||
|
|
Loading…
Reference in New Issue