diff --git a/backend/app/main.py b/backend/app/main.py index ff8595d..13a34a3 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.79" +BACKEND_VERSION = "1.0.81" app = FastAPI(title="Checklist Inteligente API", version=BACKEND_VERSION) # S3/MinIO configuration @@ -1699,10 +1699,12 @@ def generate_inspection_pdf(inspection_id: int, db: Session) -> str: if ans.comment: comment_text = ans.comment - # Limpiar prefijo de IA si existe (con cualquier porcentaje) + # Limpiar prefijo de análisis automático/IA si existe (con cualquier porcentaje) import re - # Patrón para detectar "Análisis IA (XX% confianza): " con cualquier porcentaje - comment_text = re.sub(r'^Análisis IA \(\d+%\s+confianza\):\s*', '', comment_text) + # Patrón para detectar "Análisis Automático (XX% confianza): " o "Análisis IA (XX% confianza): " + comment_text = re.sub(r'^(Análisis Automático|Análisis IA)\s*\(\d+%\s*confianza\):\s*', '', comment_text) + # También remover variantes sin emoji + comment_text = re.sub(r'^🤖\s*(Análisis Automático|Análisis IA)\s*\(\d+%\s*confianza\):\s*', '', comment_text) # Separar análisis y recomendaciones con salto de línea if "Recomendaciones:" in comment_text or "Recomendación:" in comment_text: @@ -1754,6 +1756,44 @@ def generate_inspection_pdf(inspection_id: int, db: Session) -> str: elements.append(KeepTogether(q_table)) elements.append(Spacer(1, 3*mm)) + # ===== FIRMA ===== + if inspection.signature_data: + elements.append(PageBreak()) + elements.append(Spacer(1, 10*mm)) + elements.append(Paragraph("✍️ FIRMA DEL OPERARIO", section_header_style)) + elements.append(Spacer(1, 5*mm)) + + try: + # Decodificar firma base64 + import base64 + signature_bytes = base64.b64decode(inspection.signature_data.split(',')[1] if ',' in inspection.signature_data else inspection.signature_data) + signature_img_buffer = BytesIO(signature_bytes) + signature_img = RLImage(signature_img_buffer, width=80*mm, height=40*mm) + + # Tabla con la firma y datos + signature_data = [ + [signature_img], + [Paragraph(f"Operario: {inspection.mechanic_employee_code or 'N/A'}", info_style)], + [Paragraph(f"Fecha de finalización: {inspection.completed_at.strftime('%d/%m/%Y %H:%M') if inspection.completed_at else 'N/A'}", info_style)] + ] + + signature_table = Table(signature_data, colWidths=[180*mm]) + signature_table.setStyle(TableStyle([ + ('ALIGN', (0, 0), (-1, -1), 'CENTER'), + ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), + ('LINEABOVE', (0, 0), (0, 0), 1, colors.HexColor('#cbd5e1')), + ('PADDING', (0, 0), (-1, -1), 8), + ])) + + elements.append(signature_table) + print(f"✅ Firma agregada al PDF") + except Exception as e: + print(f"⚠️ Error agregando firma al PDF: {e}") + elements.append(Paragraph( + f"Error al cargar la firma", + ParagraphStyle('error', parent=small_style, alignment=TA_CENTER, textColor=colors.HexColor('#ef4444')) + )) + # ===== FOOTER ===== elements.append(Spacer(1, 10*mm)) elements.append(Paragraph(