Files
n3wt-school/Back-End/School/management/commands/init_mock_datas.py
2025-03-14 19:51:35 +01:00

427 lines
19 KiB
Python

from django.core.management.base import BaseCommand
from Subscriptions.models import (
RegistrationForm,
Student,
Guardian,
Fee,
Discount,
RegistrationFileGroup,
RegistrationTemplateMaster,
RegistrationTemplate
)
from Auth.models import Profile, ProfileRole
from School.models import (
FeeType,
Speciality,
Teacher,
SchoolClass,
PaymentMode,
PaymentModeType,
PaymentPlan,
PaymentPlanType,
DiscountType
)
from django.utils import timezone
from dateutil.relativedelta import relativedelta
from django.core.files import File
from django.core.exceptions import SuspiciousFileOperation
import os
from django.conf import settings
from faker import Faker
import random
import json
from School.serializers import (
FeeSerializer,
DiscountSerializer,
PaymentModeSerializer,
PaymentPlanSerializer,
SpecialitySerializer,
TeacherSerializer,
SchoolClassSerializer
)
from Auth.serializers import ProfileSerializer, ProfileRoleSerializer
from Establishment.serializers import EstablishmentSerializer
from Subscriptions.serializers import RegistrationFormSerializer, StudentSerializer
# Définir le chemin vers le dossier mock_datas
MOCK_DATAS_PATH = os.path.join(settings.BASE_DIR, 'School', 'management', 'mock_datas')
class Command(BaseCommand):
help = 'Initialise toutes les données mock'
def handle(self, *args, **kwargs):
self.init_establishments()
self.init_profiles()
self.init_fees()
self.init_discounts()
self.init_payment_modes()
self.init_payment_plans()
self.init_specialities()
self.init_teachers()
self.init_school_classes()
self.init_file_group()
self.init_register_form()
def load_data(self, filename):
with open(os.path.join(MOCK_DATAS_PATH, filename), 'r') as file:
return json.load(file)
def init_establishments(self):
establishments_data = self.load_data('establishments.json')
self.establishments = []
for establishment_data in establishments_data:
serializer = EstablishmentSerializer(data=establishment_data)
if serializer.is_valid():
establishment = serializer.save()
self.establishments.append(establishment)
self.stdout.write(self.style.SUCCESS(f'Establishment {establishment.name} created or updated successfully'))
else:
self.stdout.write(self.style.ERROR(f'Error in data for establishment: {serializer.errors}'))
def init_profiles(self):
fake = Faker()
for _ in range(50):
# Générer des données fictives pour le profil
profile_data = {
"username": fake.user_name(),
"email": fake.email(),
"password": "Provisoire01!",
"code": "",
"datePeremption": ""
}
# Créer le profil
profile_serializer = ProfileSerializer(data=profile_data)
if profile_serializer.is_valid():
profile = profile_serializer.save()
profile.set_password(profile_data["password"])
profile.save()
self.stdout.write(self.style.SUCCESS(f'Profile {profile.email} created successfully'))
# Créer entre 1 et 3 ProfileRole pour chaque profil
num_roles = random.randint(1, 3)
created_roles = set()
for _ in range(num_roles):
establishment = random.choice(self.establishments)
role_type = random.choice([ProfileRole.RoleType.PROFIL_ECOLE, ProfileRole.RoleType.PROFIL_ADMIN, ProfileRole.RoleType.PROFIL_PARENT])
# Vérifier si le rôle existe déjà pour cet établissement
if (establishment.id, role_type) in created_roles:
continue
profile_role_data = {
"profile": profile.id,
"establishment": establishment.id,
"role_type": role_type,
"is_active": random.choice([True, False])
}
profile_role_serializer = ProfileRoleSerializer(data=profile_role_data)
if profile_role_serializer.is_valid():
profile_role_serializer.save()
created_roles.add((establishment.id, role_type))
self.stdout.write(self.style.SUCCESS(f'ProfileRole for {profile.email} created successfully with role type {role_type}'))
else:
self.stdout.write(self.style.ERROR(f'Error in data for profile role: {profile_role_serializer.errors}'))
else:
self.stdout.write(self.style.ERROR(f'Error in data for profile: {profile_serializer.errors}'))
def init_fees(self):
fees_data = self.load_data('fees.json')
for fee_data in fees_data:
establishment = random.choice(self.establishments)
print(f'establishment : {establishment}')
fee_data["name"] = fee_data['name']
fee_data["establishment"] = establishment.id
fee_data["type"] = random.choice([FeeType.REGISTRATION_FEE, FeeType.TUITION_FEE])
serializer = FeeSerializer(data=fee_data)
if serializer.is_valid():
fee = serializer.save()
self.stdout.write(self.style.SUCCESS(f'Fee {fee.name} created successfully'))
else:
self.stdout.write(self.style.ERROR(f'Error in data for fee: {serializer.errors}'))
def init_discounts(self):
discounts_data = self.load_data('discounts.json')
for discount_data in discounts_data:
establishment = random.choice(self.establishments)
discount_data["name"] = discount_data['name']
discount_data["establishment"] = establishment.id
discount_data["type"] = random.choice([FeeType.REGISTRATION_FEE, FeeType.TUITION_FEE])
discount_data["discount_type"] = random.choice([DiscountType.CURRENCY, DiscountType.PERCENT])
serializer = DiscountSerializer(data=discount_data)
if serializer.is_valid():
discount = serializer.save()
self.stdout.write(self.style.SUCCESS(f'Discount {discount.name} created successfully'))
else:
self.stdout.write(self.style.ERROR(f'Error in data for discount: {serializer.errors}'))
def init_payment_modes(self):
modes = [PaymentModeType.SEPA, PaymentModeType.TRANSFER, PaymentModeType.CHECK, PaymentModeType.CASH]
types = [FeeType.REGISTRATION_FEE, FeeType.TUITION_FEE]
for establishment in self.establishments:
for mode in modes:
for type in types:
payment_mode_data = {
"mode": mode,
"type": type,
"is_active": random.choice([True, False]),
"establishment": establishment.id
}
serializer = PaymentModeSerializer(data=payment_mode_data)
if serializer.is_valid():
payment_mode = serializer.save()
self.stdout.write(self.style.SUCCESS(f'Payment Mode {payment_mode} created successfully'))
else:
self.stdout.write(self.style.ERROR(f'Error in data for payment mode: {serializer.errors}'))
def init_payment_plans(self):
frequencies = [PaymentPlanType.ONE_TIME, PaymentPlanType.THREE_TIMES, PaymentPlanType.TEN_TIMES, PaymentPlanType.TWELVE_TIMES]
types = [FeeType.REGISTRATION_FEE, FeeType.TUITION_FEE]
current_date = timezone.now().date()
for establishment in self.establishments:
for frequency in frequencies:
for type in types:
payment_plan_data = {
"frequency": frequency,
"type": type,
"is_active": random.choice([True, False]),
"establishment": establishment.id,
"due_dates": self.generate_due_dates(frequency, current_date)
}
serializer = PaymentPlanSerializer(data=payment_plan_data)
if serializer.is_valid():
payment_plan = serializer.save()
self.stdout.write(self.style.SUCCESS(f'Payment Plan {payment_plan} created successfully'))
else:
self.stdout.write(self.style.ERROR(f'Error in data for payment plan: {serializer.errors}'))
def generate_due_dates(self, frequency, start_date):
if frequency == PaymentPlanType.ONE_TIME:
return [start_date + relativedelta(months=1)]
elif frequency == PaymentPlanType.THREE_TIMES:
return [start_date + relativedelta(months=1+4*i) for i in range(3)]
elif frequency == PaymentPlanType.TEN_TIMES:
return [start_date + relativedelta(months=1+i) for i in range(10)]
elif frequency == PaymentPlanType.TWELVE_TIMES:
return [start_date + relativedelta(months=1+i) for i in range(12)]
def init_specialities(self):
specialities_data = self.load_data('specialities.json')
for speciality_data in specialities_data:
establishment = random.choice(self.establishments)
speciality_data["name"] = speciality_data['name']
speciality_data["establishment"] = establishment.id
serializer = SpecialitySerializer(data=speciality_data)
if serializer.is_valid():
speciality = serializer.save()
self.stdout.write(self.style.SUCCESS(f'Speciality {speciality.name} created successfully'))
else:
self.stdout.write(self.style.ERROR(f'Error in data for speciality: {serializer.errors}'))
def init_teachers(self):
fake = Faker()
# Récupérer tous les profils existants avec un rôle ECOLE ou ADMIN
profiles_with_roles = Profile.objects.filter(roles__role_type__in=[ProfileRole.RoleType.PROFIL_ECOLE, ProfileRole.RoleType.PROFIL_ADMIN]).distinct()
if not profiles_with_roles.exists():
self.stdout.write(self.style.ERROR('No profiles with role_type ECOLE or ADMIN found'))
return
used_profiles = set()
for _ in range(15):
# Récupérer un profil aléatoire qui n'a pas encore été utilisé
available_profiles = profiles_with_roles.exclude(id__in=used_profiles)
if not available_profiles.exists():
self.stdout.write(self.style.ERROR('Not enough profiles with role_type ECOLE or ADMIN available'))
break
profile = random.choice(available_profiles)
used_profiles.add(profile.id)
# Récupérer les ProfileRole associés au profil avec les rôles ECOLE ou ADMIN
profile_roles = ProfileRole.objects.filter(profile=profile, role_type__in=[ProfileRole.RoleType.PROFIL_ECOLE, ProfileRole.RoleType.PROFIL_ADMIN])
if not profile_roles.exists():
self.stdout.write(self.style.ERROR(f'No ProfileRole with role_type ECOLE or ADMIN found for profile {profile.email}'))
continue
profile_role = random.choice(profile_roles)
# Générer des données fictives pour l'enseignant
teacher_data = {
"last_name": fake.last_name(),
"first_name": fake.first_name(),
"profile_role": profile_role.id
}
establishment_specialities = list(Speciality.objects.filter(establishment=profile_role.establishment))
num_specialities = min(random.randint(1, 3), len(establishment_specialities))
selected_specialities = random.sample(establishment_specialities, num_specialities)
# Créer l'enseignant si il n'existe pas
teacher_serializer = TeacherSerializer(data=teacher_data)
if teacher_serializer.is_valid():
teacher = teacher_serializer.save()
# Associer les spécialités
teacher.specialities.set(selected_specialities)
teacher.save()
self.stdout.write(self.style.SUCCESS(f'Teacher {teacher.last_name} created successfully for establishment {profile_role.establishment.name}'))
else:
self.stdout.write(self.style.ERROR(f'Error in data for teacher: {teacher_serializer.errors}'))
self.stdout.write(self.style.SUCCESS('Teachers initialized or updated successfully'))
def init_school_classes(self):
school_classes_data = self.load_data('school_classes.json')
for index, class_data in enumerate(school_classes_data, start=1):
# Randomize establishment
establishment = random.choice(self.establishments)
class_data["atmosphere_name"] = f"Classe {index}"
class_data["establishment"] = establishment.id
# Randomize levels
class_data["levels"] = random.sample(range(1, 10), random.randint(1, 5))
# Randomize teachers
establishment_teachers = list(Teacher.objects.filter(profile_role__establishment=establishment))
if len(establishment_teachers) > 0:
num_teachers = min(2, len(establishment_teachers))
selected_teachers = random.sample(establishment_teachers, num_teachers)
teachers_ids = [teacher.id for teacher in selected_teachers]
else:
teachers_ids = []
# Use the serializer to create or update the school class
class_data["teachers"] = teachers_ids
serializer = SchoolClassSerializer(data=class_data)
if serializer.is_valid():
school_class = serializer.save()
self.stdout.write(self.style.SUCCESS(f'SchoolClass {school_class.atmosphere_name} created or updated successfully'))
else:
self.stdout.write(self.style.ERROR(f'Error in data for school class: {serializer.errors}'))
self.stdout.write(self.style.SUCCESS('SchoolClasses initialized or updated successfully'))
def init_file_group(self):
fake = Faker()
for establishment in self.establishments:
for i in range(1, 4): # Créer 3 groupes de fichiers par établissement
name = f"Fichiers d'inscription - {fake.word()}"
description = fake.sentence()
group_data = {
"name": name,
"description": description,
"establishment": establishment
}
RegistrationFileGroup.objects.update_or_create(name=name, defaults=group_data)
self.stdout.write(self.style.SUCCESS(f'RegistrationFileGroup {name} initialized or updated successfully'))
self.stdout.write(self.style.SUCCESS('All RegistrationFileGroups initialized or updated successfully'))
def init_register_form(self):
fake = Faker('fr_FR') # Utiliser le locale français pour Faker
file_group_count = RegistrationFileGroup.objects.count()
# Récupérer tous les profils existants avec un ProfileRole Parent
profiles_with_parent_role = Profile.objects.filter(roles__role_type=ProfileRole.RoleType.PROFIL_PARENT).distinct()
if not profiles_with_parent_role.exists():
self.stdout.write(self.style.ERROR('No profiles with ProfileRole Parent found'))
return
used_profiles = set()
for _ in range(50):
# Récupérer un profil aléatoire qui n'a pas encore été utilisé
available_profiles = profiles_with_parent_role.exclude(id__in=used_profiles)
if not available_profiles.exists():
self.stdout.write(self.style.ERROR('Not enough profiles with ProfileRole Parent available'))
break
profile = random.choice(available_profiles)
used_profiles.add(profile.id)
# Récupérer le ProfileRole Parent associé au profil
profile_roles = ProfileRole.objects.filter(profile=profile, role_type=ProfileRole.RoleType.PROFIL_PARENT)
profile_role = random.choice(profile_roles)
# Générer des données fictives pour le guardian
guardian_data = {
"profile_role": profile_role.id,
"last_name": fake.last_name(),
"first_name": fake.first_name(),
"birth_date": fake.date_of_birth().strftime('%Y-%m-%d'),
"address": fake.address(),
"phone": fake.phone_number(),
"profession": fake.job()
}
# Générer des données fictives pour l'étudiant
student_data = {
"last_name": fake.last_name(),
"first_name": fake.first_name(),
"address": fake.address(),
"birth_date": fake.date_of_birth(),
"birth_place": fake.city(),
"birth_postal_code": fake.postcode(),
"nationality": fake.country(),
"attending_physician": fake.name(),
"level": fake.random_int(min=1, max=6),
"guardians": [guardian_data],
"sibling": []
}
# Créer ou mettre à jour l'étudiant
student_serializer = StudentSerializer(data=student_data)
if student_serializer.is_valid():
student = student_serializer.save()
self.stdout.write(self.style.SUCCESS(f'Student {student.last_name} created successfully'))
else:
self.stdout.write(self.style.ERROR(f'Error in data for student: {student_serializer.errors}'))
continue
# Récupérer les frais et les réductions
fees = Fee.objects.filter(id__in=[1, 2, 3, 4])
discounts = Discount.objects.filter(id__in=[1])
# Créer les données du formulaire d'inscription
register_form_data = {
"fileGroup": RegistrationFileGroup.objects.get(id=fake.random_int(min=1, max=file_group_count)),
"establishment": profile_role.establishment,
"status": fake.random_int(min=1, max=3)
}
# Créer ou mettre à jour le formulaire d'inscription
register_form, created = RegistrationForm.objects.get_or_create(
student=student,
establishment=profile_role.establishment,
defaults=register_form_data
)
if created:
register_form.fees.set(fees)
register_form.discounts.set(discounts)
self.stdout.write(self.style.SUCCESS(f'RegistrationForm for student {student.last_name} created successfully'))
else:
self.stdout.write(self.style.SUCCESS(f'RegistrationForm for student {student.last_name} already exists'))
self.stdout.write(self.style.SUCCESS('50 RegistrationForms initialized or updated successfully'))