generate test data for the reservations

This commit is contained in:
imperosol 2025-04-21 17:26:56 +02:00
parent 691d956c0e
commit c896640923

View File

@ -24,6 +24,7 @@ from counter.models import (
) )
from forum.models import Forum, ForumMessage, ForumTopic from forum.models import Forum, ForumMessage, ForumTopic
from pedagogy.models import UV from pedagogy.models import UV
from reservation.models import ReservationSlot, Room
from subscription.models import Subscription from subscription.models import Subscription
@ -40,45 +41,20 @@ class Command(BaseCommand):
self.stdout.write("Creating users...") self.stdout.write("Creating users...")
users = self.create_users() users = self.create_users()
# len(subscribers) is approximately 480
subscribers = random.sample(users, k=int(0.8 * len(users))) subscribers = random.sample(users, k=int(0.8 * len(users)))
self.stdout.write("Creating subscriptions...") self.stdout.write("Creating subscriptions...")
self.create_subscriptions(subscribers) self.create_subscriptions(subscribers)
self.stdout.write("Creating club memberships...") self.stdout.write("Creating club memberships...")
users_qs = User.objects.filter(id__in=[s.id for s in subscribers]) self.create_club_memberships(subscribers)
subscribers_now = list( self.stdout.write("Creating rooms and reservation...")
users_qs.annotate( self.create_resources_and_reservations(random.sample(subscribers, k=40))
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.stdout.write("Creating uvs...") self.stdout.write("Creating uvs...")
self.create_uvs() self.create_uvs()
self.stdout.write("Creating products...") self.stdout.write("Creating products...")
self.create_products() self.create_products()
self.stdout.write("Creating sales and refills...") 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.create_sales(sellers)
self.stdout.write("Creating permanences...") self.stdout.write("Creating permanences...")
self.create_permanences(sellers) self.create_permanences(sellers)
@ -188,6 +164,99 @@ class Command(BaseCommand):
memberships = Membership.objects.bulk_create(memberships) memberships = Membership.objects.bulk_create(memberships)
Membership._add_club_groups(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): def create_uvs(self):
root = User.objects.get(username="root") root = User.objects.get(username="root")
categories = ["CS", "TM", "OM", "QC", "EC"] categories = ["CS", "TM", "OM", "QC", "EC"]
@ -379,7 +448,7 @@ class Command(BaseCommand):
Permanency.objects.bulk_create(perms) Permanency.objects.bulk_create(perms)
def create_forums(self): 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) most_actives = random.sample(forumers, 10)
categories = list(Forum.objects.filter(is_category=True)) categories = list(Forum.objects.filter(is_category=True))
new_forums = [ new_forums = [
@ -397,7 +466,7 @@ class Command(BaseCommand):
for _ in range(100) for _ in range(100)
] ]
ForumTopic.objects.bulk_create(new_topics) ForumTopic.objects.bulk_create(new_topics)
topics = list(ForumTopic.objects.all()) topics = list(ForumTopic.objects.values_list("id", flat=True))
def get_author(): def get_author():
if random.random() > 0.5: if random.random() > 0.5:
@ -405,7 +474,7 @@ class Command(BaseCommand):
return random.choice(forumers) return random.choice(forumers)
messages = [] messages = []
for t in topics: for topic_id in topics:
nb_messages = max(1, int(random.normalvariate(mu=90, sigma=50))) nb_messages = max(1, int(random.normalvariate(mu=90, sigma=50)))
dates = sorted( dates = sorted(
[ [
@ -417,7 +486,7 @@ class Command(BaseCommand):
messages.extend( messages.extend(
[ [
ForumMessage( ForumMessage(
topic=t, topic_id=topic_id,
author=get_author(), author=get_author(),
date=d, date=d,
message="\n\n".join( message="\n\n".join(