diff --git a/src/components/conversores/BocadConverter.tsx b/src/components/conversores/BocadConverter.tsx index 5c9a28c..6f8385e 100644 --- a/src/components/conversores/BocadConverter.tsx +++ b/src/components/conversores/BocadConverter.tsx @@ -390,8 +390,13 @@ export const BocadConverter: React.FC = () => { const rawMaterial = firstWhiteRow ? firstWhiteRow.qualid : 'A36'; const normalizedMat = normalizeMaterial(rawMaterial); - // Comprimento de referência (pega da linha principal ou do primeiro componente se a linha principal não tiver) - const compRef = asm.compr || (firstWhiteRow ? firstWhiteRow.compr : ''); + // Comprimento de referência (pega da linha principal, do primeiro componente ou do maior componente) + let maxCompSub = 0; + asm.components.forEach(c => { + const n = Number(c.compr) || 0; + if (n > maxCompSub) maxCompSub = n; + }); + const compRef = asm.compr || (firstWhiteRow ? firstWhiteRow.compr : '') || (maxCompSub > 0 ? maxCompSub : ''); return { of: detectedOF, diff --git a/src/components/pecas/ImportarXLSModal.tsx b/src/components/pecas/ImportarXLSModal.tsx index 51141af..250b4cb 100644 --- a/src/components/pecas/ImportarXLSModal.tsx +++ b/src/components/pecas/ImportarXLSModal.tsx @@ -28,6 +28,7 @@ export interface PecaXLSData { material: string; perfil_principal: string; tem_componentes: boolean; + comprimento?: number | null; comprimento_ref?: number | string; marca_componente?: string; descricao_componente?: string; @@ -112,24 +113,30 @@ export function ImportarXLSModal({ const ws = workbook.Sheets['Importacao_TrackSteel']; const jsonRows: any[] = XLSX.utils.sheet_to_json(ws, { defval: '' }); if (jsonRows && jsonRows.length > 0) { - const lidas: PecaXLSData[] = jsonRows.map((r) => ({ - of_number: String(r.of_number || ofDefault || 'B134').trim().replace(/^B-(\d+)/i, 'B$1'), - etapa_fase: String(r.etapa_fase || '1').trim(), - marca: String(r.marca || '').trim(), - descricao: String(r.descricao || '').trim(), - quantidade: Math.max(1, Math.round(parseNumber(r.quantidade) || 1)), - peso_unitario: parseNumber(r.peso_unitario), - peso_total: parseNumber(r.peso_total), - tratamento_superficial: String(r.tratamento_superficial || 'pintura').trim(), - material: String(r.material || 'Aço A36').trim(), - perfil_principal: String(r.perfil_principal || r.descricao || '').trim(), - tem_componentes: Boolean(r.tem_componentes || (r.marca_componente && String(r.marca_componente).trim() !== '')), - marca_componente: r.marca_componente ? String(r.marca_componente).trim() : undefined, - descricao_componente: r.descricao_componente ? String(r.descricao_componente).trim() : undefined, - perfil_componente: r.perfil_componente ? String(r.perfil_componente).trim() : undefined, - peso_unitario_componente: r.peso_unitario_componente !== undefined ? parseNumber(r.peso_unitario_componente) : undefined, - quantidade_por_peca: r.quantidade_por_peca !== undefined ? parseNumber(r.quantidade_por_peca) : undefined, - })).filter(p => p.marca && !p.marca.toLowerCase().includes('total')); + const lidas: PecaXLSData[] = jsonRows.map((r) => { + const rawComp = r.comprimento || r.comprimento_ref || r['Comprimento'] || r['Comprimento (mm)'] || r['Comprimento Ref. (mm)']; + const compNum = parseNumber(rawComp); + return { + of_number: String(r.of_number || ofDefault || 'B134').trim().replace(/^B-(\d+)/i, 'B$1'), + etapa_fase: String(r.etapa_fase || '1').trim(), + marca: String(r.marca || '').trim(), + descricao: String(r.descricao || '').trim(), + quantidade: Math.max(1, Math.round(parseNumber(r.quantidade) || 1)), + peso_unitario: parseNumber(r.peso_unitario), + peso_total: parseNumber(r.peso_total), + comprimento: compNum > 0 ? compNum : null, + comprimento_ref: compNum > 0 ? compNum : undefined, + tratamento_superficial: String(r.tratamento_superficial || 'pintura').trim(), + material: String(r.material || 'Aço A36').trim(), + perfil_principal: String(r.perfil_principal || r.descricao || '').trim(), + tem_componentes: Boolean(r.tem_componentes || (r.marca_componente && String(r.marca_componente).trim() !== '')), + marca_componente: r.marca_componente ? String(r.marca_componente).trim() : undefined, + descricao_componente: r.descricao_componente ? String(r.descricao_componente).trim() : undefined, + perfil_componente: r.perfil_componente ? String(r.perfil_componente).trim() : undefined, + peso_unitario_componente: r.peso_unitario_componente !== undefined ? parseNumber(r.peso_unitario_componente) : undefined, + quantidade_por_peca: r.quantidade_por_peca !== undefined ? parseNumber(r.quantidade_por_peca) : undefined, + }; + }).filter(p => p.marca && !p.marca.toLowerCase().includes('total')); if (lidas.length > 0) { setPecasProcessadas(lidas); @@ -167,10 +174,15 @@ export function ImportarXLSModal({ const key = `${ofVal}-${faseVal}-${marcaPeca}`; const comps = compMap.get(key) || []; - const temComp = comps.length > 0 || String(p['Composto por Componentes?'] || '').toLowerCase() === 'sim'; + const temComp = comps.length > 0 || String(p['Composto por Componentes?'] || p['Composto por Componentes'] || '').toLowerCase() === 'sim'; + + const rawPecaComp = p['Comprimento Ref. (mm)'] || p['Comprimento (mm)'] || p['Comprimento'] || p['comprimento'] || p['comprimento_ref']; + const compPeca = parseNumber(rawPecaComp); if (comps.length > 0) { comps.forEach((c) => { + const compSub = parseNumber(c['Comprimento (mm)'] || c['Comprimento'] || c['comprimento']); + const finalComp = compPeca > 0 ? compPeca : (compSub > 0 ? compSub : null); merged.push({ of_number: ofVal, etapa_fase: faseVal, @@ -179,6 +191,8 @@ export function ImportarXLSModal({ quantidade: Math.max(1, Math.round(parseNumber(p['Quantidade']) || 1)), peso_unitario: parseNumber(p['Peso Unitário (kg)']), peso_total: parseNumber(p['Peso Total (kg)']), + comprimento: finalComp, + comprimento_ref: finalComp || undefined, tratamento_superficial: String(p['Tratamento Superficial'] || 'pintura').trim(), material: String(p['Material'] || 'Aço A36').trim(), perfil_principal: String(p['Perfil Principal'] || p['Descrição'] || '').trim(), @@ -199,6 +213,8 @@ export function ImportarXLSModal({ quantidade: Math.max(1, Math.round(parseNumber(p['Quantidade']) || 1)), peso_unitario: parseNumber(p['Peso Unitário (kg)']), peso_total: parseNumber(p['Peso Total (kg)']), + comprimento: compPeca > 0 ? compPeca : null, + comprimento_ref: compPeca > 0 ? compPeca : undefined, tratamento_superficial: String(p['Tratamento Superficial'] || 'pintura').trim(), material: String(p['Material'] || 'Aço A36').trim(), perfil_principal: String(p['Perfil Principal'] || p['Descrição'] || '').trim(), @@ -272,7 +288,7 @@ export function ImportarXLSModal({ else if ((h.includes('tratam') || h.includes('superf') || h.includes('pintura') || h.includes('acab')) && colMap['tratamento'] === undefined) colMap['tratamento'] = colIdx; else if ((h.includes('mat') || h.includes('qualidade') || h.includes('aco')) && colMap['material'] === undefined) colMap['material'] = colIdx; else if ((h.includes('perfil') || h.includes('perfilprinc')) && colMap['perfil_principal'] === undefined) colMap['perfil_principal'] = colIdx; - else if ((h.includes('compriment') || h.includes('comprmm') || h.includes('length')) && colMap['comprimento'] === undefined) colMap['comprimento'] = colIdx; + else if ((h.includes('compriment') || h.includes('comprmm') || h.includes('length') || h === 'compr' || h === 'comp') && colMap['comprimento'] === undefined) colMap['comprimento'] = colIdx; }); // Itera sobre as linhas de dados após o cabeçalho @@ -333,7 +349,8 @@ export function ImportarXLSModal({ const rawComp = String(getColVal('componentes', 4)).toLowerCase(); const temComponentes = rawComp === 'sim' || rawComp === 'true' || rawComp === '1'; - const comprimentoRef = getColVal('comprimento', 10); + const comprimentoRaw = getColVal('comprimento', 11); + const comprimentoVal = parseNumber(comprimentoRaw); pecasLidas.push({ of_number: ofNumber, @@ -343,16 +360,17 @@ export function ImportarXLSModal({ quantidade, peso_unitario: pesoUnit, peso_total: pesoTot, + comprimento: comprimentoVal > 0 ? comprimentoVal : null, + comprimento_ref: comprimentoVal > 0 ? comprimentoVal : undefined, tratamento_superficial: tratSuperficial, material, perfil_principal: rawPerfil || rawDesc, tem_componentes: temComponentes, - comprimento_ref: comprimentoRef || undefined, }); } } else { // Fallback por ordem posicional estrita: - // Coluna 0: OF, 1: Fase, 2: Marca, 3: Descrição, 4: Quantidade, 5: Peso Unit, 6: Peso Total, 7: Tratamento, 8: Material, 9: Perfil Principal + // Coluna 0: OF, 1: Fase, 2: Marca, 3: Descrição, 4: Quantidade, 5: Peso Unit, 6: Peso Total, 7: Tratamento, 8: Material, 9: Perfil Principal, 10/11: Comprimento for (let r = 0; r < rawRows.length; r++) { const row = rawRows[r]; if (!row || row.length < 3) continue; @@ -369,6 +387,7 @@ export function ImportarXLSModal({ const tratSuperficial = String(row[7] || 'pintura').trim() || 'pintura'; const material = String(row[8] || 'Aço A36').trim(); const perfilPrincipal = String(row[9] || rawDesc).trim(); + const rawComprFallback = parseNumber(row[11] || row[10]); pecasLidas.push({ of_number: ofNumber, @@ -378,6 +397,8 @@ export function ImportarXLSModal({ quantidade, peso_unitario: pesoUnit, peso_total: pesoTot, + comprimento: rawComprFallback > 0 ? rawComprFallback : null, + comprimento_ref: rawComprFallback > 0 ? rawComprFallback : undefined, tratamento_superficial: tratSuperficial, material, perfil_principal: perfilPrincipal, @@ -444,6 +465,8 @@ export function ImportarXLSModal({ quantidade: p.quantidade, peso_unitario: p.peso_unitario, peso_total: p.peso_total, + comprimento: p.comprimento !== undefined && p.comprimento !== null ? Number(p.comprimento) : (p.comprimento_ref ? Number(p.comprimento_ref) : null), + comprimento_ref: p.comprimento_ref ? Number(p.comprimento_ref) : (p.comprimento ? Number(p.comprimento) : null), tratamento_superficial: p.tratamento_superficial || 'pintura', material: p.material, perfil_principal: p.perfil_principal, @@ -670,6 +693,7 @@ export function ImportarXLSModal({ Qtd Peso Un. (kg) Peso Total (kg) + Compr. (mm) Tratamento Material Perfil Princ. @@ -688,6 +712,9 @@ export function ImportarXLSModal({ {peca.peso_total.toLocaleString('pt-BR')} + + {peca.comprimento || peca.comprimento_ref ? `${peca.comprimento || peca.comprimento_ref} mm` : '-'} + {peca.tratamento_superficial} {peca.material} {peca.perfil_principal}