Cambios Adicionales
✅ Importado or_ de SQLAlchemy para query del reporte ✅ Backend: 1.0.86 → 1.0.87 🎯 Resultado ✅ Inspecciones solo muestran preguntas activas del checklist ✅ PDFs correctos sin preguntas eliminadas ✅ Cálculo de score preciso (solo preguntas vigentes) ✅ Webhooks envían solo datos relevantes ✅ Reportes con métricas correctas ✅ Respuestas huérfanas de preguntas eliminadas se ignoran automáticamente
This commit is contained in:
@@ -5,7 +5,7 @@ from fastapi import FastAPI, File, UploadFile, Form, Depends, HTTPException, sta
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
||||
from sqlalchemy.orm import Session, joinedload
|
||||
from sqlalchemy import func, case
|
||||
from sqlalchemy import func, case, or_
|
||||
from typing import List, Optional
|
||||
from io import BytesIO
|
||||
import os
|
||||
@@ -100,11 +100,14 @@ def send_completed_inspection_to_n8n(inspection, db):
|
||||
# Obtener checklist
|
||||
checklist = db.query(models.Checklist).filter(models.Checklist.id == inspection.checklist_id).first()
|
||||
|
||||
# Obtener todas las respuestas con sus imágenes
|
||||
# Obtener todas las respuestas con sus imágenes - SOLO de preguntas NO eliminadas
|
||||
answers = db.query(models.Answer).options(
|
||||
joinedload(models.Answer.media_files),
|
||||
joinedload(models.Answer.question)
|
||||
).filter(models.Answer.inspection_id == inspection.id).all()
|
||||
).join(models.Question).filter(
|
||||
models.Answer.inspection_id == inspection.id,
|
||||
models.Question.is_deleted == False # Excluir preguntas eliminadas
|
||||
).all()
|
||||
|
||||
# Preparar respuestas con imágenes
|
||||
respuestas_data = []
|
||||
@@ -204,7 +207,7 @@ def send_completed_inspection_to_n8n(inspection, db):
|
||||
# No lanzamos excepción para no interrumpir el flujo normal
|
||||
|
||||
|
||||
BACKEND_VERSION = "1.0.86"
|
||||
BACKEND_VERSION = "1.0.87"
|
||||
app = FastAPI(title="Checklist Inteligente API", version=BACKEND_VERSION)
|
||||
|
||||
# S3/MinIO configuration
|
||||
@@ -1226,7 +1229,7 @@ def get_inspection(
|
||||
current_user: models.User = Depends(get_current_user)
|
||||
):
|
||||
inspection = db.query(models.Inspection).options(
|
||||
joinedload(models.Inspection.checklist).joinedload(models.Checklist.questions),
|
||||
joinedload(models.Inspection.checklist),
|
||||
joinedload(models.Inspection.mechanic),
|
||||
joinedload(models.Inspection.answers).joinedload(models.Answer.question),
|
||||
joinedload(models.Inspection.answers).joinedload(models.Answer.media_files)
|
||||
@@ -1235,6 +1238,13 @@ def get_inspection(
|
||||
if not inspection:
|
||||
raise HTTPException(status_code=404, detail="Inspección no encontrada")
|
||||
|
||||
# Cargar solo preguntas NO eliminadas del checklist
|
||||
if inspection.checklist:
|
||||
inspection.checklist.questions = db.query(models.Question).filter(
|
||||
models.Question.checklist_id == inspection.checklist.id,
|
||||
models.Question.is_deleted == False
|
||||
).order_by(models.Question.order).all()
|
||||
|
||||
return inspection
|
||||
|
||||
|
||||
@@ -1672,12 +1682,13 @@ def generate_inspection_pdf(inspection_id: int, db: Session) -> str:
|
||||
elements.append(Paragraph("📝 DETALLE DE LA INSPECCIÓN", section_header_style))
|
||||
elements.append(Spacer(1, 5*mm))
|
||||
|
||||
# Obtener respuestas agrupadas por sección
|
||||
# Obtener respuestas agrupadas por sección - SOLO de preguntas NO eliminadas
|
||||
answers = db.query(models.Answer).options(
|
||||
joinedload(models.Answer.media_files),
|
||||
joinedload(models.Answer.question)
|
||||
).join(models.Question).filter(
|
||||
models.Answer.inspection_id == inspection_id
|
||||
models.Answer.inspection_id == inspection_id,
|
||||
models.Question.is_deleted == False # Excluir preguntas eliminadas
|
||||
).order_by(
|
||||
models.Question.section,
|
||||
models.Question.order
|
||||
@@ -1905,8 +1916,11 @@ def complete_inspection(
|
||||
if not inspection:
|
||||
raise HTTPException(status_code=404, detail="Inspección no encontrada")
|
||||
|
||||
# Calcular score
|
||||
answers = db.query(models.Answer).filter(models.Answer.inspection_id == inspection_id).all()
|
||||
# Calcular score - SOLO de preguntas NO eliminadas
|
||||
answers = db.query(models.Answer).join(models.Question).filter(
|
||||
models.Answer.inspection_id == inspection_id,
|
||||
models.Question.is_deleted == False # Excluir preguntas eliminadas
|
||||
).all()
|
||||
total_score = sum(a.points_earned for a in answers)
|
||||
flagged_count = sum(1 for a in answers if a.is_flagged)
|
||||
|
||||
@@ -2078,9 +2092,10 @@ def update_answer(
|
||||
if inspection.status == "completed":
|
||||
print(f"🔄 Regenerando PDF para inspección completada #{inspection.id}")
|
||||
|
||||
# Recalcular score de la inspección
|
||||
answers = db.query(models.Answer).filter(
|
||||
models.Answer.inspection_id == inspection.id
|
||||
# Recalcular score de la inspección - SOLO de preguntas NO eliminadas
|
||||
answers = db.query(models.Answer).join(models.Question).filter(
|
||||
models.Answer.inspection_id == inspection.id,
|
||||
models.Question.is_deleted == False # Excluir preguntas eliminadas
|
||||
).all()
|
||||
|
||||
inspection.score = sum(a.points_earned for a in answers)
|
||||
@@ -2243,9 +2258,10 @@ def admin_edit_answer(
|
||||
if inspection and inspection.status == "completed":
|
||||
print(f"🔄 Regenerando PDF para inspección completada #{inspection.id} (admin-edit)")
|
||||
|
||||
# Recalcular score de la inspección
|
||||
answers = db.query(models.Answer).filter(
|
||||
models.Answer.inspection_id == inspection.id
|
||||
# Recalcular score de la inspección - SOLO de preguntas NO eliminadas
|
||||
answers = db.query(models.Answer).join(models.Question).filter(
|
||||
models.Answer.inspection_id == inspection.id,
|
||||
models.Question.is_deleted == False # Excluir preguntas eliminadas
|
||||
).all()
|
||||
|
||||
inspection.score = sum(a.points_earned for a in answers)
|
||||
@@ -3298,7 +3314,11 @@ def get_inspections_report(
|
||||
.join(models.Checklist, models.Inspection.checklist_id == models.Checklist.id)\
|
||||
.join(models.User, models.Inspection.mechanic_id == models.User.id)\
|
||||
.outerjoin(models.Answer, models.Answer.inspection_id == models.Inspection.id)\
|
||||
.filter(models.Inspection.is_active == True)
|
||||
.outerjoin(models.Question, models.Answer.question_id == models.Question.id)\
|
||||
.filter(
|
||||
models.Inspection.is_active == True,
|
||||
or_(models.Question.is_deleted == False, models.Question.id == None) # Solo contar answers de preguntas no eliminadas o si no hay answer
|
||||
)
|
||||
|
||||
# Aplicar filtros
|
||||
if start_date:
|
||||
|
||||
Reference in New Issue
Block a user