diff --git a/backend/app/main.py b/backend/app/main.py index c697991..18c667a 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -57,7 +57,7 @@ def send_answer_notification(answer, question, mechanic, db): "vehiculo_placa": inspection.vehicle_plate, "vehiculo_marca": inspection.vehicle_brand, "vehiculo_modelo": inspection.vehicle_model, - "cliente": inspection.client_name, + "pedido": inspection.order_number, "or_number": inspection.or_number }, "mecanico": { @@ -153,7 +153,7 @@ def send_completed_inspection_to_n8n(inspection, db): "modelo": inspection.vehicle_model, "kilometraje": inspection.vehicle_km }, - "cliente": inspection.client_name, + "pedido": inspection.order_number, "mecanico": { "id": mechanic.id if mechanic else None, "nombre": mechanic.full_name if mechanic else None, @@ -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.64" +BACKEND_VERSION = "1.0.65" app = FastAPI(title="Checklist Inteligente API", version=BACKEND_VERSION) # S3/MinIO configuration @@ -1318,7 +1318,7 @@ def generate_inspection_pdf(inspection_id: int, db: Session) -> str: inspection_data = [ [Paragraph("👤 INFORMACIÓN DEL CLIENTE", info_style)], [Table([ - [Paragraph("Cliente:", small_style), Paragraph(f"{inspection.client_name or 'N/A'}", info_style)], + [Paragraph("Nº Pedido:", small_style), Paragraph(f"{inspection.order_number or 'N/A'}", info_style)], [Paragraph("OR N°:", small_style), Paragraph(f"{inspection.or_number or 'N/A'}", info_style)], [Paragraph("Mecánico:", small_style), Paragraph(f"{mechanic.full_name if mechanic else 'N/A'}", info_style)], [Paragraph("Cód. Operario:", small_style), Paragraph(f"{inspection.mechanic_employee_code or 'N/A'}", info_style)], @@ -2175,7 +2175,7 @@ INFORMACIÓN DEL VEHÍCULO INSPECCIONADO: - Modelo: {inspection.vehicle_model} - Placa: {inspection.vehicle_plate} - Kilometraje: {inspection.vehicle_km} km -- Cliente: {inspection.client_name} +- Nº Pedido: {inspection.order_number} - OR/Orden: {inspection.or_number} """ else: diff --git a/frontend/package.json b/frontend/package.json index 26eb76f..fe10d24 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "checklist-frontend", "private": true, - "version": "1.0.58", + "version": "1.0.59", "type": "module", "scripts": { "dev": "vite", diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 635ad71..1a1327a 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -3615,25 +3615,46 @@ function InspectionModal({ checklist, user, onClose, onComplete }) { const question = questions.find(q => q.id === questionId) let filesArray = Array.from(files) + // Get existing photos + const existingPhotos = answers[questionId]?.photos || [] + + // Combine existing and new photos + const allPhotos = [...existingPhotos, ...filesArray] + // Validar límite de fotos - if (question.max_photos && filesArray.length > question.max_photos) { + if (question.max_photos && allPhotos.length > question.max_photos) { alert(`⚠️ Solo puedes subir hasta ${question.max_photos} foto${question.max_photos > 1 ? 's' : ''} para esta pregunta`) - filesArray = filesArray.slice(0, question.max_photos) + return } - // Update photos immediately + // Update photos immediately (do NOT auto-analyze) setAnswers(prev => ({ ...prev, [questionId]: { ...(prev[questionId] || { value: '', observations: '', photos: [] }), - photos: filesArray + photos: allPhotos } })) - - // If AI mode is assisted or full, analyze the photos - if ((checklist.ai_mode === 'assisted' || checklist.ai_mode === 'full') && filesArray.length > 0) { - await analyzePhotosWithAI(questionId, filesArray) + } + + const handleRemovePhoto = (questionId, photoIndex) => { + setAnswers(prev => ({ + ...prev, + [questionId]: { + ...(prev[questionId] || { value: '', observations: '', photos: [] }), + photos: prev[questionId].photos.filter((_, index) => index !== photoIndex) + } + })) + } + + const handleAnalyzePhotos = async (questionId) => { + const photos = answers[questionId]?.photos || [] + if (photos.length === 0) { + alert('Primero debes subir al menos una foto') + return } + + await analyzePhotosWithAI(questionId, photos) } const analyzePhotosWithAI = async (questionId, files) => { @@ -4197,10 +4218,11 @@ function InspectionModal({ checklist, user, onClose, onComplete }) { )} {(checklist.ai_mode === 'assisted' || checklist.ai_mode === 'full') && ( - 🤖 Análisis IA activado + 🤖 Análisis IA disponible )} + handlePhotoChange(currentQuestion.id, e.target.files)} className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500" disabled={aiAnalyzing} - required + required={!answers[currentQuestion.id]?.photos?.length} /> + {/* Photo Previews */} + {answers[currentQuestion.id]?.photos?.length > 0 && ( +