From fecdf70ac54932a71b4dda87ac840f274b641220 Mon Sep 17 00:00:00 2001 From: Luca Date: Mon, 20 May 2024 18:40:19 +0200 Subject: [PATCH] fix(fallback): use fractional part of setpoint as extra shift chance --- shiftregister/fallback/models.py | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/shiftregister/fallback/models.py b/shiftregister/fallback/models.py index ef63d9b..e396051 100644 --- a/shiftregister/fallback/models.py +++ b/shiftregister/fallback/models.py @@ -2,7 +2,9 @@ import math import secrets from base64 import urlsafe_b64encode from datetime import datetime, time +from random import random +import sentry_sdk from django.db.models import Count, Exists, ExpressionWrapper, Max, OuterRef, Sum from django.db.models.fields import DateTimeField from django.db.models.lookups import LessThan @@ -74,17 +76,23 @@ class TeamMember(models.Model): free_slot_count = free_bucket.annotate( needed_helpers=F("required_helpers") - F("fallback_count") ).aggregate(sum=Sum("needed_helpers"))["sum"] - active_team_members = ( - TeamMember.objects.filter(~Q(fallback_shifts=None)).count() + 1 - ) quota = global_preferences["helper__fallback_quota"] number_of_team_members = TeamMember.objects.count() - max_shifts_per_member = math.ceil( - total_slot_count / max((number_of_team_members * quota), 1) + max_shifts_per_member = total_slot_count / max( + number_of_team_members * quota, 1 ) - shifts_per_member = math.ceil(total_slot_count / (active_team_members)) - shift_count = min(max_shifts_per_member, shifts_per_member) + + active_team_members = ( + TeamMember.objects.filter(~Q(fallback_shifts=None)).count() + 1 + ) + shifts_per_member = total_slot_count / active_team_members + + extra_chance, shift_count = math.modf( + min(max_shifts_per_member, shifts_per_member) + ) + if extra_chance > random(): + shift_count += 1 blocked_times = [] for shift in self.fallback_shifts.all(): @@ -174,6 +182,9 @@ class TeamMember(models.Model): break if not assignment: print("could not find any matching assignments to take away") + sentry_sdk.capture_message( + "could not find any matching assignments to take away" + ) return shifts_needed -= 1 blocked_times.append(