mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-01-29 07:53:23 +00:00
feat: A la signature d'un document, on récupère l'URL du PDF [#22]
This commit is contained in:
@ -1,8 +1,9 @@
|
|||||||
from django.urls import path, re_path
|
from django.urls import path, re_path
|
||||||
from .views import generate_jwt_token, clone_template, remove_template
|
from .views import generate_jwt_token, clone_template, remove_template, download_template
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
re_path(r'generateToken$', generate_jwt_token, name='generate_jwt_token'),
|
re_path(r'generateToken$', generate_jwt_token, name='generate_jwt_token'),
|
||||||
re_path(r'cloneTemplate$', clone_template, name='clone_template'),
|
re_path(r'cloneTemplate$', clone_template, name='clone_template'),
|
||||||
re_path(r'removeTemplate/(?P<id>[0-9]+)$', remove_template, name='remove_template'),
|
re_path(r'removeTemplate/(?P<id>[0-9]+)$', remove_template, name='remove_template'),
|
||||||
|
re_path(r'downloadTemplate/(?P<slug>[\w-]+)$', download_template, name='download_template')
|
||||||
]
|
]
|
||||||
|
|||||||
@ -13,8 +13,6 @@ import requests
|
|||||||
def generate_jwt_token(request):
|
def generate_jwt_token(request):
|
||||||
# Vérifier la clé API
|
# Vérifier la clé API
|
||||||
api_key = request.headers.get('X-Auth-Token')
|
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"]:
|
if not api_key or api_key != settings.DOCUSEAL_JWT["API_KEY"]:
|
||||||
return Response({'error': 'Invalid API key'}, status=status.HTTP_401_UNAUTHORIZED)
|
return Response({'error': 'Invalid API key'}, status=status.HTTP_401_UNAUTHORIZED)
|
||||||
|
|
||||||
@ -124,4 +122,35 @@ def remove_template(request, id):
|
|||||||
return Response(data, status=status.HTTP_200_OK)
|
return Response(data, status=status.HTTP_200_OK)
|
||||||
|
|
||||||
except requests.RequestException as e:
|
except requests.RequestException as e:
|
||||||
return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||||
|
|
||||||
|
@csrf_exempt
|
||||||
|
@api_view(['GET'])
|
||||||
|
def download_template(request, slug):
|
||||||
|
# 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)
|
||||||
|
|
||||||
|
# Vérifier les données requises
|
||||||
|
if not slug :
|
||||||
|
return Response({'error': 'slug is required'}, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
# URL de l'API de DocuSeal pour cloner le template
|
||||||
|
download_url = f'https://docuseal.com/submitters/{slug}/download'
|
||||||
|
|
||||||
|
# Faire la requête pour cloner le template
|
||||||
|
try:
|
||||||
|
response = requests.get(download_url, headers={
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-Auth-Token': settings.DOCUSEAL_JWT['API_KEY']
|
||||||
|
})
|
||||||
|
|
||||||
|
if response.status_code != status.HTTP_200_OK:
|
||||||
|
return Response({'error': 'Failed to download 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)
|
||||||
|
|||||||
@ -219,12 +219,16 @@ class RegistrationForm(models.Model):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "RF_" + self.student.last_name + "_" + self.student.first_name
|
return "RF_" + self.student.last_name + "_" + self.student.first_name
|
||||||
|
|
||||||
|
def registration_file_upload_to(instance, filename):
|
||||||
|
return f"registration_files/dossier_rf_{instance.register_form.pk}/{filename}"
|
||||||
|
|
||||||
class RegistrationTemplate(models.Model):
|
class RegistrationTemplate(models.Model):
|
||||||
master = models.ForeignKey(RegistrationTemplateMaster, on_delete=models.CASCADE, related_name='templates')
|
master = models.ForeignKey(RegistrationTemplateMaster, on_delete=models.CASCADE, related_name='templates')
|
||||||
template_id = models.IntegerField(primary_key=True)
|
template_id = models.IntegerField(primary_key=True)
|
||||||
slug = models.CharField(max_length=255, default="")
|
slug = models.CharField(max_length=255, default="")
|
||||||
name = models.CharField(max_length=255, default="")
|
name = models.CharField(max_length=255, default="")
|
||||||
registration_form = models.ForeignKey(RegistrationForm, on_delete=models.CASCADE, related_name='templates')
|
registration_form = models.ForeignKey(RegistrationForm, on_delete=models.CASCADE, related_name='templates')
|
||||||
|
file = models.FileField(null=True,blank=True, upload_to=registration_file_upload_to)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
@ -234,7 +238,7 @@ class RegistrationTemplate(models.Model):
|
|||||||
"""
|
"""
|
||||||
Récupère tous les fichiers liés à un dossier d’inscription donné.
|
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')
|
registration_files = RegistrationTemplate.objects.filter(registration_form=register_form_id)
|
||||||
filenames = []
|
filenames = []
|
||||||
for reg_file in registration_files:
|
for reg_file in registration_files:
|
||||||
filenames.append(reg_file.file.path)
|
filenames.append(reg_file.file.path)
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
import { BE_SUBSCRIPTION_REGISTRATIONFILE_GROUPS_URL,
|
import { BE_SUBSCRIPTION_REGISTRATIONFILE_GROUPS_URL,
|
||||||
BE_SUBSCRIPTION_REGISTRATION_TEMPLATES_URL,
|
BE_SUBSCRIPTION_REGISTRATION_TEMPLATES_URL,
|
||||||
BE_SUBSCRIPTION_REGISTRATION_TEMPLATE_MASTER_URL,
|
BE_SUBSCRIPTION_REGISTRATION_TEMPLATE_MASTER_URL,
|
||||||
FE_API_DOCUSEAL_CLONE_URL
|
FE_API_DOCUSEAL_CLONE_URL,
|
||||||
|
FE_API_DOCUSEAL_DOWNLOAD_URL
|
||||||
} from '@/utils/Url';
|
} from '@/utils/Url';
|
||||||
|
|
||||||
const requestResponseHandler = async (response) => {
|
const requestResponseHandler = async (response) => {
|
||||||
@ -208,4 +209,14 @@ export const cloneTemplate = (templateId, email) => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
.then(requestResponseHandler)
|
.then(requestResponseHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const downloadTemplate = (slug) => {
|
||||||
|
return fetch(`${FE_API_DOCUSEAL_DOWNLOAD_URL}/${slug}`, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(requestResponseHandler)
|
||||||
}
|
}
|
||||||
@ -7,8 +7,8 @@ import Loader from '@/components/Loader';
|
|||||||
import Button from '@/components/Button';
|
import Button from '@/components/Button';
|
||||||
import DjangoCSRFToken from '@/components/DjangoCSRFToken';
|
import DjangoCSRFToken from '@/components/DjangoCSRFToken';
|
||||||
import Table from '@/components/Table';
|
import Table from '@/components/Table';
|
||||||
import { fetchRegistrationTemplateMaster, createRegistrationTemplates, fetchRegisterForm, deleteRegistrationTemplates, fetchTemplatesFromRegistrationFiles } from '@/app/actions/subscriptionAction';
|
import { fetchRegisterForm, fetchTemplatesFromRegistrationFiles } from '@/app/actions/subscriptionAction';
|
||||||
import { fetchRegistrationFileFromGroup } from '@/app/actions/registerFileGroupAction';
|
import { fetchRegistrationFileFromGroup, fetchRegistrationTemplateMaster, downloadTemplate, createRegistrationTemplates, deleteRegistrationTemplates } from '@/app/actions/registerFileGroupAction';
|
||||||
import { Download, Upload, Trash2, Eye } from 'lucide-react';
|
import { Download, Upload, Trash2, Eye } from 'lucide-react';
|
||||||
import { BASE_URL } from '@/utils/Url';
|
import { BASE_URL } from '@/utils/Url';
|
||||||
import DraggableFileUpload from '@/components/DraggableFileUpload';
|
import DraggableFileUpload from '@/components/DraggableFileUpload';
|
||||||
@ -19,6 +19,7 @@ import StudentInfoForm from '@/components/Inscription/StudentInfoForm';
|
|||||||
import FilesToSign from '@/components/Inscription/FilesToSign';
|
import FilesToSign from '@/components/Inscription/FilesToSign';
|
||||||
import FilesToUpload from '@/components/Inscription/FilesToUpload';
|
import FilesToUpload from '@/components/Inscription/FilesToUpload';
|
||||||
import { DocusealForm } from '@docuseal/react';
|
import { DocusealForm } from '@docuseal/react';
|
||||||
|
import { ESTABLISHMENT_ID } from '@/utils/Url';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Composant de formulaire d'inscription partagé
|
* Composant de formulaire d'inscription partagé
|
||||||
@ -170,7 +171,9 @@ export default function InscriptionFormShared({
|
|||||||
student: {
|
student: {
|
||||||
...formData,
|
...formData,
|
||||||
guardians
|
guardians
|
||||||
}
|
},
|
||||||
|
establishment: ESTABLISHMENT_ID,
|
||||||
|
status:3
|
||||||
}
|
}
|
||||||
onSubmit(data);
|
onSubmit(data);
|
||||||
};
|
};
|
||||||
@ -273,10 +276,11 @@ export default function InscriptionFormShared({
|
|||||||
src={"https://docuseal.com/s/"+requiredFileTemplates[currentPage - 2].slug}
|
src={"https://docuseal.com/s/"+requiredFileTemplates[currentPage - 2].slug}
|
||||||
withDownloadButton={false}
|
withDownloadButton={false}
|
||||||
onComplete={() => {
|
onComplete={() => {
|
||||||
const formContainer = document.getElementById('form_container');
|
downloadTemplate(requiredFileTemplates[currentPage - 2].slug)
|
||||||
if (formContainer) {
|
.then((data) => {
|
||||||
formContainer.style.display = 'none';
|
logger.debug("PDF URL : ", data)
|
||||||
}
|
})
|
||||||
|
.catch((error) => console.error(error));
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
</DocusealForm>
|
</DocusealForm>
|
||||||
|
|||||||
32
Front-End/src/pages/api/docuseal/downloadTemplate/[slug].js
Normal file
32
Front-End/src/pages/api/docuseal/downloadTemplate/[slug].js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { BE_DOCUSEAL_DOWNLOAD_TEMPLATE } from '@/utils/Url';
|
||||||
|
|
||||||
|
export default function handler(req, res) {
|
||||||
|
if (req.method === 'GET') {
|
||||||
|
const { slug } = req.query;
|
||||||
|
console.log('slug : ', slug)
|
||||||
|
|
||||||
|
fetch(`${BE_DOCUSEAL_DOWNLOAD_TEMPLATE}/${slug}`, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'X-Auth-Token': process.env.DOCUSEAL_API_KEY
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
return response.json().then(err => { throw new Error(err.message); });
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
console.log('Template downloaded successfully:', data);
|
||||||
|
res.status(200).json(data);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error downloading template:', error);
|
||||||
|
res.status(500).json({ error: 'Internal Server Error' });
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
res.setHeader('Allow', ['GET']);
|
||||||
|
res.status(405).end(`Method ${req.method} Not Allowed`);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,8 +2,6 @@ import { BE_DOCUSEAL_GET_JWT } from '@/utils/Url';
|
|||||||
|
|
||||||
export default function handler(req, res) {
|
export default function handler(req, res) {
|
||||||
if (req.method === 'POST') {
|
if (req.method === 'POST') {
|
||||||
console.log('DOCUSEAL_API_KEY:', process.env.DOCUSEAL_API_KEY);
|
|
||||||
|
|
||||||
fetch(BE_DOCUSEAL_GET_JWT, {
|
fetch(BE_DOCUSEAL_GET_JWT, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
|
|||||||
@ -8,6 +8,7 @@ export const BASE_URL = process.env.NEXT_PUBLIC_API_URL;
|
|||||||
export const BE_DOCUSEAL_GET_JWT = `${BASE_URL}/DocuSeal/generateToken`
|
export const BE_DOCUSEAL_GET_JWT = `${BASE_URL}/DocuSeal/generateToken`
|
||||||
export const BE_DOCUSEAL_CLONE_TEMPLATE = `${BASE_URL}/DocuSeal/cloneTemplate`
|
export const BE_DOCUSEAL_CLONE_TEMPLATE = `${BASE_URL}/DocuSeal/cloneTemplate`
|
||||||
export const BE_DOCUSEAL_REMOVE_TEMPLATE = `${BASE_URL}/DocuSeal/removeTemplate`
|
export const BE_DOCUSEAL_REMOVE_TEMPLATE = `${BASE_URL}/DocuSeal/removeTemplate`
|
||||||
|
export const BE_DOCUSEAL_DOWNLOAD_TEMPLATE = `${BASE_URL}/DocuSeal/downloadTemplate`
|
||||||
|
|
||||||
// GESTION LOGIN
|
// GESTION LOGIN
|
||||||
export const BE_AUTH_NEW_PASSWORD_URL = `${BASE_URL}/Auth/newPassword`
|
export const BE_AUTH_NEW_PASSWORD_URL = `${BASE_URL}/Auth/newPassword`
|
||||||
@ -89,4 +90,5 @@ export const FE_PARENTS_SETTINGS_URL = `/parents/settings`
|
|||||||
export const FE_PARENTS_EDIT_INSCRIPTION_URL = `/parents/editInscription`
|
export const FE_PARENTS_EDIT_INSCRIPTION_URL = `/parents/editInscription`
|
||||||
|
|
||||||
// API DOCUSEAL
|
// API DOCUSEAL
|
||||||
export const FE_API_DOCUSEAL_CLONE_URL = `/api/docuseal/cloneTemplate`
|
export const FE_API_DOCUSEAL_CLONE_URL = `/api/docuseal/cloneTemplate`
|
||||||
|
export const FE_API_DOCUSEAL_DOWNLOAD_URL = `/api/docuseal/downloadTemplate`
|
||||||
Reference in New Issue
Block a user