feat: A la signature d'un document, on récupère l'URL du PDF [#22]

This commit is contained in:
N3WT DE COMPET
2025-03-01 23:55:48 +01:00
parent eb81bbba92
commit 2ac4832985
8 changed files with 97 additions and 16 deletions

View File

@ -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')
]

View File

@ -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)
@ -125,3 +123,34 @@ def remove_template(request, id):
except requests.RequestException as e:
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)

View File

@ -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 dinscription 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)

View File

@ -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) => {
@ -209,3 +210,13 @@ 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)
}

View File

@ -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>

View 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`);
}
}

View File

@ -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: {

View File

@ -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`
@ -90,3 +91,4 @@ 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_DOWNLOAD_URL = `/api/docuseal/downloadTemplate`