feat: Gestion des pièces à fournir par les parents (configuration école)

This commit is contained in:
N3WT DE COMPET
2025-04-15 18:00:58 +02:00
parent 4c2e2f8756
commit a65bd47905
20 changed files with 956 additions and 569 deletions

View File

@ -163,6 +163,9 @@ class RegistrationFileGroup(models.Model):
def __str__(self):
return self.name
def __str__(self):
return f'{self.group.name} - {self.id}'
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}'
@ -211,7 +214,7 @@ class RegistrationForm(models.Model):
# Many-to-Many Relationship
discounts = models.ManyToManyField(Discount, blank=True, related_name='register_forms')
fileGroup = models.ForeignKey(RegistrationFileGroup,
on_delete=models.CASCADE,
on_delete=models.SET_NULL,
related_name='register_forms',
null=True,
blank=True)
@ -223,6 +226,20 @@ class RegistrationForm(models.Model):
def __str__(self):
return "RF_" + self.student.last_name + "_" + self.student.first_name
def save(self, *args, **kwargs):
# Vérifier si un fichier existant doit être remplacé
if self.pk: # Si l'objet existe déjà dans la base de données
try:
old_instance = RegistrationForm.objects.get(pk=self.pk)
if old_instance.sepa_file and old_instance.sepa_file != self.sepa_file:
# Supprimer l'ancien fichier
old_instance.sepa_file.delete(save=False)
except RegistrationForm.DoesNotExist:
pass # L'objet n'existe pas encore, rien à supprimer
# Appeler la méthode save originale
super().save(*args, **kwargs)
def registration_file_upload_to(instance, filename):
return f"registration_files/dossier_rf_{instance.registration_form.pk}/{filename}"
@ -246,4 +263,10 @@ class RegistrationTemplate(models.Model):
filenames = []
for reg_file in registration_files:
filenames.append(reg_file.file.path)
return filenames
return filenames
class RegistrationParentFile(models.Model):
groups = models.ManyToManyField(RegistrationFileGroup, related_name='parent_files', blank=True)
name = models.CharField(max_length=255, default="")
description = models.CharField(blank=True, null=True)
file = models.FileField(null=True,blank=True, upload_to=registration_file_upload_to)

View File

@ -1,5 +1,5 @@
from rest_framework import serializers
from .models import RegistrationFileGroup, RegistrationForm, Student, Guardian, Sibling, Language, RegistrationTemplateMaster, RegistrationTemplate
from .models import RegistrationFileGroup, RegistrationForm, Student, Guardian, Sibling, Language, RegistrationTemplateMaster, RegistrationTemplate, RegistrationParentFile
from School.models import SchoolClass, Fee, Discount, FeeType
from School.serializers import FeeSerializer, DiscountSerializer
from Auth.models import ProfileRole, Profile
@ -24,6 +24,12 @@ class RegistrationTemplateSerializer(serializers.ModelSerializer):
model = RegistrationTemplate
fields = '__all__'
class RegistrationParentFileSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(required=False)
class Meta:
model = RegistrationParentFile
fields = '__all__'
class GuardianSimpleSerializer(serializers.ModelSerializer):
associated_profile_email = serializers.SerializerMethodField()
@ -280,7 +286,7 @@ class RegistrationFormByParentSerializer(serializers.ModelSerializer):
class Meta:
model = RegistrationForm
fields = ['student', 'status']
fields = ['student', 'status', 'sepa_file']
def __init__(self, *args, **kwargs):
super(RegistrationFormByParentSerializer, self).__init__(*args, **kwargs)

View File

@ -7,7 +7,7 @@ from .views import RegisterFormView, RegisterFormWithIdView, send, resend, archi
# SubClasses
from .views import StudentView, GuardianView, ChildrenListView, StudentListView, DissociateGuardianView
# Files
from .views import RegistrationTemplateMasterView, RegistrationTemplateMasterSimpleView, RegistrationTemplateView, RegistrationTemplateSimpleView
from .views import RegistrationTemplateMasterView, RegistrationTemplateMasterSimpleView, RegistrationTemplateView, RegistrationTemplateSimpleView, RegistrationParentFileSimpleView, RegistrationParentFileView
from .views import RegistrationFileGroupView, RegistrationFileGroupSimpleView, get_registration_files_by_group
from .views import registration_file_views, get_templates_by_rf
@ -39,6 +39,9 @@ urlpatterns = [
re_path(r'^registrationTemplates/(?P<id>[0-9]+)$', RegistrationTemplateSimpleView.as_view(), name='registrationTemplates'),
re_path(r'^registrationTemplates$', RegistrationTemplateView.as_view(), name="registrationTemplates"),
re_path(r'^registrationParentFiles/(?P<id>[0-9]+)$', RegistrationParentFileSimpleView.as_view(), name='registrationParentFiles'),
re_path(r'^registrationParentFiles$', RegistrationParentFileView.as_view(), name="registrationParentFiles"),
re_path(r'^students/(?P<student_id>[0-9]+)/guardians/(?P<guardian_id>[0-9]+)/dissociate', DissociateGuardianView.as_view(), name='dissociate-guardian'),
]

View File

@ -1,5 +1,5 @@
from .register_form_views import RegisterFormView, RegisterFormWithIdView, send, resend, archive, get_templates_by_rf
from .registration_file_views import RegistrationTemplateMasterView, RegistrationTemplateMasterSimpleView, RegistrationTemplateView, RegistrationTemplateSimpleView
from .registration_file_views import RegistrationTemplateMasterView, RegistrationTemplateMasterSimpleView, RegistrationTemplateView, RegistrationTemplateSimpleView, RegistrationParentFileView, RegistrationParentFileSimpleView
from .registration_file_group_views import RegistrationFileGroupView, RegistrationFileGroupSimpleView, get_registration_files_by_group
from .student_views import StudentView, StudentListView, ChildrenListView
from .guardian_views import GuardianView, DissociateGuardianView
@ -12,6 +12,8 @@ __all__ = [
'archive',
'RegistrationTemplateView',
'RegistrationTemplateSimpleView',
'RegistrationParentFileSimpleView',
'RegistrationParentFileView',
'RegistrationTemplateMasterView',
'RegistrationTemplateMasterSimpleView',
'RegistrationFileGroupView',

View File

@ -0,0 +1,159 @@
from django.http.response import JsonResponse
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi
from rest_framework.parsers import MultiPartParser, FormParser
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import status
from Subscriptions.serializers import RegistrationTemplateMasterSerializer, RegistrationTemplateSerializer
from Subscriptions.models import RegistrationTemplateMaster, RegistrationTemplate
from N3wtSchool import bdd
class RegistrationTemplateMasterView(APIView):
@swagger_auto_schema(
operation_description="Récupère tous les masters de templates d'inscription",
responses={200: RegistrationTemplateMasterSerializer(many=True)}
)
def get(self, request):
masters = RegistrationTemplateMaster.objects.all()
serializer = RegistrationTemplateMasterSerializer(masters, many=True)
return Response(serializer.data)
@swagger_auto_schema(
operation_description="Crée un nouveau master de template d'inscription",
request_body=RegistrationTemplateMasterSerializer,
responses={
201: RegistrationTemplateMasterSerializer,
400: "Données invalides"
}
)
def post(self, request):
serializer = RegistrationTemplateMasterSerializer(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)
class RegistrationTemplateMasterSimpleView(APIView):
@swagger_auto_schema(
operation_description="Récupère un master de template d'inscription spécifique",
responses={
200: RegistrationTemplateMasterSerializer,
404: "Master non trouvé"
}
)
def get(self, request, id):
master = bdd.getObject(_objectName=RegistrationTemplateMaster, _columnName='id', _value=id)
if master is None:
return JsonResponse({"errorMessage":'Le master de template n\'a pas été trouvé'}, safe=False, status=status.HTTP_404_NOT_FOUND)
serializer = RegistrationTemplateMasterSerializer(master)
return JsonResponse(serializer.data, safe=False)
@swagger_auto_schema(
operation_description="Met à jour un master de template d'inscription existant",
request_body=RegistrationTemplateMasterSerializer,
responses={
200: RegistrationTemplateMasterSerializer,
400: "Données invalides",
404: "Master non trouvé"
}
)
def put(self, request, id):
master = bdd.getObject(_objectName=RegistrationTemplateMaster, _columnName='id', _value=id)
if master is None:
return JsonResponse({'erreur': 'Le master de template n\'a pas été trouvé'}, safe=False, status=status.HTTP_404_NOT_FOUND)
serializer = RegistrationTemplateMasterSerializer(master, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@swagger_auto_schema(
operation_description="Supprime un master de template d'inscription",
responses={
204: "Suppression réussie",
404: "Master non trouvé"
}
)
def delete(self, request, id):
master = bdd.getObject(_objectName=RegistrationTemplateMaster, _columnName='id', _value=id)
if master is not None:
master.delete()
return JsonResponse({'message': 'La suppression du master de template a été effectuée avec succès'}, safe=False, status=status.HTTP_204_NO_CONTENT)
else:
return JsonResponse({'erreur': 'Le master de template n\'a pas été trouvé'}, safe=False, status=status.HTTP_404_NOT_FOUND)
class RegistrationTemplateView(APIView):
@swagger_auto_schema(
operation_description="Récupère tous les templates d'inscription",
responses={200: RegistrationTemplateSerializer(many=True)}
)
def get(self, request):
templates = RegistrationTemplate.objects.all()
serializer = RegistrationTemplateSerializer(templates, many=True)
return Response(serializer.data)
@swagger_auto_schema(
operation_description="Crée un nouveau template d'inscription",
request_body=RegistrationTemplateSerializer,
responses={
201: RegistrationTemplateSerializer,
400: "Données invalides"
}
)
def post(self, request):
serializer = RegistrationTemplateSerializer(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)
class RegistrationTemplateSimpleView(APIView):
@swagger_auto_schema(
operation_description="Récupère un template d'inscription spécifique",
responses={
200: RegistrationTemplateSerializer,
404: "Template non trouvé"
}
)
def get(self, request, id):
template = bdd.getObject(_objectName=RegistrationTemplate, _columnName='id', _value=id)
if template is None:
return JsonResponse({"errorMessage":'Le template d\'inscription n\'a pas été trouvé'}, safe=False, status=status.HTTP_404_NOT_FOUND)
serializer = RegistrationTemplateSerializer(template)
return JsonResponse(serializer.data, safe=False)
@swagger_auto_schema(
operation_description="Met à jour un template d'inscription existant",
request_body=RegistrationTemplateSerializer,
responses={
200: RegistrationTemplateSerializer,
400: "Données invalides",
404: "Template non trouvé"
}
)
def put(self, request, id):
template = bdd.getObject(_objectName=RegistrationTemplate, _columnName='id', _value=id)
if template is None:
return JsonResponse({'erreur': 'Le template d\'inscription n\'a pas été trouvé'}, safe=False, status=status.HTTP_404_NOT_FOUND)
serializer = RegistrationTemplateSerializer(template, data=request.data)
if serializer.is_valid():
serializer.save()
return Response({'message': 'Template mis à jour avec succès', 'data': serializer.data}, status=status.HTTP_200_OK)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@swagger_auto_schema(
operation_description="Supprime un template d'inscription",
responses={
204: "Suppression réussie",
404: "Template non trouvé"
}
)
def delete(self, request, id):
template = bdd.getObject(_objectName=RegistrationTemplate, _columnName='id', _value=id)
if template is not None:
template.delete()
return JsonResponse({'message': 'La suppression du template a été effectuée avec succès'}, safe=False, status=status.HTTP_204_NO_CONTENT)
else:
return JsonResponse({'erreur': 'Le template n\'a pas été trouvé'}, safe=False, status=status.HTTP_404_NOT_FOUND)

View File

@ -6,8 +6,8 @@ from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import status
from Subscriptions.serializers import RegistrationTemplateMasterSerializer, RegistrationTemplateSerializer
from Subscriptions.models import RegistrationTemplateMaster, RegistrationTemplate
from Subscriptions.serializers import RegistrationTemplateMasterSerializer, RegistrationTemplateSerializer, RegistrationParentFileSerializer
from Subscriptions.models import RegistrationTemplateMaster, RegistrationTemplate, RegistrationParentFile
from N3wtSchool import bdd
class RegistrationTemplateMasterView(APIView):
@ -157,3 +157,78 @@ class RegistrationTemplateSimpleView(APIView):
return JsonResponse({'message': 'La suppression du template a été effectuée avec succès'}, safe=False, status=status.HTTP_204_NO_CONTENT)
else:
return JsonResponse({'erreur': 'Le template n\'a pas été trouvé'}, safe=False, status=status.HTTP_404_NOT_FOUND)
class RegistrationParentFileView(APIView):
@swagger_auto_schema(
operation_description="Récupère tous les fichiers parents",
responses={200: RegistrationParentFileSerializer(many=True)}
)
def get(self, request):
templates = RegistrationParentFile.objects.all()
serializer = RegistrationParentFileSerializer(templates, many=True)
return Response(serializer.data)
@swagger_auto_schema(
operation_description="Crée un nouveau fichier parent",
request_body=RegistrationParentFileSerializer,
responses={
201: RegistrationParentFileSerializer,
400: "Données invalides"
}
)
def post(self, request):
serializer = RegistrationParentFileSerializer(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)
class RegistrationParentFileSimpleView(APIView):
@swagger_auto_schema(
operation_description="Récupère un fichier parent spécifique",
responses={
200: RegistrationParentFileSerializer,
404: "Fichier parent non trouvé"
}
)
def get(self, request, id):
template = bdd.getObject(_objectName=RegistrationParentFile, _columnName='id', _value=id)
if template is None:
return JsonResponse({"errorMessage":'Le fichier parent n\'a pas été trouvé'}, safe=False, status=status.HTTP_404_NOT_FOUND)
serializer = RegistrationParentFileSerializer(template)
return JsonResponse(serializer.data, safe=False)
@swagger_auto_schema(
operation_description="Met à jour un fichier parent existant",
request_body=RegistrationParentFileSerializer,
responses={
200: RegistrationParentFileSerializer,
400: "Données invalides",
404: "Fichier parent non trouvé"
}
)
def put(self, request, id):
template = bdd.getObject(_objectName=RegistrationParentFile, _columnName='id', _value=id)
if template is None:
return JsonResponse({'erreur': 'Le fichier parent n\'a pas été trouvé'}, safe=False, status=status.HTTP_404_NOT_FOUND)
serializer = RegistrationParentFileSerializer(template, data=request.data)
if serializer.is_valid():
serializer.save()
return Response({'message': 'Fichier parent mis à jour avec succès', 'data': serializer.data}, status=status.HTTP_200_OK)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@swagger_auto_schema(
operation_description="Supprime un fichier parent",
responses={
204: "Suppression réussie",
404: "Fichier parent non trouvé"
}
)
def delete(self, request, id):
template = bdd.getObject(_objectName=RegistrationParentFile, _columnName='id', _value=id)
if template is not None:
template.delete()
return JsonResponse({'message': 'La suppression du fichier parent a été effectuée avec succès'}, safe=False, status=status.HTTP_204_NO_CONTENT)
else:
return JsonResponse({'erreur': 'Le fichier parent n\'a pas été trouvé'}, safe=False, status=status.HTTP_404_NOT_FOUND)