fix: persistencia e extracao de comprimento de pecas e subcomponentes na importacao
This commit is contained in:
@@ -26,7 +26,7 @@ import * as XLSX from 'xlsx';
|
|||||||
import { useAppLabels } from '@/hooks/useAppLabels';
|
import { useAppLabels } from '@/hooks/useAppLabels';
|
||||||
import { usePecas } from '@/hooks/usePecas';
|
import { usePecas } from '@/hooks/usePecas';
|
||||||
import { supabase } from '@/integrations/supabase/client';
|
import { supabase } from '@/integrations/supabase/client';
|
||||||
import { analisarConflitosImportacao, consolidarPecasEComponentes } from '@/utils/importDiffService';
|
import { analisarConflitosImportacao, consolidarPecasEComponentes, extrairComprimentoSeguro, extrairComprimentoComponenteSeguro } from '@/utils/importDiffService';
|
||||||
import { ResultadoAnaliseImportacao } from '@/types/importDiff';
|
import { ResultadoAnaliseImportacao } from '@/types/importDiff';
|
||||||
import { ImportarPecasDiffModal } from '@/components/pecas/ImportarPecasDiffModal';
|
import { ImportarPecasDiffModal } from '@/components/pecas/ImportarPecasDiffModal';
|
||||||
|
|
||||||
@@ -835,8 +835,12 @@ const AdvanceSteelConverterContent: React.FC = () => {
|
|||||||
try {
|
try {
|
||||||
const importacaoRows: any[] = [];
|
const importacaoRows: any[] = [];
|
||||||
extractedData.forEach((item) => {
|
extractedData.forEach((item) => {
|
||||||
|
const comprPeca = extrairComprimentoSeguro(item.comprimentoMax);
|
||||||
|
|
||||||
if (item.components && item.components.length > 0) {
|
if (item.components && item.components.length > 0) {
|
||||||
item.components.forEach((comp) => {
|
item.components.forEach((comp) => {
|
||||||
|
const comprComp = extrairComprimentoComponenteSeguro(comp.comprimento);
|
||||||
|
|
||||||
importacaoRows.push({
|
importacaoRows.push({
|
||||||
of_number: item.of,
|
of_number: item.of,
|
||||||
etapa_fase: item.fase,
|
etapa_fase: item.fase,
|
||||||
@@ -845,6 +849,8 @@ const AdvanceSteelConverterContent: React.FC = () => {
|
|||||||
quantidade: Number(item.quantidade),
|
quantidade: Number(item.quantidade),
|
||||||
peso_unitario: item.pesoUnit === '-' ? 0 : Number(item.pesoUnit),
|
peso_unitario: item.pesoUnit === '-' ? 0 : Number(item.pesoUnit),
|
||||||
peso_total: item.pesoTotal === '-' ? 0 : Number(item.pesoTotal),
|
peso_total: item.pesoTotal === '-' ? 0 : Number(item.pesoTotal),
|
||||||
|
comprimento: comprPeca,
|
||||||
|
comprimento_ref: comprPeca,
|
||||||
tratamento_superficial: item.tratamentoSuperficial || tratamentoGlobal,
|
tratamento_superficial: item.tratamentoSuperficial || tratamentoGlobal,
|
||||||
material: item.material,
|
material: item.material,
|
||||||
perfil_principal: item.perfilPrincipal,
|
perfil_principal: item.perfilPrincipal,
|
||||||
@@ -853,6 +859,7 @@ const AdvanceSteelConverterContent: React.FC = () => {
|
|||||||
descricao_componente: comp.perfil || item.descricao,
|
descricao_componente: comp.perfil || item.descricao,
|
||||||
perfil_componente: comp.perfil || item.descricao,
|
perfil_componente: comp.perfil || item.descricao,
|
||||||
peso_unitario_componente: comp.pesoUnitario || 0,
|
peso_unitario_componente: comp.pesoUnitario || 0,
|
||||||
|
comprimento_componente: comprComp,
|
||||||
quantidade_por_peca: Number(comp.quantidade) || 1
|
quantidade_por_peca: Number(comp.quantidade) || 1
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -865,6 +872,8 @@ const AdvanceSteelConverterContent: React.FC = () => {
|
|||||||
quantidade: Number(item.quantidade),
|
quantidade: Number(item.quantidade),
|
||||||
peso_unitario: item.pesoUnit === '-' ? 0 : Number(item.pesoUnit),
|
peso_unitario: item.pesoUnit === '-' ? 0 : Number(item.pesoUnit),
|
||||||
peso_total: item.pesoTotal === '-' ? 0 : Number(item.pesoTotal),
|
peso_total: item.pesoTotal === '-' ? 0 : Number(item.pesoTotal),
|
||||||
|
comprimento: comprPeca,
|
||||||
|
comprimento_ref: comprPeca,
|
||||||
tratamento_superficial: item.tratamentoSuperficial || tratamentoGlobal,
|
tratamento_superficial: item.tratamentoSuperficial || tratamentoGlobal,
|
||||||
material: item.material,
|
material: item.material,
|
||||||
perfil_principal: item.perfilPrincipal,
|
perfil_principal: item.perfilPrincipal,
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import {
|
|||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
import * as XLSX from 'xlsx';
|
import * as XLSX from 'xlsx';
|
||||||
import { usePecas } from '@/hooks/usePecas';
|
import { usePecas } from '@/hooks/usePecas';
|
||||||
import { analisarConflitosImportacao, consolidarPecasEComponentes } from '@/utils/importDiffService';
|
import { analisarConflitosImportacao, consolidarPecasEComponentes, extrairComprimentoSeguro, extrairComprimentoComponenteSeguro } from '@/utils/importDiffService';
|
||||||
import { ResultadoAnaliseImportacao } from '@/types/importDiff';
|
import { ResultadoAnaliseImportacao } from '@/types/importDiff';
|
||||||
import { ImportarPecasDiffModal } from '@/components/pecas/ImportarPecasDiffModal';
|
import { ImportarPecasDiffModal } from '@/components/pecas/ImportarPecasDiffModal';
|
||||||
|
|
||||||
@@ -532,8 +532,12 @@ export const BocadConverter: React.FC = () => {
|
|||||||
try {
|
try {
|
||||||
const importacaoRows: any[] = [];
|
const importacaoRows: any[] = [];
|
||||||
extractedPieces.forEach((item) => {
|
extractedPieces.forEach((item) => {
|
||||||
|
const comprPeca = extrairComprimentoSeguro(item.comprimentoRef);
|
||||||
|
|
||||||
if (item.compostoPorComponentes === 'SIM' && item.components && item.components.length > 0) {
|
if (item.compostoPorComponentes === 'SIM' && item.components && item.components.length > 0) {
|
||||||
item.components.forEach((comp) => {
|
item.components.forEach((comp) => {
|
||||||
|
const comprComp = extrairComprimentoComponenteSeguro(comp.compr);
|
||||||
|
|
||||||
importacaoRows.push({
|
importacaoRows.push({
|
||||||
of_number: item.of,
|
of_number: item.of,
|
||||||
etapa_fase: item.fase,
|
etapa_fase: item.fase,
|
||||||
@@ -542,6 +546,8 @@ export const BocadConverter: React.FC = () => {
|
|||||||
quantidade: Number(item.quantidade),
|
quantidade: Number(item.quantidade),
|
||||||
peso_unitario: item.pesoUnitario || 0,
|
peso_unitario: item.pesoUnitario || 0,
|
||||||
peso_total: item.pesoTotal || 0,
|
peso_total: item.pesoTotal || 0,
|
||||||
|
comprimento: comprPeca,
|
||||||
|
comprimento_ref: comprPeca,
|
||||||
tratamento_superficial: item.tratamentoSuperficial,
|
tratamento_superficial: item.tratamentoSuperficial,
|
||||||
material: item.material,
|
material: item.material,
|
||||||
perfil_principal: item.perfilPrincipal,
|
perfil_principal: item.perfilPrincipal,
|
||||||
@@ -550,6 +556,7 @@ export const BocadConverter: React.FC = () => {
|
|||||||
descricao_componente: comp.perfil || item.descricao,
|
descricao_componente: comp.perfil || item.descricao,
|
||||||
perfil_componente: comp.perfil || item.descricao,
|
perfil_componente: comp.perfil || item.descricao,
|
||||||
peso_unitario_componente: comp.pesoUnit || 0,
|
peso_unitario_componente: comp.pesoUnit || 0,
|
||||||
|
comprimento_componente: comprComp,
|
||||||
quantidade_por_peca: Number(comp.quant) || 1
|
quantidade_por_peca: Number(comp.quant) || 1
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -562,6 +569,8 @@ export const BocadConverter: React.FC = () => {
|
|||||||
quantidade: Number(item.quantidade),
|
quantidade: Number(item.quantidade),
|
||||||
peso_unitario: item.pesoUnitario || 0,
|
peso_unitario: item.pesoUnitario || 0,
|
||||||
peso_total: item.pesoTotal || 0,
|
peso_total: item.pesoTotal || 0,
|
||||||
|
comprimento: comprPeca,
|
||||||
|
comprimento_ref: comprPeca,
|
||||||
tratamento_superficial: item.tratamentoSuperficial,
|
tratamento_superficial: item.tratamentoSuperficial,
|
||||||
material: item.material,
|
material: item.material,
|
||||||
perfil_principal: item.perfilPrincipal,
|
perfil_principal: item.perfilPrincipal,
|
||||||
|
|||||||
@@ -25,10 +25,13 @@ interface PecaCSVData {
|
|||||||
material: string;
|
material: string;
|
||||||
perfil_principal: string;
|
perfil_principal: string;
|
||||||
tem_componentes: boolean;
|
tem_componentes: boolean;
|
||||||
|
comprimento?: number | null;
|
||||||
|
comprimento_ref?: number | string;
|
||||||
marca_componente?: string;
|
marca_componente?: string;
|
||||||
descricao_componente?: string;
|
descricao_componente?: string;
|
||||||
perfil_componente?: string;
|
perfil_componente?: string;
|
||||||
peso_unitario_componente?: number;
|
peso_unitario_componente?: number;
|
||||||
|
comprimento_componente?: number | null;
|
||||||
quantidade_por_peca?: number;
|
quantidade_por_peca?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +111,7 @@ export function ImportarPecasModal({ open, onOpenChange, onImport, pecasExistent
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Validar e converter campos numéricos
|
// Validar e converter campos numéricos
|
||||||
const numericFields = ['quantidade', 'peso_unitario', 'peso_total', 'peso_unitario_componente', 'quantidade_por_peca'];
|
const numericFields = ['quantidade', 'peso_unitario', 'peso_total', 'peso_unitario_componente', 'quantidade_por_peca', 'comprimento', 'comprimento_ref', 'comprimento_componente'];
|
||||||
const convertedData: any = { ...rawRow };
|
const convertedData: any = { ...rawRow };
|
||||||
|
|
||||||
numericFields.forEach(field => {
|
numericFields.forEach(field => {
|
||||||
@@ -177,10 +180,12 @@ export function ImportarPecasModal({ open, onOpenChange, onImport, pecasExistent
|
|||||||
material: convertedData.material?.toString().trim() || '',
|
material: convertedData.material?.toString().trim() || '',
|
||||||
perfil_principal: convertedData.perfil_principal?.toString().trim() || '',
|
perfil_principal: convertedData.perfil_principal?.toString().trim() || '',
|
||||||
tem_componentes: convertedData.tem_componentes,
|
tem_componentes: convertedData.tem_componentes,
|
||||||
|
comprimento: convertedData.comprimento ? Number(convertedData.comprimento) : (convertedData.comprimento_ref ? Number(convertedData.comprimento_ref) : null),
|
||||||
marca_componente: convertedData.marca_componente?.toString().trim() || '',
|
marca_componente: convertedData.marca_componente?.toString().trim() || '',
|
||||||
descricao_componente: convertedData.descricao_componente?.toString().trim() || '',
|
descricao_componente: convertedData.descricao_componente?.toString().trim() || '',
|
||||||
perfil_componente: convertedData.perfil_componente?.toString().trim() || '',
|
perfil_componente: convertedData.perfil_componente?.toString().trim() || '',
|
||||||
peso_unitario_componente: convertedData.peso_unitario_componente || 0,
|
peso_unitario_componente: convertedData.peso_unitario_componente || 0,
|
||||||
|
comprimento_componente: convertedData.comprimento_componente ? Number(convertedData.comprimento_componente) : null,
|
||||||
quantidade_por_peca: convertedData.quantidade_por_peca || 0
|
quantidade_por_peca: convertedData.quantidade_por_peca || 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@
|
|||||||
import { FileSpreadsheet, Upload, Download, CheckCircle2, AlertCircle, Trash2, ArrowLeft, RefreshCw } from 'lucide-react';
|
import { FileSpreadsheet, Upload, Download, CheckCircle2, AlertCircle, Trash2, ArrowLeft, RefreshCw } from 'lucide-react';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
import * as XLSX from 'xlsx';
|
import * as XLSX from 'xlsx';
|
||||||
import { analisarConflitosImportacao, consolidarPecasEComponentes } from '@/utils/importDiffService';
|
import { analisarConflitosImportacao, consolidarPecasEComponentes, extrairComprimentoSeguro, extrairComprimentoComponenteSeguro } from '@/utils/importDiffService';
|
||||||
import { ResultadoAnaliseImportacao } from '@/types/importDiff';
|
import { ResultadoAnaliseImportacao } from '@/types/importDiff';
|
||||||
import { ImportarPecasDiffModal } from '@/components/pecas/ImportarPecasDiffModal';
|
import { ImportarPecasDiffModal } from '@/components/pecas/ImportarPecasDiffModal';
|
||||||
|
|
||||||
@@ -471,8 +471,8 @@ export function ImportarXLSModal({
|
|||||||
quantidade: p.quantidade,
|
quantidade: p.quantidade,
|
||||||
peso_unitario: p.peso_unitario,
|
peso_unitario: p.peso_unitario,
|
||||||
peso_total: p.peso_total,
|
peso_total: p.peso_total,
|
||||||
comprimento: p.comprimento !== undefined && p.comprimento !== null ? Number(p.comprimento) : (p.comprimento_ref ? Number(p.comprimento_ref) : null),
|
comprimento: extrairComprimentoSeguro(p),
|
||||||
comprimento_ref: p.comprimento_ref ? Number(p.comprimento_ref) : (p.comprimento ? Number(p.comprimento) : null),
|
comprimento_ref: extrairComprimentoSeguro(p),
|
||||||
tratamento_superficial: p.tratamento_superficial || 'pintura',
|
tratamento_superficial: p.tratamento_superficial || 'pintura',
|
||||||
material: p.material,
|
material: p.material,
|
||||||
perfil_principal: p.perfil_principal,
|
perfil_principal: p.perfil_principal,
|
||||||
@@ -481,6 +481,7 @@ export function ImportarXLSModal({
|
|||||||
descricao_componente: p.descricao_componente,
|
descricao_componente: p.descricao_componente,
|
||||||
perfil_componente: p.perfil_componente,
|
perfil_componente: p.perfil_componente,
|
||||||
peso_unitario_componente: p.peso_unitario_componente,
|
peso_unitario_componente: p.peso_unitario_componente,
|
||||||
|
comprimento_componente: extrairComprimentoComponenteSeguro(p),
|
||||||
quantidade_por_peca: p.quantidade_por_peca,
|
quantidade_por_peca: p.quantidade_por_peca,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { useState, useEffect, useCallback } from 'react';
|
|||||||
import { supabase } from '@/integrations/supabase/client';
|
import { supabase } from '@/integrations/supabase/client';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
import { useAuth } from '@/hooks/useAuth';
|
import { useAuth } from '@/hooks/useAuth';
|
||||||
|
import { extrairComprimentoSeguro, extrairComprimentoComponenteSeguro } from '@/utils/importDiffService';
|
||||||
|
|
||||||
export interface Peca {
|
export interface Peca {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -425,6 +426,7 @@ export function usePecas() {
|
|||||||
|
|
||||||
pecasData.forEach((item, index) => {
|
pecasData.forEach((item, index) => {
|
||||||
const pecaKey = `${item.of_number || ''}-${item.etapa_fase || ''}-${item.marca || ''}`;
|
const pecaKey = `${item.of_number || ''}-${item.etapa_fase || ''}-${item.marca || ''}`;
|
||||||
|
const comprimentoPeca = extrairComprimentoSeguro(item);
|
||||||
|
|
||||||
const pecaData = {
|
const pecaData = {
|
||||||
of_number: item.of_number || '',
|
of_number: item.of_number || '',
|
||||||
@@ -434,7 +436,7 @@ export function usePecas() {
|
|||||||
quantidade: Number(item.quantidade) || 0,
|
quantidade: Number(item.quantidade) || 0,
|
||||||
peso_unitario: Number(item.peso_unitario) || 0,
|
peso_unitario: Number(item.peso_unitario) || 0,
|
||||||
peso_total: Number(item.peso_total) || 0,
|
peso_total: Number(item.peso_total) || 0,
|
||||||
comprimento: item.comprimento ? Number(item.comprimento) : (item.comprimento_ref ? Number(item.comprimento_ref) : null),
|
comprimento: comprimentoPeca,
|
||||||
tratamento_superficial: item.tratamento_superficial || '',
|
tratamento_superficial: item.tratamento_superficial || '',
|
||||||
material: item.material || '',
|
material: item.material || '',
|
||||||
perfil_principal: item.perfil_principal || '',
|
perfil_principal: item.perfil_principal || '',
|
||||||
@@ -445,6 +447,8 @@ export function usePecas() {
|
|||||||
|
|
||||||
if (!pecasMap.has(pecaKey)) {
|
if (!pecasMap.has(pecaKey)) {
|
||||||
pecasMap.set(pecaKey, pecaData);
|
pecasMap.set(pecaKey, pecaData);
|
||||||
|
} else if (comprimentoPeca && !pecasMap.get(pecaKey).comprimento) {
|
||||||
|
pecasMap.get(pecaKey).comprimento = comprimentoPeca;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.marca_componente && String(item.marca_componente).trim()) {
|
if (item.marca_componente && String(item.marca_componente).trim()) {
|
||||||
@@ -470,12 +474,13 @@ export function usePecas() {
|
|||||||
}
|
}
|
||||||
cleanMarca = String(numVal);
|
cleanMarca = String(numVal);
|
||||||
|
|
||||||
|
const compComprimento = extrairComprimentoComponenteSeguro(item);
|
||||||
const componenteData = {
|
const componenteData = {
|
||||||
marca_componente: cleanMarca,
|
marca_componente: cleanMarca,
|
||||||
descricao: item.descricao_componente || item.descricao || '',
|
descricao: item.descricao_componente || item.descricao || '',
|
||||||
perfil: item.perfil_componente || item.perfil_principal || '',
|
perfil: item.perfil_componente || item.perfil_principal || '',
|
||||||
peso_unitario: Number(item.peso_unitario_componente) || 0,
|
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)),
|
quantidade_por_peca: Math.max(1, Math.round(Number(item.quantidade_por_peca) || 1)),
|
||||||
user_id: user.id
|
user_id: user.id
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -27,6 +27,90 @@ const CAMPOS_MONITORADOS: CampoConfig[] = [
|
|||||||
{ key: 'tem_componentes', label: 'Tem Componentes', isCritico: true },
|
{ 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
|
* Normaliza e agrupa linhas de peças e subcomponentes
|
||||||
*/
|
*/
|
||||||
@@ -45,6 +129,7 @@ export function consolidarPecasEComponentes(rawItems: any[]): {
|
|||||||
if (!marca) return;
|
if (!marca) return;
|
||||||
|
|
||||||
const pecaKey = `${ofNumber}-${etapaFase}-${marca}`;
|
const pecaKey = `${ofNumber}-${etapaFase}-${marca}`;
|
||||||
|
const comprimentoFinal = extrairComprimentoSeguro(item);
|
||||||
|
|
||||||
const pecaData = {
|
const pecaData = {
|
||||||
of_number: ofNumber,
|
of_number: ofNumber,
|
||||||
@@ -54,12 +139,7 @@ export function consolidarPecasEComponentes(rawItems: any[]): {
|
|||||||
quantidade: Number(item.quantidade) || 0,
|
quantidade: Number(item.quantidade) || 0,
|
||||||
peso_unitario: Number(item.peso_unitario) || 0,
|
peso_unitario: Number(item.peso_unitario) || 0,
|
||||||
peso_total: Number(item.peso_total) || 0,
|
peso_total: Number(item.peso_total) || 0,
|
||||||
comprimento:
|
comprimento: comprimentoFinal,
|
||||||
item.comprimento !== undefined && item.comprimento !== null
|
|
||||||
? Number(item.comprimento)
|
|
||||||
: item.comprimento_ref
|
|
||||||
? Number(item.comprimento_ref)
|
|
||||||
: null,
|
|
||||||
tratamento_superficial: item.tratamento_superficial || 'pintura',
|
tratamento_superficial: item.tratamento_superficial || 'pintura',
|
||||||
material: item.material || 'Aço A36',
|
material: item.material || 'Aço A36',
|
||||||
perfil_principal: item.perfil_principal || item.descricao || '',
|
perfil_principal: item.perfil_principal || item.descricao || '',
|
||||||
@@ -68,6 +148,9 @@ export function consolidarPecasEComponentes(rawItems: any[]): {
|
|||||||
|
|
||||||
if (!pecasMap.has(pecaKey)) {
|
if (!pecasMap.has(pecaKey)) {
|
||||||
pecasMap.set(pecaKey, pecaData);
|
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
|
// Se o item contém um subcomponente
|
||||||
@@ -92,12 +175,14 @@ export function consolidarPecasEComponentes(rawItems: any[]): {
|
|||||||
}
|
}
|
||||||
cleanMarca = String(numVal);
|
cleanMarca = String(numVal);
|
||||||
|
|
||||||
|
const compComprimento = extrairComprimentoComponenteSeguro(item);
|
||||||
|
|
||||||
const compData = {
|
const compData = {
|
||||||
marca_componente: cleanMarca,
|
marca_componente: cleanMarca,
|
||||||
descricao: item.descricao_componente || item.descricao || '',
|
descricao: item.descricao_componente || item.descricao || '',
|
||||||
perfil: item.perfil_componente || item.perfil_principal || '',
|
perfil: item.perfil_componente || item.perfil_principal || '',
|
||||||
peso_unitario: Number(item.peso_unitario_componente) || 0,
|
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)),
|
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);
|
const exists = comps.some((c) => c.marca_componente === cleanMarca);
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
comps.push(compData);
|
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 { supabase } from '@/integrations/supabase/client';
|
||||||
import { ItemAnaliseImportacao } from '@/types/importDiff';
|
import { ItemAnaliseImportacao } from '@/types/importDiff';
|
||||||
|
import { extrairComprimentoSeguro } from '@/utils/importDiffService';
|
||||||
|
|
||||||
export interface ExecucaoImportacaoParams {
|
export interface ExecucaoImportacaoParams {
|
||||||
itens: ItemAnaliseImportacao[];
|
itens: ItemAnaliseImportacao[];
|
||||||
@@ -75,12 +76,14 @@ export async function executarImportacaoConciliada(
|
|||||||
const pesoUnitFinal = Number(importado.peso_unitario || existente.peso_unitario || 0);
|
const pesoUnitFinal = Number(importado.peso_unitario || existente.peso_unitario || 0);
|
||||||
const pesoTotalCalculado = Number((qtdFinal * pesoUnitFinal).toFixed(3)) || Number(importado.peso_total || 0);
|
const pesoTotalCalculado = Number((qtdFinal * pesoUnitFinal).toFixed(3)) || Number(importado.peso_total || 0);
|
||||||
|
|
||||||
|
const comprFinal = extrairComprimentoSeguro(importado) ?? extrairComprimentoSeguro(existente);
|
||||||
|
|
||||||
const payloadUpdate: any = {
|
const payloadUpdate: any = {
|
||||||
descricao: importado.descricao || existente.descricao || '',
|
descricao: importado.descricao || existente.descricao || '',
|
||||||
quantidade: qtdFinal,
|
quantidade: qtdFinal,
|
||||||
peso_unitario: pesoUnitFinal,
|
peso_unitario: pesoUnitFinal,
|
||||||
peso_total: pesoTotalCalculado,
|
peso_total: pesoTotalCalculado,
|
||||||
comprimento: importado.comprimento !== undefined ? importado.comprimento : existente.comprimento,
|
comprimento: comprFinal,
|
||||||
tratamento_superficial: importado.tratamento_superficial || existente.tratamento_superficial || 'pintura',
|
tratamento_superficial: importado.tratamento_superficial || existente.tratamento_superficial || 'pintura',
|
||||||
material: importado.material || existente.material || 'Aço A36',
|
material: importado.material || existente.material || 'Aço A36',
|
||||||
perfil_principal: importado.perfil_principal || existente.perfil_principal || '',
|
perfil_principal: importado.perfil_principal || existente.perfil_principal || '',
|
||||||
@@ -170,6 +173,7 @@ export async function executarImportacaoConciliada(
|
|||||||
const qtd = Number(imp.quantidade) || 0;
|
const qtd = Number(imp.quantidade) || 0;
|
||||||
const pesoU = Number(imp.peso_unitario) || 0;
|
const pesoU = Number(imp.peso_unitario) || 0;
|
||||||
const pesoT = Number(imp.peso_total) || Number((qtd * pesoU).toFixed(3));
|
const pesoT = Number(imp.peso_total) || Number((qtd * pesoU).toFixed(3));
|
||||||
|
const comprFinal = extrairComprimentoSeguro(imp);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
of_number: imp.of_number,
|
of_number: imp.of_number,
|
||||||
@@ -179,7 +183,7 @@ export async function executarImportacaoConciliada(
|
|||||||
quantidade: qtd,
|
quantidade: qtd,
|
||||||
peso_unitario: pesoU,
|
peso_unitario: pesoU,
|
||||||
peso_total: pesoT,
|
peso_total: pesoT,
|
||||||
comprimento: imp.comprimento || null,
|
comprimento: comprFinal,
|
||||||
tratamento_superficial: imp.tratamento_superficial || 'pintura',
|
tratamento_superficial: imp.tratamento_superficial || 'pintura',
|
||||||
material: imp.material || 'Aço A36',
|
material: imp.material || 'Aço A36',
|
||||||
perfil_principal: imp.perfil_principal || '',
|
perfil_principal: imp.perfil_principal || '',
|
||||||
|
|||||||
Reference in New Issue
Block a user