diff --git a/src/components/viewer3d/ModelViewer3D.tsx b/src/components/viewer3d/ModelViewer3D.tsx index 92c145f..39d20bc 100644 --- a/src/components/viewer3d/ModelViewer3D.tsx +++ b/src/components/viewer3d/ModelViewer3D.tsx @@ -348,22 +348,7 @@ export const ModelViewer3D: React.FC = ({ // Se o elemento não estiver visível na fase atual, pula estilização detalhada if (!isVisibleByPhase) return; - // 4. Mapeamento de Processos Industriais para Inovação Híbrida (Corte -> Solda -> Pintura -> Expedição -> Montagem) - const PROCESS_ORDER_MAP: Record = { - 'corte': 1, - 'solda': 2, - 'pintura': 3, - 'pintura/galv': 3, - 'pintura/galvanizacao': 3, - 'pintura / galvanizacao': 3, - 'galvanizacao': 3, - 'expedicao': 4, - 'expedição': 4, - 'montagem': 5, - 'montagem obra': 5, - 'montagem de obra': 5, - }; - + // 4. Mapeamento de Processos Industriais (Corte, Solda, Pintura, Expedição, Montagem) const PROCESS_COLOR_MAP: Record = { 'corte': '#3b82f6', 'solda': '#f97316', @@ -374,31 +359,39 @@ export const ModelViewer3D: React.FC = ({ 'galvanizacao': '#10b981', 'expedicao': '#06b6d4', 'expedição': '#06b6d4', - 'montagem': '#6366f1', - 'montagem obra': '#6366f1', - 'montagem de obra': '#6366f1', + 'montagem': '#8b5cf6', + 'montagem obra': '#8b5cf6', + 'montagem de obra': '#8b5cf6', }; - const targetProcKey = String(selectedProcess || 'all').toLowerCase(); - const targetOrder = PROCESS_ORDER_MAP[targetProcKey] || 0; + const normalizeStr = (s: string) => s.normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase(); + const targetProcKey = normalizeStr(String(selectedProcess || 'all')); const targetColorHex = PROCESS_COLOR_MAP[targetProcKey] || '#22c55e'; let isPointedInTargetProcess = false; - if (selectedProcess !== 'all' && prod && prod.pointedQtd > 0) { - const pieceProcOrder = Number(prod.processOrdem || 0); - const pieceProcName = String(prod.currentProcessName || '').toLowerCase(); + if (selectedProcess !== 'all' && prod) { const procsDone: string[] = Array.isArray(prod.processesCompleted) ? prod.processesCompleted : []; + const procPointedMap: Record = prod.processPointedQtds || {}; - const normalizeStr = (s: string) => s.normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase(); - const normTarget = normalizeStr(targetProcKey); - - const hasDirectProcess = - procsDone.some((p: string) => normalizeStr(p).includes(normTarget)) || - normalizeStr(pieceProcName).includes(normTarget); - - isPointedInTargetProcess = - hasDirectProcess || - (targetOrder > 0 && pieceProcOrder >= targetOrder); + // Checagem estrita de apontamento real no processo selecionado + if (targetProcKey === 'corte') { + isPointedInTargetProcess = (procPointedMap['corte'] && procPointedMap['corte'] > 0) || procsDone.includes('corte'); + } else if (targetProcKey === 'solda') { + isPointedInTargetProcess = (procPointedMap['solda'] && procPointedMap['solda'] > 0) || procsDone.includes('solda'); + } else if (targetProcKey === 'pintura') { + isPointedInTargetProcess = + (procPointedMap['pintura'] && procPointedMap['pintura'] > 0) || + (procPointedMap['pintura/galv'] && procPointedMap['pintura/galv'] > 0) || + (procPointedMap['pintura / galvanizacao'] && procPointedMap['pintura / galvanizacao'] > 0) || + (procPointedMap['galvanizacao'] && procPointedMap['galvanizacao'] > 0) || + procsDone.some(p => p.includes('pint') || p.includes('galv')); + } else if (targetProcKey === 'expedicao') { + isPointedInTargetProcess = (procPointedMap['expedicao'] && procPointedMap['expedicao'] > 0) || procsDone.some(p => p.includes('exped')); + } else if (targetProcKey === 'montagem') { + isPointedInTargetProcess = (procPointedMap['montagem'] && procPointedMap['montagem'] > 0) || procsDone.some(p => p.includes('montag')); + } else { + isPointedInTargetProcess = Boolean(procPointedMap[targetProcKey] && procPointedMap[targetProcKey] > 0) || procsDone.includes(targetProcKey); + } } // 5. Aplicação de Cores / Materiais (Sólido vs Aramado Híbrido) @@ -464,24 +457,28 @@ export const ModelViewer3D: React.FC = ({ if (prod && prod.pointedQtd > 0) { pointedCount++; - // Determina a cor do processo mais avançado da peça - const procName = String(prod.currentProcessName || '').toLowerCase(); + // Determina a cor do processo mais avançado da peça (sem considerar Detalhamento) + const procPointedMap: Record = prod.processPointedQtds || {}; const procsDone: string[] = Array.isArray(prod.processesCompleted) ? prod.processesCompleted : []; - const procOrder = Number(prod.processOrdem || 0); - let pieceColorHex = '#3b82f6'; // Padrão Corte + let pieceColorHex = '#a1a1aa'; // Padrão se não tiver processo fabril - if (procName.includes('montag') || procsDone.some(p => p.includes('montag')) || procOrder >= 5) { + if (procPointedMap['montagem'] > 0 || procsDone.some(p => p.includes('montag'))) { pieceColorHex = '#8b5cf6'; // Roxo Montagem - } else if (procName.includes('exped') || procsDone.some(p => p.includes('exped')) || procOrder === 4) { + } else if (procPointedMap['expedicao'] > 0 || procsDone.some(p => p.includes('exped'))) { pieceColorHex = '#06b6d4'; // Ciano Expedição - } else if (procName.includes('pint') || procName.includes('galv') || procsDone.some(p => p.includes('pint') || p.includes('galv')) || procOrder === 3) { + } else if ( + procPointedMap['pintura'] > 0 || + procPointedMap['pintura/galv'] > 0 || + procPointedMap['galvanizacao'] > 0 || + procsDone.some(p => p.includes('pint') || p.includes('galv')) + ) { pieceColorHex = '#10b981'; // Verde Pintura - } else if (procName.includes('sold') || procsDone.some(p => p.includes('sold')) || procOrder === 2) { + } else if (procPointedMap['solda'] > 0 || procsDone.some(p => p.includes('sold'))) { pieceColorHex = '#f97316'; // Laranja Solda - } else if (procName.includes('corte') || procsDone.some(p => p.includes('corte')) || procOrder === 1) { + } else if (procPointedMap['corte'] > 0 || procsDone.some(p => p.includes('corte'))) { pieceColorHex = '#3b82f6'; // Azul Corte - } else if (prod.processColor) { + } else if (prod.processColor && !String(prod.currentProcessName || '').toLowerCase().includes('detalh')) { pieceColorHex = prod.processColor; } diff --git a/src/pages/Visualizador3D.tsx b/src/pages/Visualizador3D.tsx index 4356d7f..7b528f8 100644 --- a/src/pages/Visualizador3D.tsx +++ b/src/pages/Visualizador3D.tsx @@ -149,6 +149,7 @@ export default function Visualizador3D() { processColor: '#64748b', processOrdem: 0, processesCompleted: [] as string[], + processPointedQtds: {} as Record, }; uniqueItems.push(item); @@ -188,15 +189,24 @@ export default function Visualizador3D() { if (existing) { const qty = Number(ap.quantidade_produzida || 0); + const procRaw = String(ap.processo?.nome || '').trim(); + const procNorm = procRaw.normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase(); + + // Detalhamento é um processo de engenharia prévio, não fabril + const isDetalhamento = procNorm.includes('detalh'); + if (qty > 0) { - existing.pointedQtd = Math.max(existing.pointedQtd, qty); - const procNome = String(ap.processo?.nome || '').trim(); - if (procNome && !existing.processesCompleted.includes(procNome.toLowerCase())) { - existing.processesCompleted.push(procNome.toLowerCase()); + existing.processPointedQtds[procNorm] = (existing.processPointedQtds[procNorm] || 0) + qty; + + if (!isDetalhamento) { + existing.pointedQtd = Math.max(existing.pointedQtd, qty); + if (!existing.processesCompleted.includes(procNorm)) { + existing.processesCompleted.push(procNorm); + } + existing.currentProcessName = procRaw || existing.currentProcessName; + existing.processColor = ap.processo?.cor || PROCESS_COLORS[procRaw] || '#10b981'; + existing.processOrdem = Math.max(existing.processOrdem, Number(ap.processo?.ordem || 0)); } - existing.currentProcessName = procNome || existing.currentProcessName; - existing.processColor = ap.processo?.cor || PROCESS_COLORS[procNome] || '#10b981'; - existing.processOrdem = Math.max(existing.processOrdem, Number(ap.processo?.ordem || 0)); } } }