mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-01-29 07:53:23 +00:00
feat: Signatures électroniques docuseal [#22]
This commit is contained in:
1
Back-End/DocuSeal/__init__.py
Normal file
1
Back-End/DocuSeal/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
# This file is intentionally left blank to make this directory a Python package.
|
||||
7
Back-End/DocuSeal/urls.py
Normal file
7
Back-End/DocuSeal/urls.py
Normal file
@ -0,0 +1,7 @@
|
||||
from django.urls import path, re_path
|
||||
from .views import generate_jwt_token, clone_template
|
||||
|
||||
urlpatterns = [
|
||||
re_path(r'generateToken$', generate_jwt_token, name='generate_jwt_token'),
|
||||
re_path(r'cloneTemplate$', clone_template, name='clone_template'),
|
||||
]
|
||||
81
Back-End/DocuSeal/views.py
Normal file
81
Back-End/DocuSeal/views.py
Normal file
@ -0,0 +1,81 @@
|
||||
from django.conf import settings
|
||||
from django.http import JsonResponse
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from rest_framework.decorators import api_view
|
||||
from rest_framework.response import Response
|
||||
from rest_framework import status
|
||||
import jwt
|
||||
import datetime
|
||||
import requests
|
||||
|
||||
@csrf_exempt
|
||||
@api_view(['POST'])
|
||||
def generate_jwt_token(request):
|
||||
# Vérifier la clé API
|
||||
api_key = request.headers.get('X-Auth-Token')
|
||||
print(f'api_key : {api_key}')
|
||||
print(f'settings.DOCUSEAL_JWT["API_KEY"] : {settings.DOCUSEAL_JWT["API_KEY"]}')
|
||||
if not api_key or api_key != settings.DOCUSEAL_JWT["API_KEY"]:
|
||||
return Response({'error': 'Invalid API key'}, status=status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
# Récupérer les données de la requête
|
||||
user_email = request.data.get('user_email')
|
||||
documents_urls = request.data.get('documents_urls', [])
|
||||
template_id = request.data.get('template_id') # Récupérer le template_id
|
||||
|
||||
# Vérifier les données requises
|
||||
if not user_email:
|
||||
return Response({'error': 'User email is required'}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# Utiliser la configuration JWT de DocuSeal depuis les settings
|
||||
jwt_secret = settings.DOCUSEAL_JWT['API_KEY']
|
||||
jwt_algorithm = settings.DOCUSEAL_JWT['ALGORITHM']
|
||||
expiration_delta = settings.DOCUSEAL_JWT['EXPIRATION_DELTA']
|
||||
|
||||
# Définir le payload
|
||||
payload = {
|
||||
'user_email': user_email,
|
||||
'documents_urls': documents_urls,
|
||||
'template_id': template_id, # Ajouter le template_id au payload
|
||||
'exp': datetime.datetime.utcnow() + expiration_delta # Temps d'expiration du token
|
||||
}
|
||||
|
||||
# Générer le token JWT
|
||||
token = jwt.encode(payload, jwt_secret, algorithm=jwt_algorithm)
|
||||
|
||||
return Response({'token': token}, status=status.HTTP_200_OK)
|
||||
|
||||
@csrf_exempt
|
||||
@api_view(['POST'])
|
||||
def clone_template(request):
|
||||
# Vérifier la clé API
|
||||
api_key = request.headers.get('X-Auth-Token')
|
||||
if not api_key or api_key != settings.DOCUSEAL_JWT["API_KEY"]:
|
||||
return Response({'error': 'Invalid API key'}, status=status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
# Récupérer les données de la requête
|
||||
document_id = request.data.get('templateId')
|
||||
email = request.data.get('email')
|
||||
|
||||
# Vérifier les données requises
|
||||
if not document_id or not email :
|
||||
return Response({'error': 'template ID, email are required'}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# URL de l'API de DocuSeal pour cloner le template
|
||||
clone_url = f'https://docuseal.com/api/templates/{document_id}/clone'
|
||||
|
||||
# Faire la requête pour cloner le template
|
||||
try:
|
||||
response = requests.post(clone_url, json={'submitters': [{'email': email}]}, headers={
|
||||
'Content-Type': 'application/json',
|
||||
'X-Auth-Token': settings.DOCUSEAL_JWT['API_KEY']
|
||||
})
|
||||
|
||||
if response.status_code != 200:
|
||||
return Response({'error': 'Failed to clone template'}, status=response.status_code)
|
||||
|
||||
data = response.json()
|
||||
return Response(data, status=status.HTTP_200_OK)
|
||||
|
||||
except requests.RequestException as e:
|
||||
return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||
8
Back-End/N3wtSchool/middleware.py
Normal file
8
Back-End/N3wtSchool/middleware.py
Normal file
@ -0,0 +1,8 @@
|
||||
class ContentSecurityPolicyMiddleware:
|
||||
def __init__(self, get_response):
|
||||
self.get_response = get_response
|
||||
|
||||
def __call__(self, request):
|
||||
response = self.get_response(request)
|
||||
response['Content-Security-Policy'] = "frame-ancestors 'self' http://localhost:3000"
|
||||
return response
|
||||
@ -251,6 +251,12 @@ DOCUMENT_DIR = 'documents'
|
||||
CORS_ORIGIN_ALLOW_ALL = True
|
||||
CORS_ALLOW_ALL_HEADERS = True
|
||||
CORS_ALLOW_CREDENTIALS = True
|
||||
CORS_ALLOW_HEADERS = [
|
||||
'content-type',
|
||||
'authorization',
|
||||
'X-Auth-Token',
|
||||
'x-csrftoken'
|
||||
]
|
||||
|
||||
CORS_ALLOWED_ORIGINS = [
|
||||
os.getenv('CORS_ALLOWED_ORIGINS', 'http://localhost:3000')
|
||||
@ -333,5 +339,5 @@ DOCUSEAL_JWT = {
|
||||
'ALGORITHM': 'HS256',
|
||||
'SIGNING_KEY': SECRET_KEY,
|
||||
'EXPIRATION_DELTA': timedelta(hours=1),
|
||||
'API_KEY': '1kzHsXqN8P2ezUGT7TjVuBwM1hqtLsztrVSsQ87T7Mz'
|
||||
'API_KEY': os.getenv('DOCUSEAL_API_KEY')
|
||||
}
|
||||
@ -7,7 +7,7 @@ from Subscriptions.models import (
|
||||
Fee,
|
||||
Discount,
|
||||
RegistrationFileGroup,
|
||||
RegistrationFileTemplate
|
||||
# RegistrationFileTemplate
|
||||
)
|
||||
from Auth.models import Profile
|
||||
from School.models import (
|
||||
@ -43,7 +43,7 @@ class Command(BaseCommand):
|
||||
self.create_or_update_teachers()
|
||||
self.create_or_update_school_classes()
|
||||
self.create_or_update_registration_file_group()
|
||||
self.create_or_update_registration_file_template()
|
||||
# self.create_or_update_registration_file_template()
|
||||
self.create_register_form()
|
||||
|
||||
def create_or_update_establishment(self):
|
||||
@ -376,13 +376,21 @@ class Command(BaseCommand):
|
||||
self.stdout.write(self.style.SUCCESS('SchoolClasses initialized or updated successfully'))
|
||||
|
||||
def create_or_update_registration_file_group(self):
|
||||
group_data = {
|
||||
group_data_1 = {
|
||||
"name": "LMDE",
|
||||
"description": "Fichiers d'inscription de l'école LMDE"
|
||||
}
|
||||
|
||||
self.registration_file_group, created = RegistrationFileGroup.objects.get_or_create(name=group_data["name"], defaults=group_data)
|
||||
self.stdout.write(self.style.SUCCESS('RegistrationFileGroup initialized or updated successfully'))
|
||||
self.registration_file_group_1, created = RegistrationFileGroup.objects.get_or_create(name=group_data_1["name"], defaults=group_data_1)
|
||||
self.stdout.write(self.style.SUCCESS('RegistrationFileGroup 1 initialized or updated successfully'))
|
||||
|
||||
group_data_2 = {
|
||||
"name": "LMDE 2",
|
||||
"description": "Fichiers d'inscription de l'école LMDE 2"
|
||||
}
|
||||
|
||||
self.registration_file_group_2, created = RegistrationFileGroup.objects.get_or_create(name=group_data_2["name"], defaults=group_data_2)
|
||||
self.stdout.write(self.style.SUCCESS('RegistrationFileGroup 2 initialized or updated successfully'))
|
||||
|
||||
def create_or_update_registration_file_template(self):
|
||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
@ -394,28 +402,28 @@ class Command(BaseCommand):
|
||||
"file": "RIB LA MAISON DES ENFANTS.pdf",
|
||||
"order": 0,
|
||||
"is_required": False,
|
||||
"group": self.registration_file_group
|
||||
"group": self.registration_file_group_2 # Associer ce fichier au deuxième groupe
|
||||
},
|
||||
{
|
||||
"name": "Contrat d'engagement 2024 2025",
|
||||
"file": "Contrat d'engagement 2024 2025.pdf",
|
||||
"order": 0,
|
||||
"is_required": True,
|
||||
"group": self.registration_file_group
|
||||
"group": self.registration_file_group_1
|
||||
},
|
||||
{
|
||||
"name": "Bulletin d'adhésion familiale scolaire",
|
||||
"file": "Bulletin d'adhésion familiale scolaire.pdf",
|
||||
"order": 0,
|
||||
"is_required": True,
|
||||
"group": self.registration_file_group
|
||||
"group": self.registration_file_group_1
|
||||
},
|
||||
{
|
||||
"name": "Fiche sanitaire de liaison",
|
||||
"file": "Fiche sanitaire de liaison.pdf",
|
||||
"order": 0,
|
||||
"is_required": True,
|
||||
"group": self.registration_file_group
|
||||
"group": self.registration_file_group_1
|
||||
}
|
||||
]
|
||||
|
||||
@ -442,69 +450,79 @@ class Command(BaseCommand):
|
||||
|
||||
def create_register_form(self):
|
||||
# Créer ou mettre à jour le profil associé au guardian
|
||||
profile_data = {
|
||||
"email": "anthony.casini.30@gmail.com",
|
||||
"droit": 2,
|
||||
"username": "anthony.casini.30@gmail.com",
|
||||
"is_active": True,
|
||||
"password": "Provisoire01!"
|
||||
}
|
||||
|
||||
user, created = Profile.objects.update_or_create(
|
||||
email=profile_data["email"],
|
||||
defaults={
|
||||
"username": profile_data["username"],
|
||||
"email": profile_data["email"],
|
||||
"is_active": profile_data["is_active"],
|
||||
"droit": profile_data["droit"]
|
||||
profiles_data = [
|
||||
{
|
||||
"email": "anthony.casini.30@gmail.com",
|
||||
"droit": 2,
|
||||
"username": "anthony.casini.30@gmail.com",
|
||||
"is_active": True,
|
||||
"password": "Provisoire01!"
|
||||
},
|
||||
{
|
||||
"email": "anthony.audrey.34@gmail.com",
|
||||
"droit": 2,
|
||||
"username": "anthony.audrey.34@gmail.com",
|
||||
"is_active": True,
|
||||
"password": "Provisoire01!"
|
||||
}
|
||||
)
|
||||
if created:
|
||||
user.set_password(profile_data["password"])
|
||||
user.save()
|
||||
]
|
||||
|
||||
# Créer les données du guardian
|
||||
guardian_data = {
|
||||
"associated_profile_id": user.id,
|
||||
"email": "anthony.casini.30@gmail.com",
|
||||
}
|
||||
for profile_data in profiles_data:
|
||||
user, created = Profile.objects.update_or_create(
|
||||
email=profile_data["email"],
|
||||
defaults={
|
||||
"username": profile_data["username"],
|
||||
"email": profile_data["email"],
|
||||
"is_active": profile_data["is_active"],
|
||||
"droit": profile_data["droit"]
|
||||
}
|
||||
)
|
||||
if created:
|
||||
user.set_password(profile_data["password"])
|
||||
user.save()
|
||||
|
||||
# Créer les données de l'étudiant
|
||||
student_data = {
|
||||
"last_name": "CASINI",
|
||||
"first_name": "Giulia",
|
||||
}
|
||||
# Créer les données du guardian
|
||||
guardian_data = {
|
||||
"associated_profile_id": user.id,
|
||||
"email": profile_data["email"],
|
||||
}
|
||||
|
||||
# Créer ou mettre à jour l'étudiant et le guardian
|
||||
student, created = Student.objects.get_or_create(
|
||||
last_name=student_data["last_name"],
|
||||
first_name=student_data["first_name"],
|
||||
defaults=student_data
|
||||
)
|
||||
guardian, created = Guardian.objects.get_or_create(
|
||||
last_name=guardian_data["email"],
|
||||
defaults=guardian_data
|
||||
)
|
||||
student.guardians.add(guardian)
|
||||
# Créer les données de l'étudiant
|
||||
student_data = {
|
||||
"last_name": f'lastname_{user.id}',
|
||||
"first_name": f'firstname_{user.id}',
|
||||
}
|
||||
|
||||
# Récupérer les frais et les réductions
|
||||
fees = Fee.objects.filter(id__in=[1, 2, 3, 4])
|
||||
discounts = Discount.objects.filter(id__in=[1])
|
||||
# Créer ou mettre à jour l'étudiant et le guardian
|
||||
student, created = Student.objects.get_or_create(
|
||||
last_name=student_data["last_name"],
|
||||
first_name=student_data["first_name"],
|
||||
defaults=student_data
|
||||
)
|
||||
guardian, created = Guardian.objects.get_or_create(
|
||||
last_name=guardian_data["email"],
|
||||
defaults=guardian_data
|
||||
)
|
||||
student.guardians.add(guardian)
|
||||
|
||||
# Créer les données du formulaire d'inscription
|
||||
register_form_data = {
|
||||
"student": student,
|
||||
"fileGroup": self.registration_file_group,
|
||||
"establishment": Establishment.objects.get(id=1),
|
||||
"status": 1
|
||||
}
|
||||
# Récupérer les frais et les réductions
|
||||
fees = Fee.objects.filter(id__in=[1, 2, 3, 4])
|
||||
discounts = Discount.objects.filter(id__in=[1])
|
||||
|
||||
# Créer ou mettre à jour le formulaire d'inscription
|
||||
register_form, created = RegistrationForm.objects.get_or_create(student=student, defaults=register_form_data)
|
||||
register_form.fees.set(fees)
|
||||
register_form.discounts.set(discounts)
|
||||
if not created:
|
||||
register_form.fileGroup = self.registration_file_group
|
||||
register_form.save()
|
||||
# Créer les données du formulaire d'inscription
|
||||
register_form_data = {
|
||||
"student": student,
|
||||
"fileGroup": self.registration_file_group_1,
|
||||
"establishment": Establishment.objects.get(id=1),
|
||||
"status": 1
|
||||
}
|
||||
|
||||
# Créer ou mettre à jour le formulaire d'inscription
|
||||
register_form, created = RegistrationForm.objects.get_or_create(student=student, defaults=register_form_data)
|
||||
register_form.fees.set(fees)
|
||||
register_form.discounts.set(discounts)
|
||||
if not created:
|
||||
register_form.fileGroup = self.registration_file_group_1
|
||||
register_form.save()
|
||||
|
||||
self.stdout.write(self.style.SUCCESS('RegistrationForm initialized or updated successfully'))
|
||||
@ -89,7 +89,7 @@ class Student(models.Model):
|
||||
siblings = models.ManyToManyField(Sibling, blank=True)
|
||||
|
||||
# Many-to-Many Relationship
|
||||
registration_files = models.ManyToManyField('RegistrationFile', blank=True, related_name='students')
|
||||
registration_files = models.ManyToManyField('RegistrationTemplate', blank=True, related_name='students')
|
||||
|
||||
# Many-to-Many Relationship
|
||||
spoken_languages = models.ManyToManyField(Language, blank=True)
|
||||
@ -162,7 +162,7 @@ class Student(models.Model):
|
||||
return None
|
||||
|
||||
class RegistrationFileGroup(models.Model):
|
||||
name = models.CharField(max_length=255)
|
||||
name = models.CharField(max_length=255, default="")
|
||||
description = models.TextField(blank=True, null=True)
|
||||
|
||||
def __str__(self):
|
||||
@ -172,10 +172,35 @@ 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}'
|
||||
|
||||
class RegistrationTemplateMaster(models.Model):
|
||||
groups = models.ManyToManyField(RegistrationFileGroup, related_name='template_masters')
|
||||
template_id = models.IntegerField(primary_key=True)
|
||||
name = models.CharField(max_length=255, default="")
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.group.name} - {self.template_id}'
|
||||
|
||||
class RegistrationTemplate(models.Model):
|
||||
master = models.ForeignKey(RegistrationTemplateMaster, on_delete=models.CASCADE, related_name='templates')
|
||||
template_id = models.IntegerField(primary_key=True)
|
||||
name = models.CharField(max_length=255, default="")
|
||||
registration_form = models.ForeignKey('RegistrationForm', on_delete=models.CASCADE, related_name='templates')
|
||||
|
||||
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 d’inscription donné.
|
||||
"""
|
||||
registration_files = RegistrationTemplate.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
|
||||
|
||||
class RegistrationForm(models.Model):
|
||||
"""
|
||||
Gère le dossier d’inscription lié à un élève donné.
|
||||
"""
|
||||
class RegistrationFormStatus(models.IntegerChoices):
|
||||
RF_ABSENT = 0, _('Pas de dossier d\'inscription')
|
||||
RF_CREATED = 1, _('Dossier d\'inscription créé')
|
||||
@ -205,7 +230,7 @@ class RegistrationForm(models.Model):
|
||||
discounts = models.ManyToManyField(Discount, blank=True, related_name='register_forms')
|
||||
fileGroup = models.ForeignKey(RegistrationFileGroup,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='file_group',
|
||||
related_name='register_forms',
|
||||
null=True,
|
||||
blank=True)
|
||||
|
||||
@ -213,56 +238,3 @@ class RegistrationForm(models.Model):
|
||||
|
||||
def __str__(self):
|
||||
return "RF_" + self.student.last_name + "_" + self.student.first_name
|
||||
|
||||
class RegistrationFileTemplate(models.Model):
|
||||
"""
|
||||
Modèle pour stocker les fichiers "templates" d’inscription.
|
||||
"""
|
||||
name = models.CharField(max_length=255)
|
||||
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)
|
||||
group = models.ForeignKey(RegistrationFileGroup, on_delete=models.CASCADE, related_name='file_templates', null=True, blank=True)
|
||||
|
||||
@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 d’inscription 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 d’inscription 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
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
from rest_framework import serializers
|
||||
from .models import RegistrationFileTemplate, RegistrationFile, RegistrationFileGroup, RegistrationForm, Student, Guardian, Sibling, Language
|
||||
from .models import RegistrationFileGroup, RegistrationForm, Student, Guardian, Sibling, Language, RegistrationTemplateMaster, RegistrationTemplate
|
||||
from School.models import SchoolClass, Fee, Discount, FeeType
|
||||
from School.serializers import FeeSerializer, DiscountSerializer
|
||||
from Auth.models import Profile
|
||||
@ -11,20 +11,38 @@ from django.utils import timezone
|
||||
import pytz
|
||||
from datetime import datetime
|
||||
|
||||
class RegistrationTemplateMasterSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = RegistrationTemplateMaster
|
||||
fields = '__all__'
|
||||
|
||||
class RegistrationTemplateSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = RegistrationTemplate
|
||||
fields = '__all__'
|
||||
|
||||
class GuardianSimpleSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Guardian
|
||||
fields = ['id', 'email']
|
||||
|
||||
class RegistrationFormSimpleSerializer(serializers.ModelSerializer):
|
||||
guardians = GuardianSimpleSerializer(many=True, source='student.guardians')
|
||||
|
||||
class Meta:
|
||||
model = RegistrationForm
|
||||
fields = ['student_id', 'guardians']
|
||||
|
||||
class RegistrationFileGroupSerializer(serializers.ModelSerializer):
|
||||
registration_forms = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = RegistrationFileGroup
|
||||
fields = '__all__'
|
||||
|
||||
class RegistrationFileSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = RegistrationFile
|
||||
fields = '__all__'
|
||||
|
||||
class RegistrationFileTemplateSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = RegistrationFileTemplate
|
||||
fields = '__all__'
|
||||
def get_registration_forms(self, obj):
|
||||
forms = RegistrationForm.objects.filter(fileGroup=obj)
|
||||
return RegistrationFormSimpleSerializer(forms, many=True).data
|
||||
|
||||
class LanguageSerializer(serializers.ModelSerializer):
|
||||
id = serializers.IntegerField(required=False)
|
||||
@ -132,7 +150,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)
|
||||
registration_files = RegistrationTemplateSerializer(many=True, required=False)
|
||||
fees = serializers.PrimaryKeyRelatedField(queryset=Fee.objects.all(), many=True, required=False)
|
||||
discounts = serializers.PrimaryKeyRelatedField(queryset=Discount.objects.all(), many=True, required=False)
|
||||
totalRegistrationFees = serializers.SerializerMethodField()
|
||||
|
||||
@ -7,8 +7,9 @@ from .views import RegisterFormView, RegisterFormWithIdView, send, resend, archi
|
||||
# SubClasses
|
||||
from .views import StudentView, GuardianView, ChildrenListView, StudentListView
|
||||
# Files
|
||||
from .views import RegistrationFileTemplateView, RegistrationFileTemplateSimpleView, RegistrationFileView, RegistrationFileSimpleView
|
||||
from .views import RegistrationTemplateMasterView, RegistrationTemplateMasterSimpleView, RegistrationTemplateView, RegistrationTemplateSimpleView
|
||||
from .views import RegistrationFileGroupView, RegistrationFileGroupSimpleView, get_registration_files_by_group
|
||||
from .views import registration_file_views
|
||||
|
||||
urlpatterns = [
|
||||
re_path(r'^registerForms/(?P<id>[0-9]+)/archive$', archive, name="archive"),
|
||||
@ -27,15 +28,13 @@ urlpatterns = [
|
||||
# Page de formulaire d'inscription - RESPONSABLE
|
||||
re_path(r'^lastGuardianId$', GuardianView.as_view(), name="lastGuardianId"),
|
||||
|
||||
# modèles de fichiers d'inscription
|
||||
re_path(r'^registrationFileTemplates/(?P<id>[0-9]+)$', RegistrationFileTemplateSimpleView.as_view(), name="registrationFileTemplate"),
|
||||
re_path(r'^registrationFileTemplates$', RegistrationFileTemplateView.as_view(), name='registrationFileTemplates'),
|
||||
|
||||
# fichiers d'inscription
|
||||
re_path(r'^registrationFiles/(?P<id>[0-9]+)$', RegistrationFileSimpleView.as_view(), name='registrationFiles'),
|
||||
re_path(r'^registrationFiles$', RegistrationFileView.as_view(), name="registrationFiles"),
|
||||
|
||||
re_path(r'^registrationFileGroups/(?P<id>[0-9]+)$', RegistrationFileGroupSimpleView.as_view(), name='registrationFileGroupDetail'),
|
||||
re_path(r'^registrationFileGroups/(?P<id>[0-9]+)/registrationFiles$', get_registration_files_by_group, name="get_registration_files_by_group"),
|
||||
re_path(r'^registrationFileGroups$', RegistrationFileGroupView.as_view(), name='registrationFileGroups'),
|
||||
|
||||
re_path(r'^registrationTemplateMasters/(?P<id>[0-9]+)$', RegistrationTemplateMasterSimpleView.as_view(), name='registrationTemplateMasters'),
|
||||
re_path(r'^registrationTemplateMasters$', RegistrationTemplateMasterView.as_view(), name='registrationTemplateMasters'),
|
||||
|
||||
re_path(r'^registrationTemplates/(?P<id>[0-9]+)$', RegistrationTemplateSimpleView.as_view(), name='registrationTemplates'),
|
||||
re_path(r'^registrationTemplates$', RegistrationTemplateView.as_view(), name="registrationTemplates"),
|
||||
]
|
||||
@ -1,5 +1,5 @@
|
||||
from .register_form_views import RegisterFormView, RegisterFormWithIdView, send, resend, archive
|
||||
from .registration_file_views import RegistrationFileTemplateView, RegistrationFileTemplateSimpleView, RegistrationFileView, RegistrationFileSimpleView
|
||||
from .registration_file_views import RegistrationTemplateMasterView, RegistrationTemplateMasterSimpleView, RegistrationTemplateView, RegistrationTemplateSimpleView
|
||||
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
|
||||
@ -10,10 +10,10 @@ __all__ = [
|
||||
'send',
|
||||
'resend',
|
||||
'archive',
|
||||
'RegistrationFileView',
|
||||
'RegistrationFileSimpleView',
|
||||
'RegistrationFileTemplateView',
|
||||
'RegistrationFileTemplateSimpleView',
|
||||
'RegistrationTemplateView',
|
||||
'RegistrationTemplateSimpleView',
|
||||
'RegistrationTemplateMasterView',
|
||||
'RegistrationTemplateMasterSimpleView',
|
||||
'RegistrationFileGroupView',
|
||||
'RegistrationFileGroupSimpleView',
|
||||
'get_registration_files_by_group',
|
||||
|
||||
@ -19,7 +19,7 @@ import Subscriptions.util as util
|
||||
from Subscriptions.serializers import RegistrationFormSerializer
|
||||
from Subscriptions.pagination import CustomPagination
|
||||
from Subscriptions.signals import clear_cache
|
||||
from Subscriptions.models import Student, Guardian, RegistrationForm, RegistrationFile, RegistrationFileGroup
|
||||
from Subscriptions.models import Student, Guardian, RegistrationForm, RegistrationTemplate, RegistrationFileGroup
|
||||
from Subscriptions.automate import updateStateMachine
|
||||
|
||||
from N3wtSchool import settings, bdd
|
||||
@ -252,7 +252,7 @@ class RegisterFormWithIdView(APIView):
|
||||
registerForm.save()
|
||||
|
||||
# Récupération des fichiers d'inscription
|
||||
fileNames = RegistrationFile.get_files_from_rf(registerForm.pk)
|
||||
fileNames = RegistrationTemplate.get_files_from_rf(registerForm.pk)
|
||||
if registerForm.registration_file:
|
||||
fileNames.insert(0, registerForm.registration_file.path)
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ from drf_yasg.utils import swagger_auto_schema
|
||||
from drf_yasg import openapi
|
||||
|
||||
from Subscriptions.serializers import RegistrationFileGroupSerializer
|
||||
from Subscriptions.models import RegistrationFileGroup, RegistrationFileTemplate
|
||||
from Subscriptions.models import RegistrationFileGroup, RegistrationTemplateMaster
|
||||
from N3wtSchool import bdd
|
||||
|
||||
class RegistrationFileGroupView(APIView):
|
||||
@ -118,7 +118,7 @@ class RegistrationFileGroupSimpleView(APIView):
|
||||
def get_registration_files_by_group(request, id):
|
||||
try:
|
||||
group = RegistrationFileGroup.objects.get(id=id)
|
||||
templates = RegistrationFileTemplate.objects.filter(group=group)
|
||||
templates = RegistrationTemplateMaster.objects.filter(group=group)
|
||||
templates_data = list(templates.values())
|
||||
return JsonResponse(templates_data, safe=False)
|
||||
except RegistrationFileGroup.DoesNotExist:
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
from django.http.response import JsonResponse
|
||||
from django.core.files import File
|
||||
from drf_yasg.utils import swagger_auto_schema
|
||||
from drf_yasg import openapi
|
||||
from rest_framework.parsers import MultiPartParser, FormParser
|
||||
@ -7,205 +6,154 @@ from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework import status
|
||||
|
||||
import os
|
||||
|
||||
from Subscriptions.serializers import RegistrationFileTemplateSerializer, RegistrationFileSerializer
|
||||
from Subscriptions.models import RegistrationFileTemplate, RegistrationFile
|
||||
from Subscriptions.serializers import RegistrationTemplateMasterSerializer, RegistrationTemplateSerializer
|
||||
from Subscriptions.models import RegistrationTemplateMaster, RegistrationTemplate
|
||||
from N3wtSchool import bdd
|
||||
|
||||
|
||||
class RegistrationFileTemplateView(APIView):
|
||||
class RegistrationTemplateMasterView(APIView):
|
||||
@swagger_auto_schema(
|
||||
operation_description="Récupère tous les fichiers templates pour les dossiers d'inscription",
|
||||
responses={200: RegistrationFileTemplateSerializer(many=True)}
|
||||
operation_description="Récupère tous les masters de templates d'inscription",
|
||||
responses={200: RegistrationTemplateMasterSerializer(many=True)}
|
||||
)
|
||||
def get(self, request):
|
||||
"""
|
||||
Récupère les fichiers templates pour les dossiers d’inscription.
|
||||
"""
|
||||
files = RegistrationFileTemplate.objects.all()
|
||||
serializer = RegistrationFileTemplateSerializer(files, many=True)
|
||||
masters = RegistrationTemplateMaster.objects.all()
|
||||
serializer = RegistrationTemplateMasterSerializer(masters, many=True)
|
||||
return Response(serializer.data)
|
||||
|
||||
@swagger_auto_schema(
|
||||
operation_description="Crée un nouveau fichier template pour les dossiers d'inscription",
|
||||
request_body=RegistrationFileTemplateSerializer,
|
||||
operation_description="Crée un nouveau master de template d'inscription",
|
||||
request_body=RegistrationTemplateMasterSerializer,
|
||||
responses={
|
||||
201: RegistrationFileTemplateSerializer,
|
||||
201: RegistrationTemplateMasterSerializer,
|
||||
400: "Données invalides"
|
||||
}
|
||||
)
|
||||
def post(self, request):
|
||||
"""
|
||||
Crée un fichier template pour les dossiers d’inscription.
|
||||
"""
|
||||
serializer = RegistrationFileTemplateSerializer(data=request.data)
|
||||
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 RegistrationFileTemplateSimpleView(APIView):
|
||||
"""
|
||||
Gère les fichiers templates pour les dossiers d’inscription.
|
||||
"""
|
||||
parser_classes = (MultiPartParser, FormParser)
|
||||
|
||||
class RegistrationTemplateMasterSimpleView(APIView):
|
||||
@swagger_auto_schema(
|
||||
operation_description="Récupère un fichier template spécifique",
|
||||
operation_description="Récupère un master de template d'inscription spécifique",
|
||||
responses={
|
||||
200: RegistrationFileTemplateSerializer,
|
||||
404: "Fichier template non trouvé"
|
||||
200: RegistrationTemplateMasterSerializer,
|
||||
404: "Master non trouvé"
|
||||
}
|
||||
)
|
||||
def get(self, request, id):
|
||||
"""
|
||||
Récupère les fichiers templates pour les dossiers d’inscription.
|
||||
"""
|
||||
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)
|
||||
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 fichier template existant",
|
||||
request_body=RegistrationFileTemplateSerializer,
|
||||
operation_description="Met à jour un master de template d'inscription existant",
|
||||
request_body=RegistrationTemplateMasterSerializer,
|
||||
responses={
|
||||
201: RegistrationFileTemplateSerializer,
|
||||
200: RegistrationTemplateMasterSerializer,
|
||||
400: "Données invalides",
|
||||
404: "Fichier template non trouvé"
|
||||
404: "Master non trouvé"
|
||||
}
|
||||
)
|
||||
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)
|
||||
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_201_CREATED)
|
||||
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 fichier template",
|
||||
operation_description="Supprime un master de template d'inscription",
|
||||
responses={
|
||||
204: "Suppression réussie",
|
||||
404: "Fichier template non trouvé"
|
||||
404: "Master non trouvé"
|
||||
}
|
||||
)
|
||||
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, status=status.HTTP_204_NO_CONTENT)
|
||||
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 fichier d\'inscription n\'a pas été trouvé'}, safe=False, status=status.HTTP_404_NOT_FOUND)
|
||||
return JsonResponse({'erreur': 'Le master de template n\'a pas été trouvé'}, safe=False, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
class RegistrationFileView(APIView):
|
||||
class RegistrationTemplateView(APIView):
|
||||
@swagger_auto_schema(
|
||||
operation_description="Récupère tous les fichiers d'inscription",
|
||||
responses={200: RegistrationFileSerializer(many=True)}
|
||||
operation_description="Récupère tous les templates d'inscription",
|
||||
responses={200: RegistrationTemplateSerializer(many=True)}
|
||||
)
|
||||
def get(self, request):
|
||||
"""
|
||||
Récupère les fichiers liés à un dossier d’inscription donné.
|
||||
"""
|
||||
files = RegistrationFile.objects.all()
|
||||
serializer = RegistrationFileSerializer(files, many=True)
|
||||
templates = RegistrationTemplate.objects.all()
|
||||
serializer = RegistrationTemplateSerializer(templates, many=True)
|
||||
return Response(serializer.data)
|
||||
|
||||
@swagger_auto_schema(
|
||||
operation_description="Crée un nouveau fichier d'inscription",
|
||||
request_body=RegistrationFileSerializer,
|
||||
operation_description="Crée un nouveau template d'inscription",
|
||||
request_body=RegistrationTemplateSerializer,
|
||||
responses={
|
||||
201: RegistrationFileSerializer,
|
||||
201: RegistrationTemplateSerializer,
|
||||
400: "Données invalides"
|
||||
}
|
||||
)
|
||||
def post(self, request):
|
||||
"""
|
||||
Crée un RegistrationFile pour le RegistrationForm associé.
|
||||
"""
|
||||
serializer = RegistrationFileSerializer(data=request.data)
|
||||
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 RegistrationFileSimpleView(APIView):
|
||||
"""
|
||||
Gère la création, mise à jour et suppression de fichiers liés à un dossier d’inscription.
|
||||
"""
|
||||
parser_classes = (MultiPartParser, FormParser)
|
||||
|
||||
class RegistrationTemplateSimpleView(APIView):
|
||||
@swagger_auto_schema(
|
||||
operation_description="Récupère un fichier d'inscription spécifique",
|
||||
operation_description="Récupère un template d'inscription spécifique",
|
||||
responses={
|
||||
200: RegistrationFileSerializer,
|
||||
404: "Fichier non trouvé"
|
||||
200: RegistrationTemplateSerializer,
|
||||
404: "Template non trouvé"
|
||||
}
|
||||
)
|
||||
def get(self, request, id):
|
||||
"""
|
||||
Récupère les fichiers liés à un dossier d’inscription donné.
|
||||
"""
|
||||
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)
|
||||
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 fichier d'inscription existant",
|
||||
request_body=RegistrationFileSerializer,
|
||||
operation_description="Met à jour un template d'inscription existant",
|
||||
request_body=RegistrationTemplateSerializer,
|
||||
responses={
|
||||
200: openapi.Response(
|
||||
description="Fichier mis à jour avec succès",
|
||||
schema=RegistrationFileSerializer
|
||||
),
|
||||
200: RegistrationTemplateSerializer,
|
||||
400: "Données invalides",
|
||||
404: "Fichier non trouvé"
|
||||
404: "Template non trouvé"
|
||||
}
|
||||
)
|
||||
def put(self, request, id):
|
||||
"""
|
||||
Met à jour un RegistrationFile existant.
|
||||
"""
|
||||
registrationFile = bdd.getObject(_objectName=RegistrationFile, _columnName='id', _value=id)
|
||||
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)
|
||||
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': 'Fichier mis à jour avec succès', 'data': serializer.data}, status=status.HTTP_200_OK)
|
||||
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 fichier d'inscription",
|
||||
operation_description="Supprime un template d'inscription",
|
||||
responses={
|
||||
200: "Suppression réussie",
|
||||
404: "Fichier non trouvé"
|
||||
204: "Suppression réussie",
|
||||
404: "Template non trouvé"
|
||||
}
|
||||
)
|
||||
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)
|
||||
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 fichier n\'a pas été trouvé'}, safe=False, status=status.HTTP_404_NOT_FOUND)
|
||||
return JsonResponse({'erreur': 'Le template n\'a pas été trouvé'}, safe=False, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
Reference in New Issue
Block a user