Backend v1.0.76:
- 🎨 Rediseñado PDF primera página con diseño moderno y profesional (cuadros con encabezados separados y coloreados, bordes redondeados, separadores internos, mejor jerarquía visual) - 🔒 Eliminado nombre de mecánico del PDF por privacidad (solo código de operario) - 🐛 Corregido bug: PDF mostraba valores técnicos en lugar de etiquetas legibles (implementada función get_readable_answer() que convierte "option1" → "Bueno", "pass" → "Pasa", soporta boolean, single_choice y multiple_choice) Frontend v1.0.75: - ❌ Sin cambios
This commit is contained in:
@@ -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"<b>{status_icon} {question.text}</b>", 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([
|
||||
[
|
||||
|
||||
Reference in New Issue
Block a user