feat: Ajout de la configuration des tarifs de l'école [#18]

This commit is contained in:
N3WT DE COMPET
2025-01-19 21:00:58 +01:00
committed by Luc SORIGNET
parent 147a70135d
commit 5a0e65bb75
45 changed files with 2089 additions and 376 deletions

View File

@ -9,6 +9,9 @@ from School.models import SchoolClass
from datetime import datetime
class RegistrationFee(models.Model):
"""
Représente un tarif ou frais dinscription avec différentes options de paiement.
"""
class PaymentOptions(models.IntegerChoices):
SINGLE_PAYMENT = 0, _('Paiement en une seule fois')
MONTHLY_PAYMENT = 1, _('Paiement mensuel')
@ -27,6 +30,9 @@ class RegistrationFee(models.Model):
return self.name
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="")
@ -34,6 +40,9 @@ class Language(models.Model):
return "LANGUAGE"
class Guardian(models.Model):
"""
Représente un responsable légal (parent/tuteur) dun é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)
@ -47,6 +56,9 @@ class Guardian(models.Model):
return self.last_name + "_" + self.first_name
class Sibling(models.Model):
"""
Représente un frère ou une sœur dun élève.
"""
id = models.AutoField(primary_key=True)
last_name = models.CharField(max_length=200, default="")
first_name = models.CharField(max_length=200, default="")
@ -56,7 +68,9 @@ class Sibling(models.Model):
return "SIBLING"
class Student(models.Model):
"""
Représente lélève inscrit ou en cours dinscription.
"""
class StudentGender(models.IntegerChoices):
NONE = 0, _('Sélection du genre')
MALE = 1, _('Garçon')
@ -95,6 +109,9 @@ class Student(models.Model):
# Many-to-Many Relationship
siblings = models.ManyToManyField(Sibling, blank=True)
# Many-to-Many Relationship
registration_files = models.ManyToManyField('RegistrationFile', blank=True, related_name='students')
# Many-to-Many Relationship
spoken_languages = models.ManyToManyField(Language, blank=True)
@ -105,21 +122,39 @@ class Student(models.Model):
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
@ -148,7 +183,9 @@ class Student(models.Model):
return None
class RegistrationForm(models.Model):
"""
Gère le dossier dinscription lié à un élève donné.
"""
class RegistrationFormStatus(models.IntegerChoices):
RF_ABSENT = 0, _('Pas de dossier d\'inscription')
RF_CREATED = 1, _('Dossier d\'inscription créé')
@ -171,9 +208,53 @@ class RegistrationForm(models.Model):
return "RF_" + self.student.last_name + "_" + self.student.first_name
class RegistrationFileTemplate(models.Model):
"""
Modèle pour stocker les fichiers "templates" dinscription.
"""
name = models.CharField(max_length=255)
file = models.FileField(upload_to='registration_files/')
file = models.FileField(upload_to='templates_files/', blank=True, null=True)
order = models.PositiveIntegerField(default=0) # Ajout du champ order
date_added = models.DateTimeField(auto_now_add=True)
is_required = models.BooleanField(default=False)
@property
def formatted_date_added(self):
if self.date_added:
return self.date_added.strftime('%d-%m-%Y')
return None
def __str__(self):
return self.name
def registration_file_upload_to(instance, filename):
return f"registration_files/dossier_rf_{instance.register_form.pk}/{filename}"
class RegistrationFile(models.Model):
"""
Fichier lié à un dossier dinscription particulier.
"""
name = models.CharField(max_length=255)
file = models.FileField(upload_to=registration_file_upload_to)
date_added = models.DateTimeField(auto_now_add=True)
template = models.OneToOneField(RegistrationFileTemplate, on_delete=models.CASCADE)
register_form = models.ForeignKey('RegistrationForm', on_delete=models.CASCADE, related_name='registration_files')
@property
def formatted_date_added(self):
if self.date_added:
return self.date_added.strftime('%d-%m-%Y')
return None
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 dinscription donné.
"""
registration_files = RegistrationFile.objects.filter(register_form_id=register_form_id).order_by('template__order')
filenames = []
for reg_file in registration_files:
filenames.append(reg_file.file.path)
return filenames

View File

@ -1,5 +1,5 @@
from rest_framework import serializers
from .models import RegistrationFileTemplate, RegistrationForm, Student, Guardian, Sibling, Language, RegistrationFee
from .models import RegistrationFileTemplate, RegistrationFile, RegistrationForm, Student, Guardian, Sibling, Language, RegistrationFee
from School.models import SchoolClass
from Auth.models import Profile
from Auth.serializers import ProfileSerializer
@ -10,17 +10,22 @@ from django.utils import timezone
import pytz
from datetime import datetime
class RegistrationFileTemplateSerializer(serializers.ModelSerializer):
class Meta:
model = RegistrationFileTemplate
fields = '__all__'
class RegistrationFeeSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(required=False)
class Meta:
model = RegistrationFee
fields = '__all__'
class RegistrationFileSerializer(serializers.ModelSerializer):
class Meta:
model = RegistrationFile
fields = '__all__'
class RegistrationFileTemplateSerializer(serializers.ModelSerializer):
class Meta:
model = RegistrationFileTemplate
fields = '__all__'
class LanguageSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(required=False)
class Meta:
@ -47,6 +52,7 @@ class GuardianSerializer(serializers.ModelSerializer):
class StudentSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(required=False)
guardians = GuardianSerializer(many=True, required=False)
siblings = SiblingSerializer(many=True, required=False)
@ -126,7 +132,7 @@ class RegistrationFormSerializer(serializers.ModelSerializer):
registration_file = serializers.FileField(required=False)
status_label = serializers.SerializerMethodField()
formatted_last_update = serializers.SerializerMethodField()
registration_files = RegistrationFileSerializer(many=True, required=False)
class Meta:
model = RegistrationForm
fields = '__all__'

View File

@ -1,36 +1,44 @@
from django.urls import path, re_path
from . import views
from Subscriptions.views import RegistrationFileTemplateView, RegisterFormListView, RegisterFormView, StudentView, GuardianView, ChildrenListView, StudentListView, RegistrationFeeView
from .views import RegistrationFileTemplateView, RegisterFormListView, RegisterFormView, StudentView, GuardianView, ChildrenListView, StudentListView, RegistrationFeeView, RegistrationFileView
urlpatterns = [
re_path(r'^registerForms/([a-zA-z]+)$', RegisterFormListView.as_view(), name="registerForms"),
re_path(r'^registerForms/(?P<_filter>[a-zA-z]+)$', RegisterFormListView.as_view(), name="registerForms"),
re_path(r'^registerForm$', RegisterFormView.as_view(), name="registerForm"),
re_path(r'^registerForm/([0-9]+)$', RegisterFormView.as_view(), name="registerForm"),
re_path(r'^registerForm/(?P<_id>[0-9]+)$', RegisterFormView.as_view(), name="registerForm"),
# Page de formulaire d'inscription - ELEVE
re_path(r'^student/([0-9]+)$', StudentView.as_view(), name="students"),
re_path(r'^student/(?P<_id>[0-9]+)$', StudentView.as_view(), name="students"),
# Page de formulaire d'inscription - RESPONSABLE
re_path(r'^lastGuardian$', GuardianView.as_view(), name="lastGuardian"),
# Envoi d'un dossier d'inscription
re_path(r'^send/([0-9]+)$', views.send, name="send"),
re_path(r'^send/(?P<_id>[0-9]+)$', views.send, name="send"),
# Archivage d'un dossier d'inscription
re_path(r'^archive/([0-9]+)$', views.archive, name="archive"),
re_path(r'^archive/(?P<_id>[0-9]+)$', views.archive, name="archive"),
# Envoi d'une relance de dossier d'inscription
re_path(r'^sendRelance/([0-9]+)$', views.relance, name="sendRelance"),
re_path(r'^sendRelance/(?P<_id>[0-9]+)$', views.relance, name="sendRelance"),
# Page PARENT - Liste des children
re_path(r'^children/([0-9]+)$', ChildrenListView.as_view(), name="children"),
re_path(r'^children/(?P<_id>[0-9]+)$', ChildrenListView.as_view(), name="children"),
# Page INSCRIPTION - Liste des élèves
re_path(r'^students$', StudentListView.as_view(), name="students"),
# Frais d'inscription
re_path(r'^registrationFees$', RegistrationFeeView.as_view(), name="registrationFees"),
# modèles de fichiers d'inscription
re_path(r'^registrationFileTemplates$', RegistrationFileTemplateView.as_view(), name='registrationFileTemplates'),
re_path(r'^registrationFileTemplates/([0-9]+)$', RegistrationFileTemplateView.as_view(), name="registrationFileTemplate"),
re_path(r'^registrationFileTemplates/(?P<_id>[0-9]+)$', RegistrationFileTemplateView.as_view(), name="registrationFileTemplate"),
# fichiers d'inscription
re_path(r'^registrationFiles/(?P<_id>[0-9]+)$', RegistrationFileView.as_view(), name='registrationFiles'),
re_path(r'^registrationFiles', RegistrationFileView.as_view(), name="registrationFiles"),
]

View File

@ -16,52 +16,95 @@ from enum import Enum
import random
import string
from rest_framework.parsers import JSONParser
import pymupdf
def recupereListeFichesInscription():
"""
Retourne la liste complète des fiches dinscription.
"""
context = {
"ficheInscriptions_list": bdd.getAllObjects(RegistrationForm),
}
return context
def recupereListeFichesInscriptionEnAttenteSEPA():
"""
Retourne les fiches dinscription avec paiement SEPA en attente.
"""
ficheInscriptionsSEPA_list = RegistrationForm.objects.filter(modePaiement="Prélèvement SEPA").filter(etat=RegistrationForm.RegistrationFormStatus['SEPA_ENVOYE'])
return ficheInscriptionsSEPA_list
def _now():
"""
Retourne la date et lheure en cours, avec fuseau.
"""
return datetime.now(ZoneInfo(settings.TZ_APPLI))
def convertToStr(dateValue, dateFormat):
"""
Convertit un objet datetime en chaîne selon un format donné.
"""
return dateValue.strftime(dateFormat)
def convertToDate(date_time):
"""
Convertit une chaîne en objet datetime selon le format '%d-%m-%Y %H:%M'.
"""
format = '%d-%m-%Y %H:%M'
datetime_str = datetime.strptime(date_time, format)
return datetime_str
def convertTelephone(telephoneValue, separator='-'):
"""
Reformate un numéro de téléphone en y insérant un séparateur donné.
"""
return f"{telephoneValue[:2]}{separator}{telephoneValue[2:4]}{separator}{telephoneValue[4:6]}{separator}{telephoneValue[6:8]}{separator}{telephoneValue[8:10]}"
def genereRandomCode(length):
"""
Génère un code aléatoire de longueur spécifiée.
"""
return ''.join(random.choice(string.ascii_letters) for i in range(length))
def calculeDatePeremption(_start, nbDays):
"""
Calcule la date de fin à partir dun point de départ et dun nombre de jours.
"""
return convertToStr(_start + timedelta(days=nbDays), settings.DATE_FORMAT)
# Fonction permettant de retourner la valeur du QueryDict
# QueryDict [ index ] -> Dernière valeur d'une liste
# dict (QueryDict [ index ]) -> Toutes les valeurs de la liste
def _(liste):
"""
Retourne la première valeur dune liste extraite dun QueryDict.
"""
return liste[0]
def getArgFromRequest(_argument, _request):
"""
Extrait la valeur dun argument depuis la requête (JSON).
"""
resultat = None
data=JSONParser().parse(_request)
resultat = data[_argument]
return resultat
def rfToPDF(registerForm):
def merge_files_pdf(filenames, output_filename):
"""
Insère plusieurs fichiers PDF dans un seul document de sortie.
"""
merger = pymupdf.open()
for filename in filenames:
merger.insert_file(filename)
merger.save(output_filename)
merger.close()
def rfToPDF(registerForm,filename):
"""
Génère le PDF dun dossier dinscription et lassocie au RegistrationForm.
"""
# Ajout du fichier d'inscriptions
data = {
'pdf_title': "Dossier d'inscription de %s"%registerForm.student.first_name,
@ -69,14 +112,12 @@ def rfToPDF(registerForm):
'signatureTime': convertToStr(_now(), '%H:%M'),
'student':registerForm.student,
}
PDFFileName = filename
pdf = renderers.render_to_pdf('pdfs/dossier_inscription.html', data)
PDFFileName = "Dossier_Inscription_%s_%s.pdf"%(registerForm.student.last_name, registerForm.student.first_name)
pathFichier = Path(settings.DOCUMENT_DIR + "/" + PDFFileName)
pathFichier = Path(filename)
if os.path.exists(str(pathFichier)):
print(f'File exists : {str(pathFichier)}')
os.remove(str(pathFichier))
receipt_file = BytesIO(pdf.content)
registerForm.fichierInscription = File(receipt_file, PDFFileName)
registerForm.fichierInscription = File(receipt_file, PDFFileName)
registerForm.fichierInscription.save()

View File

@ -10,6 +10,8 @@ from rest_framework.parsers import JSONParser,MultiPartParser, FormParser
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import status
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi
import json
from pathlib import Path
@ -18,18 +20,22 @@ from io import BytesIO
import Subscriptions.mailManager as mailer
import Subscriptions.util as util
from Subscriptions.serializers import RegistrationFormSerializer, RegistrationFileTemplateSerializer, StudentSerializer, RegistrationFormByParentSerializer, StudentByRFCreationSerializer, RegistrationFeeSerializer
from Subscriptions.pagination import CustomPagination
from Subscriptions.signals import clear_cache
from .models import Student, Guardian, RegistrationForm, RegistrationFee, RegistrationFileTemplate
from Subscriptions.automate import Automate_RF_Register, load_config, getStateMachineObjectState, updateStateMachine
from .serializers import RegistrationFormSerializer, StudentSerializer, RegistrationFormByParentSerializer, StudentByRFCreationSerializer, RegistrationFileSerializer, RegistrationFileTemplateSerializer, RegistrationFormByParentSerializer, StudentByRFCreationSerializer, RegistrationFeeSerializer
from .pagination import CustomPagination
from .signals import clear_cache
from .models import Student, Guardian, RegistrationForm, RegistrationFee, RegistrationFileTemplate, RegistrationFile
from .automate import Automate_RF_Register, load_config, getStateMachineObjectState, updateStateMachine
from Auth.models import Profile
from N3wtSchool import settings, renderers, bdd
class RegisterFormListView(APIView):
"""
Gère la liste des dossiers dinscription, lecture et création.
"""
pagination_class = CustomPagination
def get_register_form(self, _filter, search=None):
@ -47,8 +53,18 @@ class RegisterFormListView(APIView):
return bdd.getObjects(RegistrationForm, 'status', RegistrationForm.RegistrationFormStatus.RF_VALIDATED)
return None
@swagger_auto_schema(
manual_parameters=[
openapi.Parameter('_filter', openapi.IN_PATH, description="filtre", type=openapi.TYPE_STRING, enum=['pending', 'archived', 'subscribed'], required=True),
openapi.Parameter('search', openapi.IN_QUERY, description="search", type=openapi.TYPE_STRING, required=False),
openapi.Parameter('page_size', openapi.IN_QUERY, description="limite de page lors de la pagination", type=openapi.TYPE_INTEGER, required=False),
],
responses={200: RegistrationFormSerializer(many=True)}
)
def get(self, request, _filter):
"""
Récupère les fiches d'inscriptions en fonction du filtre passé.
"""
# Récupération des paramètres
search = request.GET.get('search', '').strip()
page_size = request.GET.get('page_size', None)
@ -84,6 +100,11 @@ class RegisterFormListView(APIView):
return JsonResponse({'error' : 'aucune donnée trouvée', 'count' :0}, safe=False)
@swagger_auto_schema(
manual_parameters=[
],
responses={200: RegistrationFormSerializer(many=True)}
)
def post(self, request):
studentFormList_serializer=JSONParser().parse(request)
for studentForm_data in studentFormList_serializer:
@ -104,14 +125,23 @@ class RegisterFormListView(APIView):
@method_decorator(csrf_protect, name='dispatch')
@method_decorator(ensure_csrf_cookie, name='dispatch')
class RegisterFormView(APIView):
"""
Gère la lecture, création, modification et suppression dun dossier dinscription.
"""
pagination_class = CustomPagination
def get(self, request, _id):
"""
Récupère un dossier d'inscription donné.
"""
registerForm=bdd.getObject(RegistrationForm, "student__id", _id)
registerForm_serializer=RegistrationFormSerializer(registerForm)
return JsonResponse(registerForm_serializer.data, safe=False)
def post(self, request):
"""
Crée un dossier d'inscription.
"""
studentForm_data=JSONParser().parse(request)
# Ajout de la date de mise à jour
studentForm_data["last_update"] = util.convertToStr(util._now(), '%d-%m-%Y %H:%M')
@ -137,21 +167,33 @@ class RegisterFormView(APIView):
return JsonResponse(studentForm_serializer.data, safe=False)
return JsonResponse(studentForm_serializer.errors, safe=False, status=400)
return JsonResponse(studentForm_serializer.errors, safe=False, status=status.HTTP_400_BAD_REQUEST)
def put(self, request, id):
def put(self, request, _id):
"""
Modifie un dossier d'inscription donné.
"""
studentForm_data=JSONParser().parse(request)
status = studentForm_data.pop('status', 0)
_status = studentForm_data.pop('status', 0)
studentForm_data["last_update"] = str(util.convertToStr(util._now(), '%d-%m-%Y %H:%M'))
registerForm = bdd.getObject(_objectName=RegistrationForm, _columnName='student__id', _value=id)
registerForm = bdd.getObject(_objectName=RegistrationForm, _columnName='student__id', _value=_id)
if status == RegistrationForm.RegistrationFormStatus.RF_UNDER_REVIEW:
if _status == RegistrationForm.RegistrationFormStatus.RF_UNDER_REVIEW:
# Le parent a complété le dossier d'inscription, il est soumis à validation par l'école
json.dumps(studentForm_data)
util.rfToPDF(registerForm)
#Génération de la fiche d'inscription au format PDF
PDFFileName = "rf_%s_%s.pdf"%(registerForm.student.last_name, registerForm.student.first_name)
path = Path(f"registration_files/dossier_rf_{registerForm.pk}/{PDFFileName}")
registerForm.fichierInscription = util.rfToPDF(registerForm, path)
# Récupération des fichiers d'inscription
fileNames = RegistrationFile.get_files_from_rf(registerForm.pk)
fileNames.insert(0,path)
# Création du fichier PDF Fusionné avec le dossier complet
output_path = f"registration_files/dossier_rf_{registerForm.pk}/dossier_{registerForm.pk}.pdf"
util.merge_files_pdf(fileNames, output_path)
# Mise à jour de l'automate
updateStateMachine(registerForm, 'saisiDI')
elif status == RegistrationForm.RegistrationFormStatus.RF_VALIDATED:
elif _status == RegistrationForm.RegistrationFormStatus.RF_VALIDATED:
# L'école a validé le dossier d'inscription
# Mise à jour de l'automate
updateStateMachine(registerForm, 'valideDI')
@ -162,34 +204,49 @@ class RegisterFormView(APIView):
studentForm_serializer.save()
return JsonResponse(studentForm_serializer.data, safe=False)
return JsonResponse(studentForm_serializer.errors, safe=False, status=400)
return JsonResponse(studentForm_serializer.errors, safe=False, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, id):
"""
Supprime un dossier d'inscription donné.
"""
register_form = bdd.getObject(_objectName=RegistrationForm, _columnName='student__id', _value=id)
if register_form != None:
student = register_form.student
student.guardians.clear()
student.profiles.clear()
student.registration_files.clear()
student.delete()
clear_cache()
return JsonResponse("La suppression du dossier a été effectuée avec succès", safe=False)
return JsonResponse({"errorMessage":'Aucun dossier d\'inscription rattaché à l\'élève'}, safe=False, status=400)
return JsonResponse({"errorMessage":'Aucun dossier d\'inscription rattaché à l\'élève'}, safe=False, status=status.HTTP_404_NOT_FOUND)
class StudentView(APIView):
"""
Gère la lecture dun élève donné.
"""
def get(self, request, _id):
student = bdd.getObject(_objectName=Student, _columnName='id', _value=_id)
if student is None:
return JsonResponse({"errorMessage":'Aucun élève trouvé'}, safe=False, status=status.HTTP_404_NOT_FOUND)
student_serializer = StudentSerializer(student)
return JsonResponse(student_serializer.data, safe=False)
class GuardianView(APIView):
"""
Récupère le dernier ID de responsable légal créé.
"""
def get(self, request):
lastGuardian = bdd.getLastId(Guardian)
return JsonResponse({"lastid":lastGuardian}, safe=False)
def send(request, id):
register_form = bdd.getObject(_objectName=RegistrationForm, _columnName='student__id', _value=id)
def send(request, _id):
"""
Envoie le dossier dinscription par e-mail.
"""
register_form = bdd.getObject(_objectName=RegistrationForm, _columnName='student__id', _value=_id)
if register_form != None:
student = register_form.student
guardian = student.getMainGuardian()
@ -199,24 +256,31 @@ def send(request, id):
register_form.last_update=util.convertToStr(util._now(), '%d-%m-%Y %H:%M')
# Mise à jour de l'automate
updateStateMachine(register_form, 'envoiDI')
return JsonResponse({"message": f"Le dossier d'inscription a bien été envoyé à l'addresse {email}"}, safe=False)
return JsonResponse({"errorMessage":errorMessage}, safe=False, status=400)
return JsonResponse({"errorMessage":errorMessage}, safe=False, status=status.HTTP_400_BAD_REQUEST)
return JsonResponse({"errorMessage":'Aucun dossier d\'inscription rattaché à l\'élève'}, safe=False, status=400)
return JsonResponse({"errorMessage":'Aucun dossier d\'inscription rattaché à l\'élève'}, safe=False, status=status.HTTP_404_NOT_FOUND)
def archive(request, id):
register_form = bdd.getObject(_objectName=RegistrationForm, _columnName='student__id', _value=id)
def archive(request, _id):
"""
Archive le dossier dinscription visé.
"""
register_form = bdd.getObject(_objectName=RegistrationForm, _columnName='student__id', _value=_id)
if register_form != None:
register_form.last_update=util.convertToStr(util._now(), '%d-%m-%Y %H:%M')
# Mise à jour de l'automate
updateStateMachine(register_form, 'archiveDI')
return JsonResponse({"errorMessage":''}, safe=False, status=400)
return JsonResponse({"errorMessage":''}, safe=False, status=status.HTTP_400_BAD_REQUEST)
return JsonResponse({"errorMessage":'Aucun dossier d\'inscription rattaché à l\'élève'}, safe=False, status=400)
return JsonResponse({"errorMessage":'Aucun dossier d\'inscription rattaché à l\'élève'}, safe=False, status=status.HTTP_404_NOT_FOUND)
def relance(request, id):
register_form = bdd.getObject(_objectName=RegistrationForm, _columnName='student__id', _value=id)
def relance(request, _id):
"""
Relance un dossier dinscription par e-mail.
"""
register_form = bdd.getObject(_objectName=RegistrationForm, _columnName='student__id', _value=_id)
if register_form != None:
student = register_form.student
guardian = student.getMainGuardian()
@ -227,12 +291,15 @@ def relance(request, id):
register_form.last_update=util.convertToStr(util._now(), '%d-%m-%Y %H:%M')
register_form.save()
return JsonResponse({"errorMessage":errorMessage}, safe=False, status=400)
return JsonResponse({"errorMessage":errorMessage}, safe=False, status=status.HTTP_400_BAD_REQUEST)
return JsonResponse({"errorMessage":'Aucun dossier d\'inscription rattaché à l\'élève'}, safe=False, status=400)
return JsonResponse({"errorMessage":'Aucun dossier d\'inscription rattaché à l\'élève'}, safe=False, status=status.HTTP_404_NOT_FOUND)
# API utilisée pour la vue parent
class ChildrenListView(APIView):
"""
Pour la vue parent : liste les élèves rattachés à un profil donné.
"""
# Récupération des élèves d'un parent
# idProfile : identifiant du profil connecté rattaché aux fiches d'élèves
def get(self, request, _idProfile):
@ -242,6 +309,9 @@ class ChildrenListView(APIView):
# API utilisée pour la vue de création d'un DI
class StudentListView(APIView):
"""
Pour la vue de création dun dossier dinscription : liste les élèves disponibles.
"""
# Récupération de la liste des élèves inscrits ou en cours d'inscriptions
def get(self, request):
students = bdd.getAllObjects(_objectName=Student)
@ -250,20 +320,52 @@ class StudentListView(APIView):
# API utilisée pour la vue de personnalisation des frais d'inscription pour la structure
class RegistrationFeeView(APIView):
"""
Liste les frais dinscription.
"""
def get(self, request):
tarifs = bdd.getAllObjects(RegistrationFee)
tarifs_serializer = RegistrationFeeSerializer(tarifs, many=True)
return JsonResponse(tarifs_serializer.data, safe=False)
class RegistrationFileTemplateView(APIView):
"""
Gère les fichiers templates pour les dossiers dinscription.
"""
parser_classes = (MultiPartParser, FormParser)
def get(self, request):
fichiers = RegistrationFileTemplate.objects.all()
serializer = RegistrationFileTemplateSerializer(fichiers, many=True)
return Response(serializer.data)
def get(self, request, _id=None):
"""
Récupère les fichiers templates pour les dossiers dinscription.
"""
if _id is None:
files = RegistrationFileTemplate.objects.all()
serializer = RegistrationFileTemplateSerializer(files, many=True)
return Response(serializer.data)
else :
registationFileTemplate = bdd.getObject(_objectName=RegistrationFileTemplate, _columnName='id', _value=_id)
if registationFileTemplate is None:
return JsonResponse({"errorMessage":'Le fichier d\'inscription n\'a pas été trouvé'}, safe=False, status=status.HTTP_404_NOT_FOUND)
serializer = RegistrationFileTemplateSerializer(registationFileTemplate)
return JsonResponse(serializer.data, safe=False)
def put(self, request, _id):
"""
Met à jour un fichier template existant.
"""
registationFileTemplate = bdd.getObject(_objectName=RegistrationFileTemplate, _columnName='id', _value=_id)
if registationFileTemplate is None:
return JsonResponse({'erreur': 'Le fichier d\'inscription n\'a pas été trouvé'}, safe=False, status=status.HTTP_404_NOT_FOUND)
serializer = RegistrationFileTemplateSerializer(registationFileTemplate,data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def post(self, request):
"""
Crée un fichier template pour les dossiers dinscription.
"""
serializer = RegistrationFileTemplateSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
@ -271,10 +373,71 @@ class RegistrationFileTemplateView(APIView):
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, _id):
"""
Supprime un fichier template existant.
"""
registrationFileTemplate = bdd.getObject(_objectName=RegistrationFileTemplate, _columnName='id', _value=_id)
if registrationFileTemplate is not None:
registrationFileTemplate.file.delete() # Supprimer le fichier uploadé
registrationFileTemplate.delete()
return JsonResponse({'message': 'La suppression du fichier d\'inscription a été effectuée avec succès'}, safe=False)
return JsonResponse({'message': 'La suppression du fichier d\'inscription a été effectuée avec succès'}, safe=False, status=status.HTTP_204_NO_CONTENT)
else:
return JsonResponse({'erreur': 'Le fichier d\'inscription n\'a pas été trouvé'}, safe=False, status=400)
return JsonResponse({'erreur': 'Le fichier d\'inscription n\'a pas été trouvé'}, safe=False, status=status.HTTP_404_NOT_FOUND)
class RegistrationFileView(APIView):
"""
Gère la création, mise à jour et suppression de fichiers liés à un dossier dinscription.
"""
parser_classes = (MultiPartParser, FormParser)
def get(self, request, _id=None):
"""
Récupère les fichiers liés à un dossier dinscription donné.
"""
if (_id is None):
files = RegistrationFile.objects.all()
serializer = RegistrationFileSerializer(files, many=True)
return Response(serializer.data)
else:
registationFile = bdd.getObject(_objectName=RegistrationFile, _columnName='id', _value=_id)
if registationFile is None:
return JsonResponse({"errorMessage":'Le fichier d\'inscription n\'a pas été trouvé'}, safe=False, status=status.HTTP_404_NOT_FOUND)
serializer = RegistrationFileSerializer(registationFile)
return JsonResponse(serializer.data, safe=False)
def post(self, request):
"""
Crée un RegistrationFile pour le RegistrationForm associé.
"""
serializer = RegistrationFileSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def put(self, request, fileId):
"""
Met à jour un RegistrationFile existant.
"""
registrationFile = bdd.getObject(_objectName=RegistrationFile, _columnName='id', _value=fileId)
if registrationFile is None:
return JsonResponse({'erreur': 'Le fichier d\'inscription n\'a pas été trouvé'}, safe=False, status=status.HTTP_404_NOT_FOUND)
serializer = RegistrationFileSerializer(registrationFile, data=request.data)
if serializer.is_valid():
serializer.save()
return Response({'message': 'Fichier mis à jour avec succès', 'data': serializer.data}, status=status.HTTP_200_OK)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, _id):
"""
Supprime un RegistrationFile existant.
"""
registrationFile = bdd.getObject(_objectName=RegistrationFile, _columnName='id', _value=_id)
if registrationFile is not None:
registrationFile.file.delete() # Supprimer le fichier uploadé
registrationFile.delete()
return JsonResponse({'message': 'La suppression du fichier a été effectuée avec succès'}, safe=False)
else:
return JsonResponse({'erreur': 'Le fichier n\'a pas été trouvé'}, safe=False, status=status.HTTP_404_NOT_FOUND)