Compare commits
No commits in common. "7242ed2eddb249834fee81ea17735351659fb03f" and "7b4df14bee4d172624a05198de1d9074f91f0dc3" have entirely different histories.
7242ed2edd
...
7b4df14bee
|
@ -26,6 +26,7 @@ class RegisterForm(forms.Form):
|
||||||
name = forms.CharField(
|
name = forms.CharField(
|
||||||
max_length=Helper.name.field.max_length, label="Name", widget=text_input()
|
max_length=Helper.name.field.max_length, label="Name", widget=text_input()
|
||||||
)
|
)
|
||||||
|
# actually verify phone number, lol
|
||||||
phone = PhoneNumberField(
|
phone = PhoneNumberField(
|
||||||
max_length=Helper.phone.field.max_length,
|
max_length=Helper.phone.field.max_length,
|
||||||
label="Handynummer für Benachrichtigungen",
|
label="Handynummer für Benachrichtigungen",
|
||||||
|
|
|
@ -29,9 +29,9 @@ class FallbackAssignmentInline(admin.TabularInline):
|
||||||
|
|
||||||
@admin.register(TeamMember)
|
@admin.register(TeamMember)
|
||||||
class TeamMemberAdmin(admin.ModelAdmin):
|
class TeamMemberAdmin(admin.ModelAdmin):
|
||||||
fields = ("id", "name", "comment", "url")
|
fields = ("id", "name", "url")
|
||||||
readonly_fields = ("id", "url")
|
readonly_fields = ("id", "url")
|
||||||
list_display = ("name", "comment", "shift_count")
|
list_display = ("name", "shift_count")
|
||||||
ordering = ("name",)
|
ordering = ("name",)
|
||||||
inlines = (FallbackAssignmentInline,)
|
inlines = (FallbackAssignmentInline,)
|
||||||
actions = (assign_random_shifts, clear_shifts) # , reshuffle_shifts)
|
actions = (assign_random_shifts, clear_shifts) # , reshuffle_shifts)
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
import sys
|
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand, CommandError
|
|
||||||
|
|
||||||
from ...models import TeamMember
|
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
|
||||||
help = "Import a list of team members, optionally including their affiliations (stored in the comment field)"
|
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
|
||||||
parser.add_argument(
|
|
||||||
"-d",
|
|
||||||
"--delimiter",
|
|
||||||
default=":",
|
|
||||||
help="character separating name from affiliations",
|
|
||||||
)
|
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
|
||||||
try:
|
|
||||||
self._handle(*args, **options)
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
self.stderr.write()
|
|
||||||
except Exception as e:
|
|
||||||
raise CommandError(e)
|
|
||||||
|
|
||||||
def _handle(self, *args, **options):
|
|
||||||
team_members = []
|
|
||||||
for line in sys.stdin.readlines():
|
|
||||||
line = line.strip()
|
|
||||||
if line == "" or line.startswith("#"):
|
|
||||||
continue
|
|
||||||
|
|
||||||
match line.split(options["delimiter"], maxsplit=1):
|
|
||||||
case [name, affiliations]:
|
|
||||||
team_members.append(
|
|
||||||
TeamMember(name=name, comment=affiliations.strip())
|
|
||||||
)
|
|
||||||
case [name]:
|
|
||||||
team_members.append(TeamMember(name=name))
|
|
||||||
|
|
||||||
TeamMember.objects.bulk_create(team_members)
|
|
|
@ -1,18 +0,0 @@
|
||||||
# Generated by Django 5.0.4 on 2024-05-19 21:22
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
("fallback", "0006_fallbackassignment_was_full"),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name="teammember",
|
|
||||||
name="comment",
|
|
||||||
field=models.CharField(default="", max_length=100),
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -1,15 +1,15 @@
|
||||||
import math
|
import math
|
||||||
import secrets
|
import secrets
|
||||||
from base64 import urlsafe_b64encode
|
from base64 import urlsafe_b64encode
|
||||||
from datetime import datetime, time
|
|
||||||
|
|
||||||
from django.db.models import Count, Exists, ExpressionWrapper, Max, OuterRef, Sum
|
from django.db.models import Count, Exists, ExpressionWrapper, Max, OuterRef, Sum
|
||||||
from django.db.models.fields import DateTimeField
|
from django.db.models.fields import DateTimeField
|
||||||
from django.db.models.lookups import LessThan
|
from django.db.models.lookups import LessThan
|
||||||
from django.utils import timezone
|
|
||||||
|
|
||||||
from shiftregister.importer.models import *
|
from shiftregister.importer.models import *
|
||||||
|
|
||||||
|
night_shift_query = Q(start_at__hour__gte=21) | Q(start_at__hour__lte=10)
|
||||||
|
|
||||||
|
|
||||||
def generate_id():
|
def generate_id():
|
||||||
return int.from_bytes(secrets.token_bytes(3), byteorder="big")
|
return int.from_bytes(secrets.token_bytes(3), byteorder="big")
|
||||||
|
@ -18,7 +18,6 @@ def generate_id():
|
||||||
class TeamMember(models.Model):
|
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, default="")
|
|
||||||
fallback_shifts = models.ManyToManyField(Shift, through="FallbackAssignment")
|
fallback_shifts = models.ManyToManyField(Shift, through="FallbackAssignment")
|
||||||
|
|
||||||
def url(self):
|
def url(self):
|
||||||
|
@ -32,32 +31,14 @@ class TeamMember(models.Model):
|
||||||
)
|
)
|
||||||
|
|
||||||
def assign_random_shifts(self):
|
def assign_random_shifts(self):
|
||||||
needs_fallback = Q(deleted=False, calendar__needs_fallback=True)
|
|
||||||
|
|
||||||
current_tz = timezone.get_current_timezone()
|
|
||||||
# create a datetime combining the last date having fallback shifts
|
|
||||||
# after 20:00 with the time 20:00 in the current timezone
|
|
||||||
last_night = datetime.combine(
|
|
||||||
Event.objects.filter(needs_fallback, start_at__hour__gte=20)
|
|
||||||
.latest("start_at")
|
|
||||||
.start_at.astimezone(current_tz),
|
|
||||||
time(hour=20),
|
|
||||||
current_tz,
|
|
||||||
)
|
|
||||||
|
|
||||||
is_last_night = Q(start_at__gte=last_night)
|
|
||||||
is_night_shift = Q(start_at__hour__gte=21) | Q(start_at__hour__lte=10)
|
|
||||||
|
|
||||||
if self.fallback_shifts.count() != 0:
|
if self.fallback_shifts.count() != 0:
|
||||||
return
|
return
|
||||||
|
selector1 = (~night_shift_query) & Q(
|
||||||
day_shifts = ~is_night_shift & ~is_last_night & needs_fallback
|
deleted=False, calendar__needs_fallback=True
|
||||||
night_shifts = is_night_shift & ~is_last_night & needs_fallback
|
)
|
||||||
shit_shifts = is_last_night & needs_fallback
|
selector2 = night_shift_query & Q(deleted=False, calendar__needs_fallback=True)
|
||||||
|
self._assign_from_bucket(selector1)
|
||||||
self._assign_from_bucket(day_shifts)
|
self._assign_from_bucket(selector2)
|
||||||
self._assign_from_bucket(night_shifts)
|
|
||||||
self._assign_from_bucket(shit_shifts)
|
|
||||||
|
|
||||||
def _assign_from_bucket(self, bucket_selector):
|
def _assign_from_bucket(self, bucket_selector):
|
||||||
free_bucket = (
|
free_bucket = (
|
||||||
|
@ -184,7 +165,7 @@ class TeamMember(models.Model):
|
||||||
assignment.delete()
|
assignment.delete()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.name}{f': {self.comment}' if self.comment else ''}"
|
return f"{self.name}"
|
||||||
|
|
||||||
|
|
||||||
class FallbackAssignment(models.Model):
|
class FallbackAssignment(models.Model):
|
||||||
|
|
Loading…
Reference in New Issue