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 from rest_framework.views import APIView from rest_framework import status import json from pathlib import Path import os from io import BytesIO import GestionInscriptions.mailManager as mailer import GestionInscriptions.util as util from GestionInscriptions.serializers import FicheInscriptionSerializer, EleveSerializer, FicheInscriptionByParentSerializer, EleveByDICreationSerializer from GestionInscriptions.pagination import CustomPagination from GestionInscriptions.signals import clear_cache from .models import Eleve, Responsable, FicheInscription from GestionInscriptions.automate import Automate_DI_Inscription, load_config, getStateMachineObjectState, updateStateMachine from GestionLogin.models import Profil from N3wtSchool import settings, renderers, bdd class ListFichesInscriptionView(APIView): pagination_class = CustomPagination def get(self, request, _filter): if _filter == 'all': # 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 cached_page_size = cache.get('N3WT_page_size') if cached_page_size != page_size: clear_cache() cache.set('N3WT_page_size', page_size) # Gestion du cache page_number = request.GET.get('page', 1) cache_key = f'N3WT_ficheInscriptions_page_{page_number}_search_{search}' cached_page = cache.get(cache_key) if cached_page: return JsonResponse(cached_page, safe=False) # Filtrage des résultats if search: # Utiliser la nouvelle fonction de recherche ficheInscriptions_List = bdd.searchObjects( FicheInscription, search, _excludeState=6 # Exclure les fiches archivées ) else: # Récupère toutes les fiches non archivées ficheInscriptions_List = bdd.getObjects(FicheInscription, 'etat', 6, _reverseCondition=True) # Pagination paginator = self.pagination_class() page = paginator.paginate_queryset(ficheInscriptions_List, request) if page is not None: ficheInscriptions_serializer = FicheInscriptionSerializer(page, many=True) response_data = paginator.get_paginated_response(ficheInscriptions_serializer.data) cache.set(cache_key, response_data, timeout=60*15) return JsonResponse(response_data, safe=False) elif _filter == 'archived' : page_size = request.GET.get('page_size', None) if page_size is not None: try: page_size = int(page_size) except ValueError: page_size = settings.NB_RESULT_PER_PAGE cached_page_size = cache.get('N3WT_archived_page_size') # Comparer avec le nouveau page_size if cached_page_size != page_size: # Appeler cached_page() et mettre à jour le cache clear_cache() cache.set('N3WT_archived_page_size',page_size) page_number = request.GET.get('page', 1) cache_key_page = f'N3WT_ficheInscriptions_archives_page_{page_number}' cached_page = cache.get(cache_key_page) if cached_page: return JsonResponse(cached_page, safe=False) ficheInscriptions_List=bdd.getObjects(FicheInscription, 'etat', 6) paginator = self.pagination_class() page = paginator.paginate_queryset(ficheInscriptions_List, request) if page is not None: ficheInscriptions_serializer = FicheInscriptionSerializer(page, many=True) response_data = paginator.get_paginated_response(ficheInscriptions_serializer.data) cache.set(cache_key_page, response_data, timeout=60*15) return JsonResponse(response_data, safe=False) return JsonResponse(status=status.HTTP_404_NOT_FOUND) def post(self, request): fichesEleve_data=JSONParser().parse(request) for ficheEleve_data in fichesEleve_data: # Ajout de la date de mise à jour ficheEleve_data["dateMAJ"] = util.convertToStr(util._now(), '%d-%m-%Y %H:%M') json.dumps(ficheEleve_data) # Ajout du code d'inscription code = util.genereRandomCode(12) ficheEleve_data["codeLienInscription"] = code ficheEleve_serializer = FicheInscriptionSerializer(data=ficheEleve_data) if ficheEleve_serializer.is_valid(): ficheEleve_serializer.save() return JsonResponse(ficheEleve_serializer.errors, safe=False) @method_decorator(csrf_protect, name='dispatch') @method_decorator(ensure_csrf_cookie, name='dispatch') class FicheInscriptionView(APIView): pagination_class = CustomPagination def get(self, request, _id): ficheInscription=bdd.getObject(FicheInscription, "eleve__id", _id) fiche_serializer=FicheInscriptionSerializer(ficheInscription) return JsonResponse(fiche_serializer.data, safe=False) def post(self, request): ficheEleve_data=JSONParser().parse(request) # Ajout de la date de mise à jour ficheEleve_data["dateMAJ"] = util.convertToStr(util._now(), '%d-%m-%Y %H:%M') json.dumps(ficheEleve_data) # Ajout du code d'inscription code = util.genereRandomCode(12) ficheEleve_data["codeLienInscription"] = code responsablesId = ficheEleve_data.pop('idResponsables', []) ficheEleve_serializer = FicheInscriptionSerializer(data=ficheEleve_data) if ficheEleve_serializer.is_valid(): di = ficheEleve_serializer.save() # Mise à jour de l'automate updateStateMachine(di, 'creationDI') # Récupération du reponsable associé for responsableId in responsablesId: responsable = Responsable.objects.get(id=responsableId) di.eleve.responsables.add(responsable) di.save() ficheInscriptions_List=bdd.getAllObjects(FicheInscription) return JsonResponse({'totalInscrits':len(ficheInscriptions_List)}, safe=False) return JsonResponse(ficheEleve_serializer.errors, safe=False) def put(self, request, id): ficheEleve_data=JSONParser().parse(request) admin = ficheEleve_data.pop('admin', 1) ficheEleve_data["dateMAJ"] = str(util.convertToStr(util._now(), '%d-%m-%Y %H:%M')) ficheEleve = bdd.getObject(_objectName=FicheInscription, _columnName='eleve__id', _value=id) currentState = getStateMachineObjectState(ficheEleve.etat) if admin == 0 and currentState == FicheInscription.EtatDossierInscription.DI_ENVOYE: json.dumps(ficheEleve_data) # Ajout du fichier d'inscriptions data = { 'pdf_title': "Dossier d'inscription de %s"%ficheEleve.eleve.prenom, 'dateSignature': util.convertToStr(util._now(), '%d-%m-%Y'), 'heureSignature': util.convertToStr(util._now(), '%H:%M'), 'eleve':ficheEleve.eleve, } pdf = renderers.render_to_pdf('pdfs/dossier_inscription.html', data) nomFichierPDF = "Dossier_Inscription_%s_%s.pdf"%(ficheEleve.eleve.nom, ficheEleve.eleve.prenom) pathFichier = Path(settings.DOCUMENT_DIR + "/" + nomFichierPDF) if os.path.exists(str(pathFichier)): print(f'File exists : {str(pathFichier)}') os.remove(str(pathFichier)) receipt_file = BytesIO(pdf.content) ficheEleve.fichierInscription = File(receipt_file, nomFichierPDF) # Mise à jour de l'automate updateStateMachine(di, 'saisiDI') ficheEleve_serializer = FicheInscriptionSerializer(ficheEleve, data=ficheEleve_data) if ficheEleve_serializer.is_valid(): di = ficheEleve_serializer.save() return JsonResponse("Updated Successfully", safe=False) return JsonResponse(ficheEleve_serializer.errors, safe=False) def delete(self, request, id): fiche_inscription = bdd.getObject(_objectName=FicheInscription, _columnName='eleve__id', _value=id) if fiche_inscription != None: eleve = fiche_inscription.eleve eleve.responsables.clear() eleve.profils.clear() eleve.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) class EleveView(APIView): def get(self, request, _id): eleve = bdd.getObject(_objectName=Eleve, _columnName='id', _value=_id) eleve_serializer = EleveSerializer(eleve) return JsonResponse(eleve_serializer.data, safe=False) class ResponsableView(APIView): def get(self, request): lastResponsable = bdd.getLastId(Responsable) return JsonResponse({"lastid":lastResponsable}, safe=False) def send(request, id): fiche_inscription = bdd.getObject(_objectName=FicheInscription, _columnName='eleve__id', _value=id) if fiche_inscription != None: eleve = fiche_inscription.eleve responsable = eleve.getResponsablePrincipal() mail = responsable.mail errorMessage = mailer.envoieDossierInscription(mail) if errorMessage == '': fiche_inscription.dateMAJ=util.convertToStr(util._now(), '%d-%m-%Y %H:%M') # Mise à jour de l'automate updateStateMachine(fiche_inscription, 'envoiDI') return JsonResponse({"errorMessage":errorMessage}, safe=False) return JsonResponse({"errorMessage":'Aucun dossier d\'inscription rattaché à l\'élève'}, safe=False) def archive(request, id): fiche_inscription = bdd.getObject(_objectName=FicheInscription, _columnName='eleve__id', _value=id) if fiche_inscription != None: fiche_inscription.dateMAJ=util.convertToStr(util._now(), '%d-%m-%Y %H:%M') # Mise à jour de l'automate updateStateMachine(fiche_inscription, 'archiveDI') return JsonResponse({"errorMessage":''}, safe=False) return JsonResponse({"errorMessage":'Aucun dossier d\'inscription rattaché à l\'élève'}, safe=False) def relance(request, id): fiche_inscription = bdd.getObject(_objectName=FicheInscription, _columnName='eleve__id', _value=id) if fiche_inscription != None: eleve = fiche_inscription.eleve responsable = eleve.getResponsablePrincipal() mail = responsable.mail errorMessage = mailer.envoieRelanceDossierInscription(mail, fiche_inscription.codeLienInscription) if errorMessage == '': fiche_inscription.etat=FicheInscription.EtatDossierInscription.DI_ENVOYE fiche_inscription.dateMAJ=util.convertToStr(util._now(), '%d-%m-%Y %H:%M') fiche_inscription.save() return JsonResponse({"errorMessage":errorMessage}, safe=False) return JsonResponse({"errorMessage":'Aucun dossier d\'inscription rattaché à l\'élève'}, safe=False) # API utilisée pour la vue parent class ListeEnfantsView(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=FicheInscription, _columnName='eleve__responsables__profilAssocie__id', _value=_idProfile) students_serializer = FicheInscriptionByParentSerializer(students, many=True) return JsonResponse(students_serializer.data, safe=False) # API utilisée pour la vue de création d'un DI class ListeElevesView(APIView): # Récupération de la liste des élèves inscrits ou en cours d'inscriptions def get(self, request): students = bdd.getAllObjects(_objectName=Eleve) students_serializer = EleveByDICreationSerializer(students, many=True) return JsonResponse(students_serializer.data, safe=False)