From 416588a327d5c4723e4d8a16c26c5d221aa19332 Mon Sep 17 00:00:00 2001 From: gitea Date: Thu, 27 Nov 2025 17:12:45 -0300 Subject: [PATCH] =?UTF-8?q?Backend=20v1.0.76:=20-=20=F0=9F=8E=A8=20Redise?= =?UTF-8?q?=C3=B1ado=20PDF=20primera=20p=C3=A1gina=20con=20dise=C3=B1o=20m?= =?UTF-8?q?oderno=20y=20profesional=20(cuadros=20con=20encabezados=20separ?= =?UTF-8?q?ados=20y=20coloreados,=20bordes=20redondeados,=20separadores=20?= =?UTF-8?q?internos,=20mejor=20jerarqu=C3=ADa=20visual)=20-=20=F0=9F=94=92?= =?UTF-8?q?=20Eliminado=20nombre=20de=20mec=C3=A1nico=20del=20PDF=20por=20?= =?UTF-8?q?privacidad=20(solo=20c=C3=B3digo=20de=20operario)=20-=20?= =?UTF-8?q?=F0=9F=90=9B=20Corregido=20bug:=20PDF=20mostraba=20valores=20t?= =?UTF-8?q?=C3=A9cnicos=20en=20lugar=20de=20etiquetas=20legibles=20(implem?= =?UTF-8?q?entada=20funci=C3=B3n=20get=5Freadable=5Fanswer()=20que=20convi?= =?UTF-8?q?erte=20"option1"=20=E2=86=92=20"Bueno",=20"pass"=20=E2=86=92=20?= =?UTF-8?q?"Pasa",=20soporta=20boolean,=20single=5Fchoice=20y=20multiple?= =?UTF-8?q?=5Fchoice)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Frontend v1.0.75: - ❌ Sin cambios --- backend/app/main.py | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/backend/app/main.py b/backend/app/main.py index d60b274..5ccf7d1 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -204,7 +204,7 @@ def send_completed_inspection_to_n8n(inspection, db): # No lanzamos excepción para no interrumpir el flujo normal -BACKEND_VERSION = "1.0.75" +BACKEND_VERSION = "1.0.76" app = FastAPI(title="Checklist Inteligente API", version=BACKEND_VERSION) # S3/MinIO configuration @@ -1538,6 +1538,41 @@ def generate_inspection_pdf(inspection_id: int, db: Session) -> str: models.Question.order ).all() + # Función helper para convertir valores técnicos a etiquetas legibles + def get_readable_answer(answer_value, question_options): + """ + Convierte el valor técnico de la respuesta a su etiqueta legible. + Ej: 'option1' -> 'Bueno', 'pass' -> 'Pasa' + """ + if not answer_value or not question_options: + return answer_value or 'Sin respuesta' + + config = question_options + question_type = config.get('type', '') + + # Para tipos con choices (boolean, single_choice, multiple_choice) + if question_type in ['boolean', 'single_choice', 'multiple_choice'] and config.get('choices'): + # Si es multiple_choice, puede tener varios valores separados por coma + if question_type == 'multiple_choice' and ',' in answer_value: + values = answer_value.split(',') + labels = [] + for val in values: + val = val.strip() + choice = next((c for c in config['choices'] if c.get('value') == val), None) + if choice: + labels.append(choice.get('label', val)) + else: + labels.append(val) + return ', '.join(labels) + else: + # Buscar la etiqueta correspondiente al valor + choice = next((c for c in config['choices'] if c.get('value') == answer_value), None) + if choice: + return choice.get('label', answer_value) + + # Para tipos scale, text, number, date, time - devolver el valor tal cual + return answer_value + current_section = None for ans in answers: question = ans.question @@ -1572,8 +1607,8 @@ def generate_inspection_pdf(inspection_id: int, db: Session) -> str: Paragraph(f"{status_icon} {question.text}", info_style), ]) - # Fila 2: Respuesta y estado - answer_text = ans.answer_value or 'Sin respuesta' + # Fila 2: Respuesta y estado - Convertir valor técnico a etiqueta legible + answer_text = get_readable_answer(ans.answer_value, question.options) question_data.append([ Table([ [