Refactorizacion de PDFs y cambio de biblioteca backend 1.0.18
This commit is contained in:
@@ -34,7 +34,18 @@ from app import models, schemas
|
||||
# Crear tablas
|
||||
Base.metadata.create_all(bind=engine)
|
||||
|
||||
app = FastAPI(title="Checklist Inteligente API", version="1.0.0")
|
||||
BACKEND_VERSION = "1.0.17"
|
||||
app = FastAPI(title="Checklist Inteligente API", version=BACKEND_VERSION)
|
||||
|
||||
# Información visual al iniciar el backend
|
||||
import sys
|
||||
from app.core import config as app_config
|
||||
print("\n================ BACKEND STARTUP INFO ================")
|
||||
print(f"Backend version: {BACKEND_VERSION}")
|
||||
print(f"Database URL: {app_config.settings.DATABASE_URL}")
|
||||
print(f"Environment: {app_config.settings.ENVIRONMENT}")
|
||||
print(f"MinIO endpoint: {app_config.MINIO_ENDPOINT}")
|
||||
print("====================================================\n", flush=True)
|
||||
|
||||
# CORS
|
||||
app.add_middleware(
|
||||
@@ -1694,12 +1705,74 @@ def export_inspection_to_pdf(
|
||||
doc = SimpleDocTemplate(buffer, pagesize=A4, rightMargin=30, leftMargin=30, topMargin=30, bottomMargin=30)
|
||||
elements = []
|
||||
styles = getSampleStyleSheet()
|
||||
# ...existing code for PDF generation...
|
||||
doc.build(elements)
|
||||
title_style = styles['Title']
|
||||
normal_style = styles['Normal']
|
||||
header_style = ParagraphStyle('Header', parent=styles['Heading2'], alignment=TA_CENTER, spaceAfter=12)
|
||||
# Portada
|
||||
elements.append(Paragraph(f"Informe de Inspección #{inspection.id}", title_style))
|
||||
elements.append(Spacer(1, 12))
|
||||
elements.append(Paragraph(f"Vehículo: {inspection.vehicle_brand or ''} {inspection.vehicle_model or ''} - Placa: {inspection.vehicle_plate}", normal_style))
|
||||
elements.append(Paragraph(f"Cliente: {inspection.client_name or ''}", normal_style))
|
||||
elements.append(Paragraph(f"Mecánico: {mechanic.full_name if mechanic else ''}", normal_style))
|
||||
elements.append(Paragraph(f"Checklist: {checklist.name if checklist else ''}", normal_style))
|
||||
elements.append(Paragraph(f"Fecha: {inspection.started_at.strftime('%d/%m/%Y %H:%M') if inspection.started_at else ''}", normal_style))
|
||||
elements.append(Spacer(1, 18))
|
||||
# Tabla de respuestas
|
||||
table_data = [["Sección", "Pregunta", "Respuesta", "Estado", "Comentario", "Miniaturas"]]
|
||||
for ans in answers:
|
||||
question = ans.question
|
||||
media_imgs = []
|
||||
for media in ans.media_files:
|
||||
if media.file_type == "image":
|
||||
try:
|
||||
# Descargar imagen y agregar miniatura
|
||||
import requests
|
||||
img_resp = requests.get(media.file_path)
|
||||
if img_resp.status_code == 200:
|
||||
img_bytes = BytesIO(img_resp.content)
|
||||
rl_img = RLImage(img_bytes, width=0.7*inch, height=0.7*inch)
|
||||
media_imgs.append(rl_img)
|
||||
except Exception as e:
|
||||
print(f"Error cargando imagen {media.file_path}: {e}")
|
||||
row = [
|
||||
question.section or "",
|
||||
question.text,
|
||||
ans.answer_value,
|
||||
ans.status,
|
||||
ans.comment or "",
|
||||
media_imgs if media_imgs else ""
|
||||
]
|
||||
table_data.append(row)
|
||||
# Construir tabla con miniaturas
|
||||
table = Table(table_data, colWidths=[1.2*inch, 2.5*inch, 1*inch, 0.8*inch, 2*inch, 1.5*inch])
|
||||
table.setStyle(TableStyle([
|
||||
('BACKGROUND', (0,0), (-1,0), colors.lightgrey),
|
||||
('TEXTCOLOR', (0,0), (-1,0), colors.black),
|
||||
('ALIGN', (0,0), (-1,-1), 'LEFT'),
|
||||
('VALIGN', (0,0), (-1,-1), 'TOP'),
|
||||
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
|
||||
('FONTSIZE', (0,0), (-1,0), 10),
|
||||
('BOTTOMPADDING', (0,0), (-1,0), 8),
|
||||
('GRID', (0,0), (-1,-1), 0.5, colors.grey),
|
||||
]))
|
||||
elements.append(table)
|
||||
elements.append(Spacer(1, 18))
|
||||
# Pie de página
|
||||
elements.append(Paragraph(f"Generado por Checklist Inteligente - {datetime.now().strftime('%d/%m/%Y %H:%M')}", header_style))
|
||||
# Construir PDF
|
||||
try:
|
||||
doc.build(elements)
|
||||
except Exception as e:
|
||||
print(f"Error al generar PDF: {e}")
|
||||
buffer.seek(0)
|
||||
pdf_size = len(buffer.getvalue())
|
||||
print(f"PDF generado, tamaño: {pdf_size} bytes")
|
||||
# Guardar localmente para depuración
|
||||
with open(f"/tmp/test_inspeccion_{inspection_id}.pdf", "wb") as f:
|
||||
f.write(buffer.getvalue())
|
||||
try:
|
||||
with open(f"/tmp/test_inspeccion_{inspection_id}.pdf", "wb") as f:
|
||||
f.write(buffer.getvalue())
|
||||
except Exception as e:
|
||||
print(f"No se pudo guardar PDF local: {e}")
|
||||
now = datetime.now()
|
||||
folder = f"{now.year}/{now.month:02d}"
|
||||
filename = f"inspeccion_{inspection_id}_{inspection.vehicle_plate or 'sin-patente'}.pdf"
|
||||
|
||||
@@ -16,3 +16,4 @@ Pillow==10.2.0
|
||||
reportlab==4.0.9
|
||||
python-dotenv==1.0.0
|
||||
boto3==1.34.89
|
||||
requests==2.31.0
|
||||
Reference in New Issue
Block a user