fix: persistencia e extracao de comprimento de pecas e subcomponentes na importacao
This commit is contained in:
@@ -27,6 +27,90 @@ const CAMPOS_MONITORADOS: CampoConfig[] = [
|
||||
{ key: 'tem_componentes', label: 'Tem Componentes', isCritico: true },
|
||||
];
|
||||
|
||||
/**
|
||||
* Função utilitária resiliente para extrair o comprimento numérico de uma peça principal.
|
||||
* Suporta múltiplos aliases de importação (Bocad, Advance Steel, Excel, CSV) e formatações de string.
|
||||
*/
|
||||
export function extrairComprimentoSeguro(item: any): number | null {
|
||||
if (!item) return null;
|
||||
|
||||
const raw =
|
||||
item.comprimento ??
|
||||
item.comprimento_ref ??
|
||||
item.comprimentoRef ??
|
||||
item.comprimentoMax ??
|
||||
item.comprimento_max ??
|
||||
item.comprimento_peca ??
|
||||
item['Comprimento'] ??
|
||||
item['Comprimento (mm)'] ??
|
||||
item['Comprimento Ref. (mm)'] ??
|
||||
item['Comprimento Max. (mm)'] ??
|
||||
item['Comp. (mm)'] ??
|
||||
item['Comp (mm)'] ??
|
||||
item.compr ??
|
||||
item.comp;
|
||||
|
||||
if (raw === undefined || raw === null || raw === '' || raw === '-') return null;
|
||||
|
||||
if (typeof raw === 'number') {
|
||||
return isNaN(raw) || raw <= 0 ? null : Math.round(raw);
|
||||
}
|
||||
|
||||
// String cleanup: trata formatos como "3.241", "3,241", "6000 mm", "5850.5"
|
||||
let str = String(raw).trim().replace(/mm/gi, '').trim();
|
||||
if (str.includes('.') && str.includes(',')) {
|
||||
if (str.indexOf('.') < str.indexOf(',')) {
|
||||
str = str.replace(/\./g, '').replace(',', '.');
|
||||
} else {
|
||||
str = str.replace(/,/g, '');
|
||||
}
|
||||
} else if (str.includes(',')) {
|
||||
str = str.replace(',', '.');
|
||||
}
|
||||
|
||||
const num = parseFloat(str);
|
||||
return isNaN(num) || num <= 0 ? null : Math.round(num);
|
||||
}
|
||||
|
||||
/**
|
||||
* Função utilitária resiliente para extrair o comprimento numérico de subcomponentes.
|
||||
*/
|
||||
export function extrairComprimentoComponenteSeguro(item: any): number | null {
|
||||
if (!item) return null;
|
||||
|
||||
const raw =
|
||||
item.comprimento_componente ??
|
||||
item.comprimentoComponente ??
|
||||
item.comprimento ??
|
||||
item.comprimento_ref ??
|
||||
item.compr ??
|
||||
item.comp ??
|
||||
item['Comprimento Componente'] ??
|
||||
item['Comprimento (mm)'] ??
|
||||
item['Comprimento'] ??
|
||||
item['Comp. (mm)'];
|
||||
|
||||
if (raw === undefined || raw === null || raw === '' || raw === '-') return null;
|
||||
|
||||
if (typeof raw === 'number') {
|
||||
return isNaN(raw) || raw <= 0 ? null : Math.round(raw);
|
||||
}
|
||||
|
||||
let str = String(raw).trim().replace(/mm/gi, '').trim();
|
||||
if (str.includes('.') && str.includes(',')) {
|
||||
if (str.indexOf('.') < str.indexOf(',')) {
|
||||
str = str.replace(/\./g, '').replace(',', '.');
|
||||
} else {
|
||||
str = str.replace(/,/g, '');
|
||||
}
|
||||
} else if (str.includes(',')) {
|
||||
str = str.replace(',', '.');
|
||||
}
|
||||
|
||||
const num = parseFloat(str);
|
||||
return isNaN(num) || num <= 0 ? null : Math.round(num);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normaliza e agrupa linhas de peças e subcomponentes
|
||||
*/
|
||||
@@ -45,6 +129,7 @@ export function consolidarPecasEComponentes(rawItems: any[]): {
|
||||
if (!marca) return;
|
||||
|
||||
const pecaKey = `${ofNumber}-${etapaFase}-${marca}`;
|
||||
const comprimentoFinal = extrairComprimentoSeguro(item);
|
||||
|
||||
const pecaData = {
|
||||
of_number: ofNumber,
|
||||
@@ -54,12 +139,7 @@ export function consolidarPecasEComponentes(rawItems: any[]): {
|
||||
quantidade: Number(item.quantidade) || 0,
|
||||
peso_unitario: Number(item.peso_unitario) || 0,
|
||||
peso_total: Number(item.peso_total) || 0,
|
||||
comprimento:
|
||||
item.comprimento !== undefined && item.comprimento !== null
|
||||
? Number(item.comprimento)
|
||||
: item.comprimento_ref
|
||||
? Number(item.comprimento_ref)
|
||||
: null,
|
||||
comprimento: comprimentoFinal,
|
||||
tratamento_superficial: item.tratamento_superficial || 'pintura',
|
||||
material: item.material || 'Aço A36',
|
||||
perfil_principal: item.perfil_principal || item.descricao || '',
|
||||
@@ -68,6 +148,9 @@ export function consolidarPecasEComponentes(rawItems: any[]): {
|
||||
|
||||
if (!pecasMap.has(pecaKey)) {
|
||||
pecasMap.set(pecaKey, pecaData);
|
||||
} else if (comprimentoFinal && !pecasMap.get(pecaKey).comprimento) {
|
||||
// Se a peça já estava no mapa mas sem comprimento e esta linha tem, atualiza
|
||||
pecasMap.get(pecaKey).comprimento = comprimentoFinal;
|
||||
}
|
||||
|
||||
// Se o item contém um subcomponente
|
||||
@@ -92,12 +175,14 @@ export function consolidarPecasEComponentes(rawItems: any[]): {
|
||||
}
|
||||
cleanMarca = String(numVal);
|
||||
|
||||
const compComprimento = extrairComprimentoComponenteSeguro(item);
|
||||
|
||||
const compData = {
|
||||
marca_componente: cleanMarca,
|
||||
descricao: item.descricao_componente || item.descricao || '',
|
||||
perfil: item.perfil_componente || item.perfil_principal || '',
|
||||
peso_unitario: Number(item.peso_unitario_componente) || 0,
|
||||
comprimento: item.comprimento_componente ? Number(item.comprimento_componente) : null,
|
||||
comprimento: compComprimento,
|
||||
quantidade_por_peca: Math.max(1, Math.round(Number(item.quantidade_por_peca) || 1)),
|
||||
};
|
||||
|
||||
@@ -110,6 +195,12 @@ export function consolidarPecasEComponentes(rawItems: any[]): {
|
||||
const exists = comps.some((c) => c.marca_componente === cleanMarca);
|
||||
if (!exists) {
|
||||
comps.push(compData);
|
||||
} else if (compComprimento) {
|
||||
// Se já existia mas sem comprimento, atualiza
|
||||
const cExistente = comps.find((c) => c.marca_componente === cleanMarca);
|
||||
if (cExistente && !cExistente.comprimento) {
|
||||
cExistente.comprimento = compComprimento;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { ItemAnaliseImportacao } from '@/types/importDiff';
|
||||
import { extrairComprimentoSeguro } from '@/utils/importDiffService';
|
||||
|
||||
export interface ExecucaoImportacaoParams {
|
||||
itens: ItemAnaliseImportacao[];
|
||||
@@ -75,12 +76,14 @@ export async function executarImportacaoConciliada(
|
||||
const pesoUnitFinal = Number(importado.peso_unitario || existente.peso_unitario || 0);
|
||||
const pesoTotalCalculado = Number((qtdFinal * pesoUnitFinal).toFixed(3)) || Number(importado.peso_total || 0);
|
||||
|
||||
const comprFinal = extrairComprimentoSeguro(importado) ?? extrairComprimentoSeguro(existente);
|
||||
|
||||
const payloadUpdate: any = {
|
||||
descricao: importado.descricao || existente.descricao || '',
|
||||
quantidade: qtdFinal,
|
||||
peso_unitario: pesoUnitFinal,
|
||||
peso_total: pesoTotalCalculado,
|
||||
comprimento: importado.comprimento !== undefined ? importado.comprimento : existente.comprimento,
|
||||
comprimento: comprFinal,
|
||||
tratamento_superficial: importado.tratamento_superficial || existente.tratamento_superficial || 'pintura',
|
||||
material: importado.material || existente.material || 'Aço A36',
|
||||
perfil_principal: importado.perfil_principal || existente.perfil_principal || '',
|
||||
@@ -170,6 +173,7 @@ export async function executarImportacaoConciliada(
|
||||
const qtd = Number(imp.quantidade) || 0;
|
||||
const pesoU = Number(imp.peso_unitario) || 0;
|
||||
const pesoT = Number(imp.peso_total) || Number((qtd * pesoU).toFixed(3));
|
||||
const comprFinal = extrairComprimentoSeguro(imp);
|
||||
|
||||
return {
|
||||
of_number: imp.of_number,
|
||||
@@ -179,7 +183,7 @@ export async function executarImportacaoConciliada(
|
||||
quantidade: qtd,
|
||||
peso_unitario: pesoU,
|
||||
peso_total: pesoT,
|
||||
comprimento: imp.comprimento || null,
|
||||
comprimento: comprFinal,
|
||||
tratamento_superficial: imp.tratamento_superficial || 'pintura',
|
||||
material: imp.material || 'Aço A36',
|
||||
perfil_principal: imp.perfil_principal || '',
|
||||
|
||||
Reference in New Issue
Block a user