mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-01-29 07:53:23 +00:00
246 lines
9.3 KiB
Python
246 lines
9.3 KiB
Python
from django.db import models
|
||
from django.utils.timezone import now
|
||
from django.conf import settings
|
||
from django.utils.translation import gettext_lazy as _
|
||
|
||
from Auth.models import Profile
|
||
from School.models import SchoolClass, Fee, Discount, Establishment
|
||
|
||
from datetime import datetime
|
||
|
||
class Language(models.Model):
|
||
"""
|
||
Représente une langue parlée par l’élève.
|
||
"""
|
||
id = models.AutoField(primary_key=True)
|
||
label = models.CharField(max_length=200, default="")
|
||
|
||
def __str__(self):
|
||
return "LANGUAGE"
|
||
|
||
class Guardian(models.Model):
|
||
"""
|
||
Représente un responsable légal (parent/tuteur) d’un élève.
|
||
"""
|
||
last_name = models.CharField(max_length=200, default="")
|
||
first_name = models.CharField(max_length=200, default="")
|
||
birth_date = models.CharField(max_length=200, default="", blank=True)
|
||
address = models.CharField(max_length=200, default="", blank=True)
|
||
email = models.CharField(max_length=200, default="", blank=True)
|
||
phone = models.CharField(max_length=200, default="", blank=True)
|
||
profession = models.CharField(max_length=200, default="", blank=True)
|
||
associated_profile = models.ForeignKey(Profile, on_delete=models.CASCADE)
|
||
|
||
def __str__(self):
|
||
return self.last_name + "_" + self.first_name
|
||
|
||
class Sibling(models.Model):
|
||
"""
|
||
Représente un frère ou une sœur d’un élève.
|
||
"""
|
||
id = models.AutoField(primary_key=True)
|
||
last_name = models.CharField(max_length=200, default="")
|
||
first_name = models.CharField(max_length=200, default="")
|
||
birth_date = models.CharField(max_length=200, default="", blank=True)
|
||
|
||
def __str__(self):
|
||
return "SIBLING"
|
||
|
||
class Student(models.Model):
|
||
"""
|
||
Représente l’élève inscrit ou en cours d’inscription.
|
||
"""
|
||
class StudentGender(models.IntegerChoices):
|
||
NONE = 0, _('Sélection du genre')
|
||
MALE = 1, _('Garçon')
|
||
FEMALE = 2, _('Fille')
|
||
|
||
class StudentLevel(models.IntegerChoices):
|
||
NONE = 0, _('Sélection du niveau')
|
||
TPS = 1, _('TPS - Très Petite Section')
|
||
PS = 2, _('PS - Petite Section')
|
||
MS = 3, _('MS - Moyenne Section')
|
||
GS = 4, _('GS - Grande Section')
|
||
|
||
class PaymentMethod(models.IntegerChoices):
|
||
NONE = 0, _('Sélection du mode de paiement')
|
||
SEPA_DIRECT_DEBIT = 1, _('Prélèvement SEPA')
|
||
CHECK = 2, _('Chèques')
|
||
|
||
last_name = models.CharField(max_length=200, default="")
|
||
first_name = models.CharField(max_length=200, default="")
|
||
gender = models.IntegerField(choices=StudentGender, default=StudentGender.NONE, blank=True)
|
||
level = models.IntegerField(choices=StudentLevel, default=StudentLevel.NONE, blank=True)
|
||
nationality = models.CharField(max_length=200, default="", blank=True)
|
||
address = models.CharField(max_length=200, default="", blank=True)
|
||
birth_date = models.DateField(null=True, blank=True)
|
||
birth_place = models.CharField(max_length=200, default="", blank=True)
|
||
birth_postal_code = models.IntegerField(default=0, blank=True)
|
||
attending_physician = models.CharField(max_length=200, default="", blank=True)
|
||
payment_method = models.IntegerField(choices=PaymentMethod, default=PaymentMethod.NONE, blank=True)
|
||
|
||
# Many-to-Many Relationship
|
||
profiles = models.ManyToManyField(Profile, blank=True)
|
||
|
||
# Many-to-Many Relationship
|
||
guardians = models.ManyToManyField(Guardian, blank=True)
|
||
|
||
# Many-to-Many Relationship
|
||
siblings = models.ManyToManyField(Sibling, blank=True)
|
||
|
||
# Many-to-Many Relationship
|
||
registration_files = models.ManyToManyField('RegistrationTemplate', blank=True, related_name='students')
|
||
|
||
# Many-to-Many Relationship
|
||
spoken_languages = models.ManyToManyField(Language, blank=True)
|
||
|
||
# One-to-Many Relationship
|
||
associated_class = models.ForeignKey(SchoolClass, on_delete=models.SET_NULL, null=True, blank=True, related_name='students')
|
||
|
||
def __str__(self):
|
||
return self.last_name + "_" + self.first_name
|
||
|
||
def getSpokenLanguages(self):
|
||
"""
|
||
Retourne la liste des langues parlées par l’élève.
|
||
"""
|
||
return self.spoken_languages.all()
|
||
|
||
def getMainGuardian(self):
|
||
"""
|
||
Retourne le responsable légal principal de l’élève.
|
||
"""
|
||
return self.guardians.all()[0]
|
||
|
||
def getGuardians(self):
|
||
"""
|
||
Retourne tous les responsables légaux de l’élève.
|
||
"""
|
||
return self.guardians.all()
|
||
|
||
def getProfiles(self):
|
||
"""
|
||
Retourne les profils utilisateurs liés à l’élève.
|
||
"""
|
||
return self.profiles.all()
|
||
|
||
def getSiblings(self):
|
||
"""
|
||
Retourne les frères et sœurs de l’élève.
|
||
"""
|
||
return self.siblings.all()
|
||
|
||
def getNumberOfSiblings(self):
|
||
"""
|
||
Retourne le nombre de frères et sœurs.
|
||
"""
|
||
return self.siblings.count()
|
||
|
||
@property
|
||
def age(self):
|
||
if self.birth_date:
|
||
today = datetime.today()
|
||
years = today.year - self.birth_date.year
|
||
months = today.month - self.birth_date.month
|
||
if today.day < self.birth_date.day:
|
||
months -= 1
|
||
if months < 0:
|
||
years -= 1
|
||
months += 12
|
||
|
||
# Determine the age format
|
||
if 6 <= months <= 12:
|
||
return f"{years} years 1/2"
|
||
else:
|
||
return f"{years} years"
|
||
return None
|
||
|
||
@property
|
||
def formatted_birth_date(self):
|
||
if self.birth_date:
|
||
return self.birth_date.strftime('%d-%m-%Y')
|
||
return None
|
||
|
||
class RegistrationFileGroup(models.Model):
|
||
name = models.CharField(max_length=255, default="")
|
||
description = models.TextField(blank=True, null=True)
|
||
|
||
def __str__(self):
|
||
return self.name
|
||
|
||
def registration_file_path(instance, filename):
|
||
# Génère le chemin : registration_files/dossier_rf_{student_id}/filename
|
||
return f'registration_files/dossier_rf_{instance.student_id}/{filename}'
|
||
|
||
class RegistrationTemplateMaster(models.Model):
|
||
groups = models.ManyToManyField(RegistrationFileGroup, related_name='template_masters', blank=True)
|
||
id = models.IntegerField(primary_key=True)
|
||
name = models.CharField(max_length=255, default="")
|
||
is_required = models.BooleanField(default=False)
|
||
|
||
def __str__(self):
|
||
return f'{self.group.name} - {self.id}'
|
||
|
||
class RegistrationForm(models.Model):
|
||
class RegistrationFormStatus(models.IntegerChoices):
|
||
RF_ABSENT = 0, _('Pas de dossier d\'inscription')
|
||
RF_CREATED = 1, _('Dossier d\'inscription créé')
|
||
RF_SENT = 2, _('Dossier d\'inscription envoyé')
|
||
RF_UNDER_REVIEW = 3, _('Dossier d\'inscription en cours de validation')
|
||
RF_TO_BE_FOLLOWED_UP = 4, _('Dossier d\'inscription à relancer')
|
||
RF_VALIDATED = 5, _('Dossier d\'inscription validé')
|
||
RF_ARCHIVED = 6, _('Dossier d\'inscription archivé')
|
||
|
||
# One-to-One Relationship
|
||
student = models.OneToOneField(Student, on_delete=models.CASCADE, primary_key=True)
|
||
status = models.IntegerField(choices=RegistrationFormStatus, default=RegistrationFormStatus.RF_ABSENT)
|
||
last_update = models.DateTimeField(auto_now=True)
|
||
notes = models.CharField(max_length=200, blank=True)
|
||
registration_link_code = models.CharField(max_length=200, default="", blank=True)
|
||
registration_file = models.FileField(
|
||
upload_to=registration_file_path,
|
||
null=True,
|
||
blank=True
|
||
)
|
||
associated_rf = models.CharField(max_length=200, default="", blank=True)
|
||
|
||
# Many-to-Many Relationship
|
||
fees = models.ManyToManyField(Fee, blank=True, related_name='register_forms')
|
||
|
||
# Many-to-Many Relationship
|
||
discounts = models.ManyToManyField(Discount, blank=True, related_name='register_forms')
|
||
fileGroup = models.ForeignKey(RegistrationFileGroup,
|
||
on_delete=models.CASCADE,
|
||
related_name='register_forms',
|
||
null=True,
|
||
blank=True)
|
||
|
||
establishment = models.ForeignKey(Establishment, on_delete=models.CASCADE, related_name='register_forms')
|
||
|
||
def __str__(self):
|
||
return "RF_" + self.student.last_name + "_" + self.student.first_name
|
||
|
||
def registration_file_upload_to(instance, filename):
|
||
return f"registration_files/dossier_rf_{instance.registration_form.pk}/{filename}"
|
||
|
||
class RegistrationTemplate(models.Model):
|
||
master = models.ForeignKey(RegistrationTemplateMaster, on_delete=models.CASCADE, related_name='templates', blank=True)
|
||
id = models.IntegerField(primary_key=True)
|
||
slug = models.CharField(max_length=255, default="")
|
||
name = models.CharField(max_length=255, default="")
|
||
registration_form = models.ForeignKey(RegistrationForm, on_delete=models.CASCADE, related_name='templates', blank=True)
|
||
file = models.FileField(null=True,blank=True, upload_to=registration_file_upload_to)
|
||
|
||
def __str__(self):
|
||
return self.name
|
||
|
||
@staticmethod
|
||
def get_files_from_rf(register_form_id):
|
||
"""
|
||
Récupère tous les fichiers liés à un dossier d’inscription donné.
|
||
"""
|
||
registration_files = RegistrationTemplate.objects.filter(registration_form=register_form_id)
|
||
filenames = []
|
||
for reg_file in registration_files:
|
||
filenames.append(reg_file.file.path)
|
||
return filenames |