From c896640923aac547dc17b31668cac73352bcf206 Mon Sep 17 00:00:00 2001 From: imperosol Date: Mon, 21 Apr 2025 17:26:56 +0200 Subject: [PATCH] generate test data for the reservations --- core/management/commands/populate_more.py | 137 ++++++++++++++++------ 1 file changed, 103 insertions(+), 34 deletions(-) diff --git a/core/management/commands/populate_more.py b/core/management/commands/populate_more.py index 447b6b98..06e5b3e6 100644 --- a/core/management/commands/populate_more.py +++ b/core/management/commands/populate_more.py @@ -24,6 +24,7 @@ from counter.models import ( ) from forum.models import Forum, ForumMessage, ForumTopic from pedagogy.models import UV +from reservation.models import ReservationSlot, Room from subscription.models import Subscription @@ -40,45 +41,20 @@ class Command(BaseCommand): self.stdout.write("Creating users...") users = self.create_users() + # len(subscribers) is approximately 480 subscribers = random.sample(users, k=int(0.8 * len(users))) self.stdout.write("Creating subscriptions...") self.create_subscriptions(subscribers) self.stdout.write("Creating club memberships...") - users_qs = User.objects.filter(id__in=[s.id for s in subscribers]) - subscribers_now = list( - users_qs.annotate( - filter=Exists( - Subscription.objects.filter( - member_id=OuterRef("pk"), subscription_end__gte=now() - ) - ) - ) - ) - old_subscribers = list( - users_qs.annotate( - filter=Exists( - Subscription.objects.filter( - member_id=OuterRef("pk"), subscription_end__lt=now() - ) - ) - ) - ) - self.make_club( - Club.objects.get(id=settings.SITH_MAIN_CLUB_ID), - random.sample(subscribers_now, k=min(30, len(subscribers_now))), - random.sample(old_subscribers, k=min(60, len(old_subscribers))), - ) - self.make_club( - Club.objects.get(name="Troll Penché"), - random.sample(subscribers_now, k=min(20, len(subscribers_now))), - random.sample(old_subscribers, k=min(80, len(old_subscribers))), - ) + self.create_club_memberships(subscribers) + self.stdout.write("Creating rooms and reservation...") + self.create_resources_and_reservations(random.sample(subscribers, k=40)) self.stdout.write("Creating uvs...") self.create_uvs() self.stdout.write("Creating products...") self.create_products() self.stdout.write("Creating sales and refills...") - sellers = random.sample(list(User.objects.all()), 100) + sellers = list(User.objects.order_by("?")[:100]) self.create_sales(sellers) self.stdout.write("Creating permanences...") self.create_permanences(sellers) @@ -188,6 +164,99 @@ class Command(BaseCommand): memberships = Membership.objects.bulk_create(memberships) Membership._add_club_groups(memberships) + def create_club_memberships(self, users: list[User]): + users_qs = User.objects.filter(id__in=[s.id for s in users]) + subscribers_now = list( + users_qs.annotate( + filter=Exists( + Subscription.objects.filter( + member_id=OuterRef("pk"), subscription_end__gte=now() + ) + ) + ) + ) + old_subscribers = list( + users_qs.annotate( + filter=Exists( + Subscription.objects.filter( + member_id=OuterRef("pk"), subscription_end__lt=now() + ) + ) + ) + ) + self.make_club( + Club.objects.get(id=settings.SITH_MAIN_CLUB_ID), + random.sample(subscribers_now, k=min(30, len(subscribers_now))), + random.sample(old_subscribers, k=min(60, len(old_subscribers))), + ) + self.make_club( + Club.objects.get(name="Troll Penché"), + random.sample(subscribers_now, k=min(20, len(subscribers_now))), + random.sample(old_subscribers, k=min(80, len(old_subscribers))), + ) + + def create_resources_and_reservations(self, users: list[User]): + """Generate reservable rooms and reservations slots for those rooms. + + Contrary to the other data generator, + this one generates more data than what is expected on the real db. + """ + ae = Club.objects.get(id=settings.SITH_MAIN_CLUB_ID) + pdf = Club.objects.get(id=settings.SITH_PDF_CLUB_ID) + troll = Club.objects.get(name="Troll Penché") + rooms = [ + Room( + name=name, + club=club, + address=self.faker.address(), + description=self.faker.text(100), + ) + for name, club in [ + ("Champi", ae), + ("Muzik", ae), + ("Pôle Tech", ae), + ("Jolly", troll), + ("Cookut", pdf), + ("Lucky", pdf), + ] + ] + rooms = Room.objects.bulk_create(rooms) + reservations = [] + for room in rooms: + # how much people use this room. + # The higher the number, the more reservations exist, + # the more people are present in a slot, + # the smaller the interval between two slot is, + # and the more future reservations have already been made ahead of time + affluence = random.randint(2, 6) + slot_start = make_aware(self.faker.past_datetime("-5y")) + generate_until = make_aware( + self.faker.future_datetime(timedelta(days=1) * affluence**2) + ) + while slot_start < generate_until: + if slot_start.hour < 8: + # if a reservation would start in the middle of the night + # make it start the next morning instead + slot_start += timedelta(hours=10 - slot_start.hour) + duration = timedelta(minutes=15) * (1 + int(random.gammavariate(3, 2))) + reservations.append( + ReservationSlot( + room=room, + nb_people=( + 1 + random.binomialvariate(affluence * 10, affluence / 10) + ), + author=random.choice(users), + start_at=slot_start, + duration=duration, + created_at=slot_start - self.faker.time_delta("+7d"), + ) + ) + slot_start += duration + ( + timedelta(hours=1) * random.expovariate(affluence / 48) + ) + reservations.sort(key=lambda slot: slot.created_at) + ReservationSlot.objects.bulk_create(reservations) + def create_uvs(self): root = User.objects.get(username="root") categories = ["CS", "TM", "OM", "QC", "EC"] @@ -379,7 +448,7 @@ class Command(BaseCommand): Permanency.objects.bulk_create(perms) def create_forums(self): - forumers = random.sample(list(User.objects.all()), 100) + forumers = list(User.objects.order_by("?")[:100]) most_actives = random.sample(forumers, 10) categories = list(Forum.objects.filter(is_category=True)) new_forums = [ @@ -397,7 +466,7 @@ class Command(BaseCommand): for _ in range(100) ] ForumTopic.objects.bulk_create(new_topics) - topics = list(ForumTopic.objects.all()) + topics = list(ForumTopic.objects.values_list("id", flat=True)) def get_author(): if random.random() > 0.5: @@ -405,7 +474,7 @@ class Command(BaseCommand): return random.choice(forumers) messages = [] - for t in topics: + for topic_id in topics: nb_messages = max(1, int(random.normalvariate(mu=90, sigma=50))) dates = sorted( [ @@ -417,7 +486,7 @@ class Command(BaseCommand): messages.extend( [ ForumMessage( - topic=t, + topic_id=topic_id, author=get_author(), date=d, message="\n\n".join(