from django.http.response import JsonResponse from django.contrib.auth import login, authenticate, get_user_model from django.views.decorators.csrf import ensure_csrf_cookie, csrf_protect from django.utils.decorators import method_decorator from django.core.cache import cache from django.core.paginator import Paginator from django.core.files import File from django.db.models import Q # Ajout de cet import 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 import json from pathlib import Path import os 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 Auth.models import Profile from N3wtSchool import settings, renderers, bdd class RegisterFormListView(APIView): pagination_class = CustomPagination def get_register_form(self, _filter, search=None): """ Récupère les fiches d'inscriptions en fonction du filtre passé. _filter: Filtre pour déterminer l'état des fiches ('pending', 'archived', 'subscribed') search: Terme de recherche (optionnel) """ if _filter == 'pending': exclude_states = [RegistrationForm.RegistrationFormStatus.RF_VALIDATED, RegistrationForm.RegistrationFormStatus.RF_ARCHIVED] return bdd.searchObjects(RegistrationForm, search, _excludeStates=exclude_states) elif _filter == 'archived': return bdd.getObjects(RegistrationForm, 'status', RegistrationForm.RegistrationFormStatus.RF_ARCHIVED) elif _filter == 'subscribed': return bdd.getObjects(RegistrationForm, 'status', RegistrationForm.RegistrationFormStatus.RF_VALIDATED) return None def get(self, request, _filter): # Récupération des paramètres search = request.GET.get('search', '').strip() page_size = request.GET.get('page_size', None) # Gestion du page_size if page_size is not None: try: page_size = int(page_size) except ValueError: page_size = settings.NB_RESULT_PER_PAGE # Définir le cache_key en fonction du filtre page_number = request.GET.get('page', 1) cache_key = f'N3WT_ficheInscriptions_{_filter}_page_{page_number}_search_{search if _filter == "pending" else ""}' cached_page = cache.get(cache_key) if cached_page: return JsonResponse(cached_page, safe=False) # Récupérer les fiches d'inscriptions en fonction du filtre registerForms_List = self.get_register_form(_filter, search) if not registerForms_List: return JsonResponse({'error' : 'aucune donnée trouvée', 'count' :0}, safe=False) # Pagination paginator = self.pagination_class() page = paginator.paginate_queryset(registerForms_List, request) if page is not None: registerForms_serializer = RegistrationFormSerializer(page, many=True) response_data = paginator.get_paginated_response(registerForms_serializer.data) cache.set(cache_key, response_data, timeout=60*15) return JsonResponse(response_data, safe=False) return JsonResponse({'error' : 'aucune donnée trouvée', 'count' :0}, safe=False) def post(self, request): studentFormList_serializer=JSONParser().parse(request) for studentForm_data in studentFormList_serializer: # Ajout de la date de mise à jour studentForm_data["last_update"] = util.convertToStr(util._now(), '%d-%m-%Y %H:%M') json.dumps(studentForm_data) # Ajout du code d'inscription code = util.genereRandomCode(12) studentForm_data["codeLienInscription"] = code studentForm_serializer = RegistrationFormSerializer(data=studentForm_data) if studentForm_serializer.is_valid(): studentForm_serializer.save() return JsonResponse(studentForm_serializer.errors, safe=False) @method_decorator(csrf_protect, name='dispatch') @method_decorator(ensure_csrf_cookie, name='dispatch') class RegisterFormView(APIView): pagination_class = CustomPagination def get(self, request, _id): registerForm=bdd.getObject(RegistrationForm, "student__id", _id) registerForm_serializer=RegistrationFormSerializer(registerForm) return JsonResponse(registerForm_serializer.data, safe=False) def post(self, request): 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') json.dumps(studentForm_data) # Ajout du code d'inscription code = util.genereRandomCode(12) studentForm_data["codeLienInscription"] = code guardiansId = studentForm_data.pop('idGuardians', []) studentForm_serializer = RegistrationFormSerializer(data=studentForm_data) if studentForm_serializer.is_valid(): di = studentForm_serializer.save() # Mise à jour de l'automate updateStateMachine(di, 'creationDI') # Récupération du reponsable associé for guardianId in guardiansId: guardian = Guardian.objects.get(id=guardianId) di.student.guardians.add(guardian) di.save() return JsonResponse(studentForm_serializer.data, safe=False) return JsonResponse(studentForm_serializer.errors, safe=False, status=400) def put(self, request, id): studentForm_data=JSONParser().parse(request) 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) 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) # Mise à jour de l'automate updateStateMachine(registerForm, 'saisiDI') elif status == RegistrationForm.RegistrationFormStatus.RF_VALIDATED: # L'école a validé le dossier d'inscription # Mise à jour de l'automate updateStateMachine(registerForm, 'valideDI') studentForm_serializer = RegistrationFormSerializer(registerForm, data=studentForm_data) if studentForm_serializer.is_valid(): studentForm_serializer.save() return JsonResponse(studentForm_serializer.data, safe=False) return JsonResponse(studentForm_serializer.errors, safe=False, status=400) def delete(self, request, id): 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.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) class StudentView(APIView): def get(self, request, _id): student = bdd.getObject(_objectName=Student, _columnName='id', _value=_id) student_serializer = StudentSerializer(student) return JsonResponse(student_serializer.data, safe=False) class GuardianView(APIView): 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) if register_form != None: student = register_form.student guardian = student.getMainGuardian() email = guardian.email errorMessage = mailer.sendRegisterForm(email) if errorMessage == '': register_form.last_update=util.convertToStr(util._now(), '%d-%m-%Y %H:%M') # Mise à jour de l'automate updateStateMachine(register_form, 'envoiDI') return JsonResponse({"errorMessage":errorMessage}, safe=False, status=400) return JsonResponse({"errorMessage":'Aucun dossier d\'inscription rattaché à l\'élève'}, safe=False, status=400) def archive(request, id): 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":'Aucun dossier d\'inscription rattaché à l\'élève'}, safe=False, status=400) def relance(request, id): register_form = bdd.getObject(_objectName=RegistrationForm, _columnName='student__id', _value=id) if register_form != None: student = register_form.student guardian = student.getMainGuardian() email = guardian.email errorMessage = mailer.envoieRelanceDossierInscription(email, register_form.codeLienInscription) if errorMessage == '': register_form.status=RegistrationForm.RegistrationFormStatus.RF_SENT 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":'Aucun dossier d\'inscription rattaché à l\'élève'}, safe=False, status=400) # API utilisée pour la vue parent class ChildrenListView(APIView): # 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): students = bdd.getObjects(_objectName=RegistrationForm, _columnName='student__guardians__associated_profile__id', _value=_idProfile) students_serializer = RegistrationFormByParentSerializer(students, many=True) return JsonResponse(students_serializer.data, safe=False) # API utilisée pour la vue de création d'un DI class StudentListView(APIView): # Récupération de la liste des élèves inscrits ou en cours d'inscriptions def get(self, request): students = bdd.getAllObjects(_objectName=Student) students_serializer = StudentByRFCreationSerializer(students, many=True) return JsonResponse(students_serializer.data, safe=False) # API utilisée pour la vue de personnalisation des frais d'inscription pour la structure class RegistrationFeeView(APIView): def get(self, request): tarifs = bdd.getAllObjects(RegistrationFee) tarifs_serializer = RegistrationFeeSerializer(tarifs, many=True) return JsonResponse(tarifs_serializer.data, safe=False) class RegistrationFileTemplateView(APIView): parser_classes = (MultiPartParser, FormParser) def get(self, request): fichiers = RegistrationFileTemplate.objects.all() serializer = RegistrationFileTemplateSerializer(fichiers, many=True) return Response(serializer.data) def post(self, request): serializer = RegistrationFileTemplateSerializer(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 delete(self, request, _id): 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) else: return JsonResponse({'erreur': 'Le fichier d\'inscription n\'a pas été trouvé'}, safe=False, status=400)