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
|
# 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)
|
app = FastAPI(title="Checklist Inteligente API", version=BACKEND_VERSION)
|
||||||
|
|
||||||
# S3/MinIO configuration
|
# S3/MinIO configuration
|
||||||
@@ -1538,6 +1538,41 @@ def generate_inspection_pdf(inspection_id: int, db: Session) -> str:
|
|||||||
models.Question.order
|
models.Question.order
|
||||||
).all()
|
).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
|
current_section = None
|
||||||
for ans in answers:
|
for ans in answers:
|
||||||
question = ans.question
|
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),
|
Paragraph(f"<b>{status_icon} {question.text}</b>", info_style),
|
||||||
])
|
])
|
||||||
|
|
||||||
# Fila 2: Respuesta y estado
|
# Fila 2: Respuesta y estado - Convertir valor técnico a etiqueta legible
|
||||||
answer_text = ans.answer_value or 'Sin respuesta'
|
answer_text = get_readable_answer(ans.answer_value, question.options)
|
||||||
question_data.append([
|
question_data.append([
|
||||||
Table([
|
Table([
|
||||||
[
|
[
|
||||||
|
|||||||
Reference in New Issue
Block a user