feat: Finalisation formulaire dynamique

This commit is contained in:
N3WT DE COMPET
2026-04-04 20:08:25 +02:00
parent ae06b6fef7
commit 90b0d14418
29 changed files with 1071 additions and 306 deletions

View File

@ -16,6 +16,20 @@ import Subscriptions.util as util
logger = logging.getLogger(__name__)
def _extract_nested_responses(data, max_depth=8):
"""Extrait le dictionnaire de reponses depuis des structures imbriquees."""
current = data
for _ in range(max_depth):
if not isinstance(current, dict):
return None
nested = current.get("responses")
if isinstance(nested, dict):
current = nested
continue
return current
return current if isinstance(current, dict) else None
class RegistrationSchoolFileTemplateView(APIView):
@swagger_auto_schema(
operation_description="Récupère tous les templates d'inscription pour un établissement donné",
@ -95,15 +109,26 @@ class RegistrationSchoolFileTemplateSimpleView(APIView):
responses = None
if "responses" in formTemplateData:
resp = formTemplateData["responses"]
if isinstance(resp, dict) and "responses" in resp:
responses = resp["responses"]
elif isinstance(resp, dict):
responses = resp
responses = _extract_nested_responses(resp)
# Nettoyer les meta-cles qui ne sont pas des reponses de champs
if isinstance(responses, dict):
cleaned = {
key: value
for key, value in responses.items()
if key not in {"responses", "formId", "id", "templateId"}
}
responses = cleaned
if responses and "fields" in formTemplateData:
for field in formTemplateData["fields"]:
field_id = field.get("id")
if field_id and field_id in responses:
field["value"] = responses[field_id]
# Stocker les reponses aplaties pour eviter l'empilement responses.responses
if isinstance(responses, dict):
formTemplateData["responses"] = responses
payload['formTemplateData'] = formTemplateData
template = bdd.getObject(_objectName=RegistrationSchoolFileTemplate, _columnName='id', _value=id)
@ -137,7 +162,7 @@ class RegistrationSchoolFileTemplateSimpleView(APIView):
return Response({'message': 'Template mis à jour avec succès', 'data': RegistrationSchoolFileTemplateSerializer(template).data}, status=status.HTTP_200_OK)
# Cas 2 : Formulaire dynamique (JSON)
serializer = RegistrationSchoolFileTemplateSerializer(template, data=payload)
serializer = RegistrationSchoolFileTemplateSerializer(template, data=payload, partial=True)
if serializer.is_valid():
serializer.save()
# Régénérer le PDF si besoin
@ -148,19 +173,50 @@ class RegistrationSchoolFileTemplateSimpleView(APIView):
and formTemplateData.get("fields")
and hasattr(template, "file")
):
old_pdf_name = None
if template.file and template.file.name:
old_pdf_name = os.path.basename(template.file.name)
# Lire le contenu du fichier source en mémoire AVANT suppression.
# Priorité au fichier master (document source admin) pour éviter
# de re-générer à partir d'un PDF template déjà enrichi.
base_pdf_content = None
base_file_ext = None
if template.master and template.master.file and template.master.file.name:
base_file_ext = os.path.splitext(template.master.file.name)[1].lower()
try:
template.master.file.open('rb')
base_pdf_content = template.master.file.read()
template.master.file.close()
except Exception as e:
logger.error(f"Erreur lecture fichier source master: {e}")
elif template.file and template.file.name:
base_file_ext = os.path.splitext(template.file.name)[1].lower()
try:
template.file.open('rb')
base_pdf_content = template.file.read()
template.file.close()
except Exception as e:
logger.error(f"Erreur lecture fichier source template: {e}")
try:
old_path = template.file.path
template.file.delete(save=False)
if os.path.exists(template.file.path):
os.remove(template.file.path)
if os.path.exists(old_path):
os.remove(old_path)
except Exception as e:
logger.error(f"Erreur lors de la suppression du fichier existant: {e}")
from Subscriptions.util import generate_form_json_pdf
pdf_file = generate_form_json_pdf(template.registration_form, formTemplateData)
pdf_filename = old_pdf_name or f"{template.name}_{template.id}.pdf"
template.file.save(pdf_filename, pdf_file, save=True)
pdf_file = generate_form_json_pdf(
template.registration_form,
formTemplateData,
base_pdf_content=base_pdf_content,
base_file_ext=base_file_ext,
)
form_name = (formTemplateData.get("title") or template.name or f"formulaire_{template.id}").strip().replace(" ", "_")
pdf_filename = f"{form_name}.pdf"
util.save_file_field_without_suffix(
template,
'file',
pdf_filename,
pdf_file,
save=True,
)
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)