|
|
@ -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")
|
|
|
@ -32,14 +32,32 @@ 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(
|
|
|
|
|
|
|
|
deleted=False, calendar__needs_fallback=True
|
|
|
|
day_shifts = ~is_night_shift & ~is_last_night & needs_fallback
|
|
|
|
)
|
|
|
|
night_shifts = is_night_shift & ~is_last_night & needs_fallback
|
|
|
|
selector2 = night_shift_query & Q(deleted=False, calendar__needs_fallback=True)
|
|
|
|
shit_shifts = is_last_night & needs_fallback
|
|
|
|
self._assign_from_bucket(selector1)
|
|
|
|
|
|
|
|
self._assign_from_bucket(selector2)
|
|
|
|
self._assign_from_bucket(day_shifts)
|
|
|
|
|
|
|
|
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 = (
|
|
|
|