mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-01-28 23:43:22 +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 .views import generate_jwt_token, clone_template, remove_template
|
||||
from .views import generate_jwt_token, clone_template, remove_template, download_template
|
||||
|
||||
urlpatterns = [
|
||||
re_path(r'generateToken$', generate_jwt_token, name='generate_jwt_token'),
|
||||
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'downloadTemplate/(?P<slug>[\w-]+)$', download_template, name='download_template')
|
||||
]
|
||||
|
||||
@ -13,8 +13,6 @@ import requests
|
||||
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)
|
||||
|
||||
@ -124,4 +122,35 @@ def remove_template(request, id):
|
||||
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)
|
||||
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):
|
||||
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):
|
||||
master = models.ForeignKey(RegistrationTemplateMaster, on_delete=models.CASCADE, related_name='templates')
|
||||
template_id = models.IntegerField(primary_key=True)
|
||||
slug = 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')
|
||||
file = models.FileField(null=True,blank=True, upload_to=registration_file_upload_to)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
@ -234,7 +238,7 @@ class RegistrationTemplate(models.Model):
|
||||
"""
|
||||
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 = []
|
||||
for reg_file in registration_files:
|
||||
filenames.append(reg_file.file.path)
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import { BE_SUBSCRIPTION_REGISTRATIONFILE_GROUPS_URL,
|
||||
BE_SUBSCRIPTION_REGISTRATION_TEMPLATES_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';
|
||||
|
||||
const requestResponseHandler = async (response) => {
|
||||
@ -208,4 +209,14 @@ export const cloneTemplate = (templateId, email) => {
|
||||
})
|
||||
})
|
||||
.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 DjangoCSRFToken from '@/components/DjangoCSRFToken';
|
||||
import Table from '@/components/Table';
|
||||
import { fetchRegistrationTemplateMaster, createRegistrationTemplates, fetchRegisterForm, deleteRegistrationTemplates, fetchTemplatesFromRegistrationFiles } from '@/app/actions/subscriptionAction';
|
||||
import { fetchRegistrationFileFromGroup } from '@/app/actions/registerFileGroupAction';
|
||||
import { fetchRegisterForm, fetchTemplatesFromRegistrationFiles } from '@/app/actions/subscriptionAction';
|
||||
import { fetchRegistrationFileFromGroup, fetchRegistrationTemplateMaster, downloadTemplate, createRegistrationTemplates, deleteRegistrationTemplates } from '@/app/actions/registerFileGroupAction';
|
||||
import { Download, Upload, Trash2, Eye } from 'lucide-react';
|
||||
import { BASE_URL } from '@/utils/Url';
|
||||
import DraggableFileUpload from '@/components/DraggableFileUpload';
|
||||
@ -19,6 +19,7 @@ import StudentInfoForm from '@/components/Inscription/StudentInfoForm';
|
||||
import FilesToSign from '@/components/Inscription/FilesToSign';
|
||||
import FilesToUpload from '@/components/Inscription/FilesToUpload';
|
||||
import { DocusealForm } from '@docuseal/react';
|
||||
import { ESTABLISHMENT_ID } from '@/utils/Url';
|
||||
|
||||
/**
|
||||
* Composant de formulaire d'inscription partagé
|
||||
@ -170,7 +171,9 @@ export default function InscriptionFormShared({
|
||||
student: {
|
||||
...formData,
|
||||
guardians
|
||||
}
|
||||
},
|
||||
establishment: ESTABLISHMENT_ID,
|
||||
status:3
|
||||
}
|
||||
onSubmit(data);
|
||||
};
|
||||
@ -273,10 +276,11 @@ export default function InscriptionFormShared({
|
||||
src={"https://docuseal.com/s/"+requiredFileTemplates[currentPage - 2].slug}
|
||||
withDownloadButton={false}
|
||||
onComplete={() => {
|
||||
const formContainer = document.getElementById('form_container');
|
||||
if (formContainer) {
|
||||
formContainer.style.display = 'none';
|
||||
}
|
||||
downloadTemplate(requiredFileTemplates[currentPage - 2].slug)
|
||||
.then((data) => {
|
||||
logger.debug("PDF URL : ", data)
|
||||
})
|
||||
.catch((error) => console.error(error));
|
||||
}}
|
||||
>
|
||||
</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) {
|
||||
if (req.method === 'POST') {
|
||||
console.log('DOCUSEAL_API_KEY:', process.env.DOCUSEAL_API_KEY);
|
||||
|
||||
fetch(BE_DOCUSEAL_GET_JWT, {
|
||||
method: 'POST',
|
||||
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_CLONE_TEMPLATE = `${BASE_URL}/DocuSeal/cloneTemplate`
|
||||
export const BE_DOCUSEAL_REMOVE_TEMPLATE = `${BASE_URL}/DocuSeal/removeTemplate`
|
||||
export const BE_DOCUSEAL_DOWNLOAD_TEMPLATE = `${BASE_URL}/DocuSeal/downloadTemplate`
|
||||
|
||||
// GESTION LOGIN
|
||||
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`
|
||||
|
||||
// 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