from django.http.response import JsonResponse from django.views.decorators.csrf import ensure_csrf_cookie, csrf_protect from django.utils.decorators import method_decorator from rest_framework.views import APIView from rest_framework.decorators import action, api_view from rest_framework import status from drf_yasg.utils import swagger_auto_schema from drf_yasg import openapi import json import os from django.core.files import File import N3wtSchool.mailManager as mailer import Subscriptions.util as util from Subscriptions.serializers import RegistrationFormSerializer, RegistrationSchoolFileTemplateSerializer, RegistrationParentFileTemplateSerializer from Subscriptions.pagination import CustomSubscriptionPagination from Subscriptions.models import ( Guardian, RegistrationForm, RegistrationSchoolFileTemplate, RegistrationFileGroup, RegistrationParentFileTemplate, StudentCompetency ) from Subscriptions.automate import updateStateMachine from School.models import EstablishmentCompetency from Establishment.models import Establishment from N3wtSchool import settings, bdd from django.db.models import Q import logging logger = logging.getLogger(__name__) # /Subscriptions/registerForms class RegisterFormView(APIView): """ Gère la liste des dossiers d’inscription, lecture et création. """ pagination_class = CustomSubscriptionPagination @swagger_auto_schema( manual_parameters=[ openapi.Parameter('filter', openapi.IN_QUERY, description="filtre", type=openapi.TYPE_STRING, enum=['current_year', 'next_year', 'historical'], 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), openapi.Parameter('establishment_id', openapi.IN_QUERY, description="ID de l'établissement", type=openapi.TYPE_INTEGER, required=True), ], responses={200: RegistrationFormSerializer(many=True)}, operation_description="Récupère les dossier d'inscriptions en fonction du filtre passé.", operation_summary="Récupérer les dossier d'inscriptions", examples={ "application/json": [ { "id": 1, "student": { "id": 1, "first_name": "John", "last_name": "Doe", "date_of_birth": "2010-01-01" }, "status": "current_year", "last_update": "10-02-2025 10:00" }, { "id": 2, "student": { "id": 2, "first_name": "Jane", "last_name": "Doe", "date_of_birth": "2011-02-02" }, "status": "historical", "last_update": "09-02-2025 09:00" } ] } ) def get(self, request): """ Récupère les fiches d'inscriptions en fonction du filtre passé. """ # Récupération des paramètres filter = request.GET.get('filter', '').strip() page_size = request.GET.get('page_size', None) establishment_id = request.GET.get('establishment_id', None) search = request.GET.get('search', '').strip() # <-- Ajout du paramètre search # Gestion du page_size if page_size is not None: try: page_size = int(page_size) except ValueError: page_size = settings.NB_RESULT_SUBSCRIPTIONS_PER_PAGE # Récupérer les années scolaires current_year = util.getCurrentSchoolYear() next_year = util.getNextSchoolYear() historical_years = util.getHistoricalYears() # Récupérer les dossiers d'inscriptions en fonction du filtre registerForms_List = None if filter == 'current_year': registerForms_List = RegistrationForm.objects.filter(school_year=current_year) elif filter == 'next_year': registerForms_List = RegistrationForm.objects.filter(school_year=next_year) elif filter == 'historical': registerForms_List = RegistrationForm.objects.filter(school_year__in=historical_years) else: registerForms_List = None if registerForms_List: registerForms_List = registerForms_List.filter(establishment=establishment_id) # Ajout du filtre search sur le nom et prénom de l'élève if search: registerForms_List = registerForms_List.filter( Q(student__first_name__icontains=search) | Q(student__last_name__icontains=search) ) registerForms_List = registerForms_List.order_by('-last_update') 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) return JsonResponse(response_data, safe=False) return JsonResponse({'error': 'aucune donnée trouvée', 'count': 0}, safe=False) @swagger_auto_schema( request_body=RegistrationFormSerializer, responses={200: RegistrationFormSerializer()}, operation_description="Crée un dossier d'inscription.", operation_summary="Créer un dossier d'inscription", examples={ "application/json": { "student": { "id": 1, "first_name": "John", "last_name": "Doe", "date_of_birth": "2010-01-01" }, "status": "current_year", "last_update": "10-02-2025 10:00", "codeLienInscription": "ABC123XYZ456" } } ) @method_decorator(csrf_protect, name='dispatch') @method_decorator(ensure_csrf_cookie, name='dispatch') def post(self, request): """ Crée un dossier d'inscription. """ regiterFormData = request.data.copy() logger.info(f"Création d'un dossier d'inscription {request}") # Ajout de la date de mise à jour regiterFormData["last_update"] = util.convertToStr(util._now(), '%d-%m-%Y %H:%M') # Ajout du code d'inscription code = util.genereRandomCode(12) regiterFormData["codeLienInscription"] = code guardiansId = regiterFormData.pop('idGuardians', []) registerForm_serializer = RegistrationFormSerializer(data=regiterFormData) fileGroupId = regiterFormData.pop('fileGroup', None) if registerForm_serializer.is_valid(): di = registerForm_serializer.save() # Mise à jour de l'automate updateStateMachine(di, 'EVENT_INIT') # Récupération du reponsable associé for guardianId in guardiansId: guardian = Guardian.objects.get(id=guardianId) di.student.guardians.add(guardian) di.save() if fileGroupId: di.fileGroup = RegistrationFileGroup.objects.get(id=fileGroupId) di.save() return JsonResponse(registerForm_serializer.data, safe=False) else: logger.error(f"Erreur lors de la validation des données {regiterFormData}") return JsonResponse(registerForm_serializer.errors, safe=False, status=status.HTTP_400_BAD_REQUEST) # /Subscriptions/registerForms/{id} class RegisterFormWithIdView(APIView): """ Gère la lecture, création, modification et suppression d’un dossier d’inscription. """ pagination_class = CustomSubscriptionPagination @swagger_auto_schema( responses={200: RegistrationFormSerializer()}, operation_description="Récupère un dossier d'inscription donné.", operation_summary="Récupérer un dossier d'inscription", examples={ "application/json": { "id": 1, "student": { "id": 1, "first_name": "John", "last_name": "Doe", "date_of_birth": "2010-01-01" }, } } ) def get(self, request, id): """ Récupère un dossier d'inscription donné. """ registerForm = bdd.getObject(RegistrationForm, "student__id", id) if registerForm is None: return JsonResponse({"errorMessage":'Le dossier d\'inscription n\'a pas été trouvé'}, safe=False, status=status.HTTP_404_NOT_FOUND) registerForm_serializer = RegistrationFormSerializer(registerForm) return JsonResponse(registerForm_serializer.data, safe=False) @swagger_auto_schema( request_body=RegistrationFormSerializer, responses={200: RegistrationFormSerializer()}, operation_description="Modifie un dossier d'inscription donné.", operation_summary="Modifier un dossier d'inscription", examples={ "application/json": { "id": 1, "student": { "id": 1, "first_name": "John", "last_name": "Doe", "date_of_birth": "2010-01-01" }, "status": "under_review", "last_update": "10-02-2025 10:00" } } ) @method_decorator(csrf_protect, name='dispatch') @method_decorator(ensure_csrf_cookie, name='dispatch') def put(self, request, id): """ Modifie un dossier d'inscription donné. """ studentForm_data = request.data.get('data', '{}') try: data = json.loads(studentForm_data) except json.JSONDecodeError: return JsonResponse({"error": "Invalid JSON format in 'data'"}, status=status.HTTP_400_BAD_REQUEST) # Extraire le fichier photo photo_file = request.FILES.get('photo') # Extraire le fichier photo sepa_file = request.FILES.get('sepa_file') # Ajouter la photo aux données de l'étudiant if photo_file: data['student']['photo'] = photo_file if sepa_file: data['sepa_file'] = sepa_file # Gérer le champ `_status` _status = data.pop('status', 0) _status = int(_status) # Récupérer le dossier d'inscription registerForm = bdd.getObject(_objectName=RegistrationForm, _columnName='student__id', _value=id) if not registerForm: return JsonResponse({"error": "Dossier d'inscription introuvable"}, status=status.HTTP_404_NOT_FOUND) studentForm_serializer = RegistrationFormSerializer(registerForm, data=data, partial=True) if studentForm_serializer.is_valid(): studentForm_serializer.save() # Sauvegarder la photo si elle est présente dans la requête if photo_file: student = registerForm.student # Vérifier si une photo existante est déjà associée à l'étudiant if student.photo and student.photo.name: # Construire le chemin complet du fichier existant if os.path.isabs(student.photo.name): existing_file_path = student.photo.name else: existing_file_path = os.path.join(settings.MEDIA_ROOT, student.photo.name.lstrip('/')) # Vérifier si le fichier existe et le supprimer if os.path.exists(existing_file_path): os.remove(existing_file_path) student.photo.delete(save=False) else: print(f'File does not exist: {existing_file_path}') # Sauvegarder la nouvelle photo student.photo.save(photo_file.name, photo_file, save=True) else: return JsonResponse(studentForm_serializer.errors, safe=False, status=status.HTTP_400_BAD_REQUEST) if _status == RegistrationForm.RegistrationFormStatus.RF_UNDER_REVIEW: # Le parent a rempli le dossier d'inscription sans sélectionner "Prélèvement par Mandat SEPA" # L'école doit désormais valider le dossier d'inscription try: # Génération de la fiche d'inscription au format PDF base_dir = os.path.join(settings.MEDIA_ROOT, f"registration_files/dossier_rf_{registerForm.pk}") os.makedirs(base_dir, exist_ok=True) # Fichier PDF initial initial_pdf = f"{base_dir}/Inscription_{registerForm.student.last_name}_{registerForm.student.first_name}.pdf" registerForm.registration_file = util.rfToPDF(registerForm, initial_pdf) registerForm.save() # Mise à jour de l'automate # Vérification de la présence du fichier SEPA if registerForm.sepa_file: # Mise à jour de l'automate pour SEPA updateStateMachine(registerForm, 'EVENT_SIGNATURE_SEPA') else: # Mise à jour de l'automate pour une signature classique updateStateMachine(registerForm, 'EVENT_SIGNATURE') except Exception as e: return JsonResponse({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) elif _status == RegistrationForm.RegistrationFormStatus.RF_SENT: if registerForm.status == RegistrationForm.RegistrationFormStatus.RF_UNDER_REVIEW: updateStateMachine(registerForm, 'EVENT_REFUSE') util.delete_registration_files(registerForm) elif _status == RegistrationForm.RegistrationFormStatus.RF_SEPA_SENT: # Sauvegarde du mandat SEPA student = registerForm.student guardian = student.getMainGuardian() email = guardian.profile_role.profile.email errorMessage = mailer.sendMandatSEPA(email, registerForm.establishment.pk) if errorMessage != '': return JsonResponse({"errorMessage": errorMessage}, safe=False, status=status.HTTP_400_BAD_REQUEST) registerForm.last_update = util.convertToStr(util._now(), '%d-%m-%Y %H:%M') updateStateMachine(registerForm, 'EVENT_SEND_SEPA') elif _status == RegistrationForm.RegistrationFormStatus.RF_SEPA_TO_SEND: # Le parent a rempli le dossier d'inscription en sélectionnant "Prélèvement par Mandat SEPA" # L'école doit désormais envoyer le mandat SEPA pour poursuivre l'inscription updateStateMachine(registerForm, 'EVENT_WAITING_FOR_SEPA') elif _status == RegistrationForm.RegistrationFormStatus.RF_VALIDATED: # Vérifier si le paramètre fusion est activé via l'URL fusion = data.get('fusionParam', False) if fusion: # Fusion des documents # Récupération des fichiers schoolFileTemplates school_file_paths = RegistrationSchoolFileTemplate.get_files_from_rf(registerForm.pk) # Récupération des fichiers parentFileTemplates parent_file_templates = RegistrationParentFileTemplate.get_files_from_rf(registerForm.pk) # Initialisation de la liste des fichiers à fusionner fileNames = [] # Ajout du fichier registration_file en première position if registerForm.registration_file: fileNames.append(registerForm.registration_file.path) # Ajout des fichiers schoolFileTemplates fileNames.extend(school_file_paths) # Ajout des fichiers parentFileTemplates fileNames.extend(parent_file_templates) # Création du fichier PDF fusionné merged_pdf_content = util.merge_files_pdf(fileNames) # Mise à jour du champ registration_file avec le fichier fusionné registerForm.fusion_file.save( f"dossier_complet.pdf", File(merged_pdf_content), save=True ) # Valorisation des StudentCompetency pour l'élève try: student = registerForm.student cycle = None if student.level: cycle = student.level.cycle.number if cycle: # Récupérer les EstablishmentCompetency de l'établissement et du cycle de l'élève establishment_competencies = EstablishmentCompetency.objects.filter( establishment=registerForm.establishment, custom_category__domain__cycle=cycle ) | EstablishmentCompetency.objects.filter( establishment=registerForm.establishment, competency__category__domain__cycle=cycle ) establishment_competencies = establishment_competencies.distinct() establishment = registerForm.establishment evaluation_frequency = establishment.evaluation_frequency # 1=Trimestre, 2=Semestre, 3=Année school_year = registerForm.school_year # ex: "2024_2025" establishment_competencies = establishment_competencies.distinct() periods = [] if evaluation_frequency == 1: # Trimestre periods = [f"T{i+1}_{school_year}" for i in range(3)] elif evaluation_frequency == 2: # Semestre periods = [f"S{i+1}_{school_year}" for i in range(2)] elif evaluation_frequency == 3: # Année periods = [f"A_{school_year}"] for ec in establishment_competencies: for period in periods: StudentCompetency.objects.get_or_create( student=student, establishment_competency=ec, period=period ) except Exception as e: logger.error(f"Erreur lors de la valorisation des StudentCompetency: {e}") updateStateMachine(registerForm, 'EVENT_VALIDATE') # Retourner les données mises à jour return JsonResponse(studentForm_serializer.data, safe=False) @swagger_auto_schema( request_body=openapi.Schema( type=openapi.TYPE_OBJECT, properties={ 'student_data': openapi.Schema(type=openapi.TYPE_STRING, description='JSON string des données étudiant'), 'guardians_data': openapi.Schema(type=openapi.TYPE_STRING, description='JSON string des données responsables'), 'siblings_data': openapi.Schema(type=openapi.TYPE_STRING, description='JSON string des données fratrie'), 'payment_data': openapi.Schema(type=openapi.TYPE_STRING, description='JSON string des données de paiement'), 'current_page': openapi.Schema(type=openapi.TYPE_INTEGER, description='Page actuelle du formulaire'), 'auto_save': openapi.Schema(type=openapi.TYPE_BOOLEAN, description='Indicateur auto-save'), } ), responses={200: RegistrationFormSerializer()}, operation_description="Auto-sauvegarde partielle d'un dossier d'inscription.", operation_summary="Auto-sauvegarder un dossier d'inscription" ) @method_decorator(csrf_protect, name='dispatch') @method_decorator(ensure_csrf_cookie, name='dispatch') def patch(self, request, id): """ Auto-sauvegarde partielle d'un dossier d'inscription. Cette méthode est optimisée pour les sauvegardes automatiques périodiques. """ try: # Récupérer le dossier d'inscription registerForm = bdd.getObject(_objectName=RegistrationForm, _columnName='student__id', _value=id) if not registerForm: return JsonResponse({"error": "Dossier d'inscription introuvable"}, status=status.HTTP_404_NOT_FOUND) # Préparer les données à mettre à jour update_data = {} # Traiter les données étudiant si présentes if 'student_data' in request.data: try: student_data = json.loads(request.data['student_data']) # Extraire les données de paiement des données étudiant payment_fields = ['registration_payment', 'tuition_payment', 'registration_payment_plan', 'tuition_payment_plan'] payment_data = {} for field in payment_fields: if field in student_data: payment_data[field] = student_data.pop(field) # Si nous avons des données de paiement, les traiter if payment_data: logger.debug(f"Auto-save: extracted payment_data from student_data = {payment_data}") # Traiter les données de paiement payment_updates = {} # Gestion du mode de paiement d'inscription if 'registration_payment' in payment_data and payment_data['registration_payment']: try: from School.models import PaymentMode payment_mode = PaymentMode.objects.get(id=payment_data['registration_payment']) registerForm.registration_payment = payment_mode payment_updates['registration_payment'] = payment_mode.id except PaymentMode.DoesNotExist: logger.warning(f"Auto-save: PaymentMode with id {payment_data['registration_payment']} not found") # Gestion du mode de paiement de scolarité if 'tuition_payment' in payment_data and payment_data['tuition_payment']: try: from School.models import PaymentMode payment_mode = PaymentMode.objects.get(id=payment_data['tuition_payment']) registerForm.tuition_payment = payment_mode payment_updates['tuition_payment'] = payment_mode.id except PaymentMode.DoesNotExist: logger.warning(f"Auto-save: PaymentMode with id {payment_data['tuition_payment']} not found") # Gestion du plan de paiement d'inscription if 'registration_payment_plan' in payment_data and payment_data['registration_payment_plan']: try: from School.models import PaymentPlan payment_plan = PaymentPlan.objects.get(id=payment_data['registration_payment_plan']) registerForm.registration_payment_plan = payment_plan payment_updates['registration_payment_plan'] = payment_plan.id except PaymentPlan.DoesNotExist: logger.warning(f"Auto-save: PaymentPlan with id {payment_data['registration_payment_plan']} not found") # Gestion du plan de paiement de scolarité if 'tuition_payment_plan' in payment_data and payment_data['tuition_payment_plan']: try: from School.models import PaymentPlan payment_plan = PaymentPlan.objects.get(id=payment_data['tuition_payment_plan']) registerForm.tuition_payment_plan = payment_plan payment_updates['tuition_payment_plan'] = payment_plan.id except PaymentPlan.DoesNotExist: logger.warning(f"Auto-save: PaymentPlan with id {payment_data['tuition_payment_plan']} not found") # Sauvegarder les modifications de paiement if payment_updates: registerForm.save() logger.debug(f"Auto-save: Payment data updated - {payment_updates}") update_data['student'] = student_data except json.JSONDecodeError: logger.warning("Auto-save: Invalid JSON in student_data") # Traiter les données des responsables si présentes if 'guardians_data' in request.data: try: guardians_data = json.loads(request.data['guardians_data']) logger.debug(f"Auto-save: guardians_data = {guardians_data}") # Enregistrer directement chaque guardian avec le modèle for i, guardian_data in enumerate(guardians_data): guardian_id = guardian_data.get('id') if guardian_id: try: # Récupérer le guardian existant et mettre à jour ses champs guardian = Guardian.objects.get(id=guardian_id) # Mettre à jour les champs si ils sont présents if 'birth_date' in guardian_data and guardian_data['birth_date']: guardian.birth_date = guardian_data['birth_date'] if 'profession' in guardian_data: guardian.profession = guardian_data['profession'] if 'address' in guardian_data: guardian.address = guardian_data['address'] if 'phone' in guardian_data: guardian.phone = guardian_data['phone'] if 'first_name' in guardian_data: guardian.first_name = guardian_data['first_name'] if 'last_name' in guardian_data: guardian.last_name = guardian_data['last_name'] guardian.save() logger.debug(f"Guardian {i}: Updated birth_date={guardian.birth_date}, profession={guardian.profession}, address={guardian.address}") except Guardian.DoesNotExist: logger.warning(f"Auto-save: Guardian with id {guardian_id} not found") except json.JSONDecodeError: logger.warning("Auto-save: Invalid JSON in guardians_data") # Traiter les données de la fratrie si présentes if 'siblings_data' in request.data: try: siblings_data = json.loads(request.data['siblings_data']) logger.debug(f"Auto-save: siblings_data = {siblings_data}") # Enregistrer directement chaque sibling avec le modèle for i, sibling_data in enumerate(siblings_data): sibling_id = sibling_data.get('id') if sibling_id: try: # Récupérer le sibling existant et mettre à jour ses champs from Subscriptions.models import Sibling sibling = Sibling.objects.get(id=sibling_id) # Mettre à jour les champs si ils sont présents if 'first_name' in sibling_data: sibling.first_name = sibling_data['first_name'] if 'last_name' in sibling_data: sibling.last_name = sibling_data['last_name'] if 'birth_date' in sibling_data and sibling_data['birth_date']: sibling.birth_date = sibling_data['birth_date'] sibling.save() logger.debug(f"Sibling {i}: Updated first_name={sibling.first_name}, last_name={sibling.last_name}, birth_date={sibling.birth_date}") except Sibling.DoesNotExist: logger.warning(f"Auto-save: Sibling with id {sibling_id} not found") except json.JSONDecodeError: logger.warning("Auto-save: Invalid JSON in siblings_data") # Traiter les données de paiement si présentes if 'payment_data' in request.data: try: payment_data = json.loads(request.data['payment_data']) logger.debug(f"Auto-save: payment_data = {payment_data}") # Mettre à jour directement les champs de paiement du formulaire payment_updates = {} # Gestion du mode de paiement d'inscription if 'registration_payment' in payment_data and payment_data['registration_payment']: try: from School.models import PaymentMode payment_mode = PaymentMode.objects.get(id=payment_data['registration_payment']) registerForm.registration_payment = payment_mode payment_updates['registration_payment'] = payment_mode.id except PaymentMode.DoesNotExist: logger.warning(f"Auto-save: PaymentMode with id {payment_data['registration_payment']} not found") # Gestion du mode de paiement de scolarité if 'tuition_payment' in payment_data and payment_data['tuition_payment']: try: from School.models import PaymentMode payment_mode = PaymentMode.objects.get(id=payment_data['tuition_payment']) registerForm.tuition_payment = payment_mode payment_updates['tuition_payment'] = payment_mode.id except PaymentMode.DoesNotExist: logger.warning(f"Auto-save: PaymentMode with id {payment_data['tuition_payment']} not found") # Gestion du plan de paiement d'inscription if 'registration_payment_plan' in payment_data and payment_data['registration_payment_plan']: try: from School.models import PaymentPlan payment_plan = PaymentPlan.objects.get(id=payment_data['registration_payment_plan']) registerForm.registration_payment_plan = payment_plan payment_updates['registration_payment_plan'] = payment_plan.id except PaymentPlan.DoesNotExist: logger.warning(f"Auto-save: PaymentPlan with id {payment_data['registration_payment_plan']} not found") # Gestion du plan de paiement de scolarité if 'tuition_payment_plan' in payment_data and payment_data['tuition_payment_plan']: try: from School.models import PaymentPlan payment_plan = PaymentPlan.objects.get(id=payment_data['tuition_payment_plan']) registerForm.tuition_payment_plan = payment_plan payment_updates['tuition_payment_plan'] = payment_plan.id except PaymentPlan.DoesNotExist: logger.warning(f"Auto-save: PaymentPlan with id {payment_data['tuition_payment_plan']} not found") # Sauvegarder les modifications de paiement if payment_updates: registerForm.save() logger.debug(f"Auto-save: Payment data updated - {payment_updates}") except json.JSONDecodeError: logger.warning("Auto-save: Invalid JSON in payment_data") # Mettre à jour la page actuelle si présente if 'current_page' in request.data: try: current_page = int(request.data['current_page']) # Vous pouvez sauvegarder cette info dans un champ du modèle si nécessaire logger.debug(f"Auto-save: current_page = {current_page}") except (ValueError, TypeError): logger.warning("Auto-save: Invalid current_page value") # Effectuer la mise à jour partielle seulement si nous avons des données if update_data: serializer = RegistrationFormSerializer(registerForm, data=update_data, partial=True) if serializer.is_valid(): serializer.save() logger.debug(f"Auto-save successful for student {id}") return JsonResponse({"status": "auto_save_success", "timestamp": util._now().isoformat()}, safe=False) else: logger.warning(f"Auto-save validation errors: {serializer.errors}") # Pour l'auto-save, on retourne un succès même en cas d'erreur de validation return JsonResponse({"status": "auto_save_partial", "errors": serializer.errors}, safe=False) else: # Pas de données à sauvegarder, mais on retourne un succès return JsonResponse({"status": "auto_save_no_data"}, safe=False) except Exception as e: logger.error(f"Auto-save error for student {id}: {str(e)}") # Pour l'auto-save, on ne retourne pas d'erreur HTTP pour éviter d'interrompre l'UX return JsonResponse({"status": "auto_save_failed", "error": str(e)}, safe=False) @swagger_auto_schema( responses={204: 'No Content'}, operation_description="Supprime un dossier d'inscription donné.", operation_summary="Supprimer un dossier d'inscription" ) @method_decorator(csrf_protect, name='dispatch') @method_decorator(ensure_csrf_cookie, name='dispatch') 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() 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=status.HTTP_404_NOT_FOUND) @swagger_auto_schema( method='get', responses={200: openapi.Response('Success', schema=openapi.Schema( type=openapi.TYPE_OBJECT, properties={ 'message': openapi.Schema(type=openapi.TYPE_STRING) } ))}, operation_description="Envoie le dossier d'inscription par e-mail", operation_summary="Envoyer un dossier d'inscription" ) @api_view(['GET']) def send(request,id): """Envoie le dossier d'inscription 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() email = guardian.profile_role.profile.email errorMessage = mailer.sendRegisterForm(email, register_form.establishment.pk) if errorMessage == '': register_form.last_update=util.convertToStr(util._now(), '%d-%m-%Y %H:%M') updateStateMachine(register_form, 'EVENT_SEND') return JsonResponse({"message": f"Le dossier d'inscription a bien été envoyé à l'addresse {email}"}, safe=False) return JsonResponse({"errorMessage":errorMessage}, safe=False, status=status.HTTP_400_BAD_REQUEST) return JsonResponse({"errorMessage":'Dossier d\'inscription non trouvé'}, safe=False, status=status.HTTP_404_NOT_FOUND) @swagger_auto_schema( method='get', responses={200: openapi.Response('Success', schema=openapi.Schema( type=openapi.TYPE_OBJECT, properties={ 'message': openapi.Schema(type=openapi.TYPE_STRING) } ))}, operation_description="Archive le dossier d'inscription", operation_summary="Archiver un dossier d'inscription" ) @api_view(['GET']) def archive(request,id): """Archive le dossier d'inscription.""" 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') updateStateMachine(register_form, 'EVENT_ARCHIVE') return JsonResponse({"message": "Le dossier a été archivé avec succès"}, safe=False) return JsonResponse({"errorMessage":'Dossier d\'inscription non trouvé'}, safe=False, status=status.HTTP_404_NOT_FOUND) @swagger_auto_schema( method='get', responses={200: openapi.Response('Success', schema=openapi.Schema( type=openapi.TYPE_OBJECT, properties={ 'message': openapi.Schema(type=openapi.TYPE_STRING) } ))}, operation_description="Relance un dossier d'inscription par e-mail", operation_summary="Relancer un dossier d'inscription" ) @api_view(['GET']) def resend(request,id): """Relance un dossier d'inscription 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() 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({"message": f"Le dossier a été renvoyé à l'adresse {email}"}, safe=False) return JsonResponse({"errorMessage":errorMessage}, safe=False, status=status.HTTP_400_BAD_REQUEST) return JsonResponse({"errorMessage":'Dossier d\'inscription non trouvé'}, safe=False, status=status.HTTP_404_NOT_FOUND) @swagger_auto_schema( method='get', responses={200: openapi.Response('Success', schema=openapi.Schema( type=openapi.TYPE_OBJECT, properties={ 'message': openapi.Schema(type=openapi.TYPE_STRING) } ))}, operation_description="Récupère les fichiers à signer d'un dossier d'inscription donné", operation_summary="Récupérer les fichiers à signer d'un dossier d'inscription donné" ) @api_view(['GET']) def get_school_file_templates_by_rf(request, id): try: # Récupérer les templates associés au RegistrationForm donné templates = RegistrationSchoolFileTemplate.objects.filter(registration_form=id) # Sérialiser les données serializer = RegistrationSchoolFileTemplateSerializer(templates, many=True) # Retourner les données sérialisées return JsonResponse(serializer.data, safe=False) except RegistrationSchoolFileTemplate.DoesNotExist: return JsonResponse({'error': 'Aucun template trouvé pour ce dossier d\'inscription'}, status=status.HTTP_404_NOT_FOUND) @swagger_auto_schema( method='get', responses={200: openapi.Response('Success', schema=openapi.Schema( type=openapi.TYPE_OBJECT, properties={ 'message': openapi.Schema(type=openapi.TYPE_STRING) } ))}, operation_description="Récupère les pièces à fournir d'un dossier d'inscription donné", operation_summary="Récupérer les pièces à fournir d'un dossier d'inscription donné" ) @api_view(['GET']) def get_parent_file_templates_by_rf(request, id): try: # Récupérer les pièces à fournir associés au RegistrationForm donné parent_files = RegistrationParentFileTemplate.objects.filter(registration_form=id) # Sérialiser les données serializer = RegistrationParentFileTemplateSerializer(parent_files, many=True) # Retourner les données sérialisées return JsonResponse(serializer.data, safe=False) except RegistrationParentFileTemplate.DoesNotExist: return JsonResponse({'error': 'Aucune pièce à fournir trouvée pour ce dossier d\'inscription'}, status=status.HTTP_404_NOT_FOUND)