feat: filtro exclusivo por marca de peca e controle dimensional de comprimento no romaneio
This commit is contained in:
@@ -59,11 +59,11 @@ export const ApontamentosFilters: React.FC<ApontamentosFiltersProps> = ({
|
|||||||
{/* Primeira linha de filtros - mais compacta */}
|
{/* Primeira linha de filtros - mais compacta */}
|
||||||
<div className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-5 gap-2">
|
<div className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-5 gap-2">
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
<label className="text-xs font-medium">Buscar</label>
|
<label className="text-xs font-medium">Buscar Marca</label>
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<Search className="absolute left-2 top-1/2 transform -translate-y-1/2 h-3 w-3 text-muted-foreground" />
|
<Search className="absolute left-2 top-1/2 transform -translate-y-1/2 h-3 w-3 text-muted-foreground" />
|
||||||
<Input
|
<Input
|
||||||
placeholder="OF, Marca..."
|
placeholder="Marca da peça..."
|
||||||
value={searchTerm}
|
value={searchTerm}
|
||||||
onChange={(e) => setSearchTerm(e.target.value)}
|
onChange={(e) => setSearchTerm(e.target.value)}
|
||||||
className="pl-7 h-8 text-xs"
|
className="pl-7 h-8 text-xs"
|
||||||
|
|||||||
@@ -143,18 +143,17 @@ export const useApontamentosFilters = (apontamentos: ApontamentoProducao[]) => {
|
|||||||
|
|
||||||
let resultado = [...apontamentos]; // Começar com TODOS os apontamentos
|
let resultado = [...apontamentos]; // Começar com TODOS os apontamentos
|
||||||
|
|
||||||
// Aplicar filtro de busca textual APENAS se preenchido
|
// Aplicar filtro de busca por MARCA DA PEÇA apenas se preenchido
|
||||||
if (searchTerm && searchTerm.trim() !== '') {
|
if (searchTerm && searchTerm.trim() !== '') {
|
||||||
const searchLower = searchTerm.toLowerCase();
|
const searchLower = searchTerm.toLowerCase().trim();
|
||||||
const beforeSearch = resultado.length;
|
const beforeSearch = resultado.length;
|
||||||
|
|
||||||
resultado = resultado.filter(apt =>
|
resultado = resultado.filter(apt =>
|
||||||
(apt.of_number && apt.of_number.toLowerCase().includes(searchLower)) ||
|
|
||||||
(apt.peca?.marca && apt.peca.marca.toLowerCase().includes(searchLower)) ||
|
(apt.peca?.marca && apt.peca.marca.toLowerCase().includes(searchLower)) ||
|
||||||
(apt.componente?.marca_componente && apt.componente.marca_componente.toLowerCase().includes(searchLower))
|
(apt.componente?.marca_componente && apt.componente.marca_componente.toLowerCase().includes(searchLower))
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log(`🔎 Filtro texto "${searchTerm}": ${beforeSearch} → ${resultado.length} registros`);
|
console.log(`🔎 Filtro marca "${searchTerm}": ${beforeSearch} → ${resultado.length} registros`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Aplicar filtro por OF APENAS se selecionado
|
// Aplicar filtro por OF APENAS se selecionado
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { ScrollArea } from '@/components/ui/scroll-area';
|
|||||||
import { Card, CardContent } from '@/components/ui/card';
|
import { Card, CardContent } from '@/components/ui/card';
|
||||||
import { Checkbox } from '@/components/ui/checkbox';
|
import { Checkbox } from '@/components/ui/checkbox';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
import { Package, Plus, Wrench, Expand } from 'lucide-react';
|
import { Package, Plus, Wrench, Expand, AlertTriangle } from 'lucide-react';
|
||||||
import { RomaneioExpedicao } from '@/hooks/useRomaneios';
|
import { RomaneioExpedicao } from '@/hooks/useRomaneios';
|
||||||
import { useProcessosFabricacao } from '@/hooks/useProcessosFabricacao';
|
import { useProcessosFabricacao } from '@/hooks/useProcessosFabricacao';
|
||||||
import { usePecas } from '@/hooks/usePecas';
|
import { usePecas } from '@/hooks/usePecas';
|
||||||
@@ -31,6 +31,7 @@ interface PecaDisponivel {
|
|||||||
etapa_fase: string;
|
etapa_fase: string;
|
||||||
quantidade_disponivel: number;
|
quantidade_disponivel: number;
|
||||||
peso_unitario: number;
|
peso_unitario: number;
|
||||||
|
comprimento?: number | null;
|
||||||
prioridade: string;
|
prioridade: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,6 +41,7 @@ interface ItemRomaneioPeca {
|
|||||||
quantidade: number;
|
quantidade: number;
|
||||||
peso_unitario: number;
|
peso_unitario: number;
|
||||||
peso_total: number;
|
peso_total: number;
|
||||||
|
comprimento?: number | null;
|
||||||
marca: string;
|
marca: string;
|
||||||
descricao: string;
|
descricao: string;
|
||||||
etapa_fase: string;
|
etapa_fase: string;
|
||||||
@@ -111,6 +113,7 @@ export const ItensRomaneioModal: React.FC<ItensRomaneioModalProps> = ({
|
|||||||
descricao,
|
descricao,
|
||||||
etapa_fase,
|
etapa_fase,
|
||||||
peso_unitario,
|
peso_unitario,
|
||||||
|
comprimento,
|
||||||
prioridade,
|
prioridade,
|
||||||
of_number
|
of_number
|
||||||
)
|
)
|
||||||
@@ -165,6 +168,7 @@ export const ItensRomaneioModal: React.FC<ItensRomaneioModalProps> = ({
|
|||||||
etapa_fase: apontamento.peca.etapa_fase || '',
|
etapa_fase: apontamento.peca.etapa_fase || '',
|
||||||
quantidade_disponivel: quantidade, // Bruto temporário
|
quantidade_disponivel: quantidade, // Bruto temporário
|
||||||
peso_unitario: apontamento.peca.peso_unitario || 0,
|
peso_unitario: apontamento.peca.peso_unitario || 0,
|
||||||
|
comprimento: apontamento.peca.comprimento || null,
|
||||||
prioridade: apontamento.peca.prioridade || 'P4'
|
prioridade: apontamento.peca.prioridade || 'P4'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -210,7 +214,7 @@ export const ItensRomaneioModal: React.FC<ItensRomaneioModalProps> = ({
|
|||||||
.from('itens_romaneio_pecas')
|
.from('itens_romaneio_pecas')
|
||||||
.select(`
|
.select(`
|
||||||
*,
|
*,
|
||||||
pecas!inner(marca, descricao, etapa_fase, peso_unitario, prioridade)
|
pecas!inner(marca, descricao, etapa_fase, peso_unitario, comprimento, prioridade)
|
||||||
`)
|
`)
|
||||||
.eq('romaneio_id', romaneio.id);
|
.eq('romaneio_id', romaneio.id);
|
||||||
|
|
||||||
@@ -224,6 +228,7 @@ export const ItensRomaneioModal: React.FC<ItensRomaneioModalProps> = ({
|
|||||||
quantidade: item.quantidade_expedida,
|
quantidade: item.quantidade_expedida,
|
||||||
peso_unitario: item.peso_unitario,
|
peso_unitario: item.peso_unitario,
|
||||||
peso_total: item.peso_total,
|
peso_total: item.peso_total,
|
||||||
|
comprimento: item.pecas?.comprimento || item.comprimento || null,
|
||||||
marca: item.marca,
|
marca: item.marca,
|
||||||
descricao: item.descricao || '',
|
descricao: item.descricao || '',
|
||||||
etapa_fase: item.fase || '',
|
etapa_fase: item.fase || '',
|
||||||
@@ -308,7 +313,26 @@ export const ItensRomaneioModal: React.FC<ItensRomaneioModalProps> = ({
|
|||||||
}, [pecasDisponiveis, faseFilter, marcaFilter]);
|
}, [pecasDisponiveis, faseFilter, marcaFilter]);
|
||||||
|
|
||||||
const handleAdicionarPeca = async () => {
|
const handleAdicionarPeca = async () => {
|
||||||
|
const limiteVeiculo = romaneio.comprimento_maximo_veiculo || 12000;
|
||||||
|
|
||||||
if (adicionarTodas) {
|
if (adicionarTodas) {
|
||||||
|
// Verificar se há peças que excedem a capacidade do veículo
|
||||||
|
const pecasExcedentes = pecasFiltradas.filter(p => p.comprimento && p.comprimento > limiteVeiculo);
|
||||||
|
if (pecasExcedentes.length > 0) {
|
||||||
|
const listaMarcas = pecasExcedentes.map(p => `${p.marca} (${p.comprimento}mm)`).join(', ');
|
||||||
|
const confirmar = window.confirm(
|
||||||
|
`⚠️ ALERTA DE CAPACIDADE DO VEÍCULO:\n\n` +
|
||||||
|
`Atenção: ${pecasExcedentes.length} peça(s) excedem o limite de ${limiteVeiculo} mm (${(limiteVeiculo / 1000).toFixed(1)}m) do veículo:\n` +
|
||||||
|
`${listaMarcas}\n\n` +
|
||||||
|
`Essas peças são maiores que o espaço de carga do veículo selecionado.\n\n` +
|
||||||
|
`Deseja realmente incluí-las no romaneio?`
|
||||||
|
);
|
||||||
|
if (!confirmar) {
|
||||||
|
toast.warning('Operação cancelada para evitar carregar peças que não cabem no caminhão.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Adicionar todas as peças filtradas com suas quantidades disponíveis
|
// Adicionar todas as peças filtradas com suas quantidades disponíveis
|
||||||
for (const peca of pecasFiltradas) {
|
for (const peca of pecasFiltradas) {
|
||||||
try {
|
try {
|
||||||
@@ -345,6 +369,21 @@ export const ItensRomaneioModal: React.FC<ItensRomaneioModalProps> = ({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validação de comprimento do veículo
|
||||||
|
if (pecaSelecionada.comprimento && pecaSelecionada.comprimento > limiteVeiculo) {
|
||||||
|
const confirmar = window.confirm(
|
||||||
|
`⚠️ ALERTA DE CAPACIDADE DO VEÍCULO:\n\n` +
|
||||||
|
`A peça "${pecaSelecionada.marca}" tem comprimento de ${pecaSelecionada.comprimento} mm (${(pecaSelecionada.comprimento / 1000).toFixed(1)}m), ` +
|
||||||
|
`que ULTRAPASSA o comprimento máximo suportado pelo veículo (${limiteVeiculo} mm / ${(limiteVeiculo / 1000).toFixed(1)}m)!\n\n` +
|
||||||
|
`Essa peça NÃO caberá na carroceria do transporte selecionado.\n\n` +
|
||||||
|
`Deseja realmente adicionar esta peça mesmo com essa advertência?`
|
||||||
|
);
|
||||||
|
if (!confirmar) {
|
||||||
|
toast.warning(`Inclusão da peça ${pecaSelecionada.marca} (${pecaSelecionada.comprimento}mm) cancelada por restrição dimensional.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const quantidade = parseInt(quantidadePeca);
|
const quantidade = parseInt(quantidadePeca);
|
||||||
|
|
||||||
@@ -604,13 +643,26 @@ export const ItensRomaneioModal: React.FC<ItensRomaneioModalProps> = ({
|
|||||||
Nenhuma peça disponível para este processo
|
Nenhuma peça disponível para este processo
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
) : (
|
) : (
|
||||||
pecasFiltradas.map((peca) => (
|
pecasFiltradas.map((peca) => {
|
||||||
|
const limite = romaneio.comprimento_maximo_veiculo || 12000;
|
||||||
|
const naoCabe = Boolean(peca.comprimento && peca.comprimento > limite);
|
||||||
|
return (
|
||||||
<SelectItem key={peca.id} value={peca.id}>
|
<SelectItem key={peca.id} value={peca.id}>
|
||||||
|
<div className="flex items-center justify-between gap-2 w-full">
|
||||||
<span className="truncate">
|
<span className="truncate">
|
||||||
{peca.marca} - {peca.descricao} (Qtd: {peca.quantidade_disponivel})
|
{peca.marca} - {peca.descricao} (Qtd: {peca.quantidade_disponivel})
|
||||||
</span>
|
</span>
|
||||||
|
{peca.comprimento && (
|
||||||
|
<span className={`text-[11px] font-mono shrink-0 ml-2 px-1.5 py-0.5 rounded ${
|
||||||
|
naoCabe ? 'bg-destructive/20 text-destructive font-bold' : 'text-muted-foreground bg-muted'
|
||||||
|
}`}>
|
||||||
|
{peca.comprimento}mm {naoCabe ? '⚠️ NÃO CABE' : ''}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
))
|
);
|
||||||
|
})
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
@@ -633,6 +685,26 @@ export const ItensRomaneioModal: React.FC<ItensRomaneioModalProps> = ({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Alerta de dimensão se a peça exceder a capacidade do veículo */}
|
||||||
|
{(() => {
|
||||||
|
const pSel = pecasDisponiveis.find(p => p.id === pecaDisponivel);
|
||||||
|
const limite = romaneio.comprimento_maximo_veiculo || 12000;
|
||||||
|
if (pSel?.comprimento && pSel.comprimento > limite) {
|
||||||
|
return (
|
||||||
|
<div className="p-2.5 mb-3 rounded-md bg-destructive/15 border border-destructive/40 text-destructive text-xs space-y-1">
|
||||||
|
<div className="flex items-center gap-1.5 font-bold text-xs text-destructive">
|
||||||
|
<AlertTriangle className="h-4 w-4 shrink-0" />
|
||||||
|
ALERTA DE DIMENSÃO: Peça não cabe no veículo ({limite}mm)
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
A peça <strong>{pSel.marca}</strong> possui <strong>{pSel.comprimento} mm ({(pSel.comprimento / 1000).toFixed(1)}m)</strong> e ULTRAPASSA o comprimento máximo de carregamento deste veículo ({(limite / 1000).toFixed(1)}m).
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
})()}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ interface ItemRomaneioPeca {
|
|||||||
quantidade_expedida: number;
|
quantidade_expedida: number;
|
||||||
peso_unitario: number;
|
peso_unitario: number;
|
||||||
peso_total: number;
|
peso_total: number;
|
||||||
|
comprimento?: number | null;
|
||||||
marca: string;
|
marca: string;
|
||||||
descricao: string;
|
descricao: string;
|
||||||
fase: string;
|
fase: string;
|
||||||
@@ -44,7 +45,7 @@ export const PecasRomaneioExpandido: React.FC<PecasRomaneioExpandidoProps> = ({
|
|||||||
try {
|
try {
|
||||||
const { data, error } = await supabase
|
const { data, error } = await supabase
|
||||||
.from('itens_romaneio_pecas')
|
.from('itens_romaneio_pecas')
|
||||||
.select('*')
|
.select('*, pecas(comprimento)')
|
||||||
.eq('romaneio_id', romaneio.id)
|
.eq('romaneio_id', romaneio.id)
|
||||||
.order('marca');
|
.order('marca');
|
||||||
|
|
||||||
@@ -57,6 +58,7 @@ export const PecasRomaneioExpandido: React.FC<PecasRomaneioExpandidoProps> = ({
|
|||||||
quantidade_expedida: item.quantidade_expedida,
|
quantidade_expedida: item.quantidade_expedida,
|
||||||
peso_unitario: item.peso_unitario,
|
peso_unitario: item.peso_unitario,
|
||||||
peso_total: item.peso_total,
|
peso_total: item.peso_total,
|
||||||
|
comprimento: item.pecas?.comprimento || item.comprimento || null,
|
||||||
marca: item.marca,
|
marca: item.marca,
|
||||||
descricao: item.descricao || '',
|
descricao: item.descricao || '',
|
||||||
fase: item.fase || '',
|
fase: item.fase || '',
|
||||||
@@ -170,11 +172,12 @@ export const PecasRomaneioExpandido: React.FC<PecasRomaneioExpandidoProps> = ({
|
|||||||
{/* Cabeçalho da tabela - Desktop/Tablet */}
|
{/* Cabeçalho da tabela - Desktop/Tablet */}
|
||||||
{!isMobile && (
|
{!isMobile && (
|
||||||
<div className={`grid gap-3 font-medium text-gray-400 bg-slate-800 p-3 rounded-t-md sticky top-0 z-10 ${
|
<div className={`grid gap-3 font-medium text-gray-400 bg-slate-800 p-3 rounded-t-md sticky top-0 z-10 ${
|
||||||
isTablet ? 'grid-cols-8 text-xs' : 'grid-cols-10 text-xs'
|
isTablet ? 'grid-cols-9 text-xs' : 'grid-cols-11 text-xs'
|
||||||
}`}>
|
}`}>
|
||||||
<div>Marca</div>
|
<div>Marca</div>
|
||||||
<div>Fase</div>
|
<div>Fase</div>
|
||||||
<div className={isTablet ? 'col-span-1' : 'col-span-2'}>Descrição</div>
|
<div className={isTablet ? 'col-span-1' : 'col-span-2'}>Descrição</div>
|
||||||
|
<div className="text-right">Comp. (mm)</div>
|
||||||
<div className="text-center">Qtd</div>
|
<div className="text-center">Qtd</div>
|
||||||
<div className="text-right">Peso Unit.</div>
|
<div className="text-right">Peso Unit.</div>
|
||||||
<div className="text-right">Peso Total</div>
|
<div className="text-right">Peso Total</div>
|
||||||
@@ -184,16 +187,29 @@ export const PecasRomaneioExpandido: React.FC<PecasRomaneioExpandidoProps> = ({
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Linhas de dados */}
|
{/* Linhas de dados */}
|
||||||
{itensPeca.map((item, index) => (
|
{itensPeca.map((item, index) => {
|
||||||
|
const limite = romaneio.comprimento_maximo_veiculo || 12000;
|
||||||
|
const naoCabe = Boolean(item.comprimento && item.comprimento > limite);
|
||||||
|
|
||||||
|
return (
|
||||||
<div key={item.id}>
|
<div key={item.id}>
|
||||||
{isMobile ? (
|
{isMobile ? (
|
||||||
// Layout mobile - card style
|
// Layout mobile - card style
|
||||||
<div className={`p-3 border border-slate-700 rounded-md mb-2 ${
|
<div className={`p-3 border rounded-md mb-2 ${
|
||||||
|
naoCabe ? 'border-red-500/50 bg-red-950/20' : 'border-slate-700'
|
||||||
|
} ${
|
||||||
index % 2 === 0 ? 'bg-slate-800/20' : 'bg-slate-800/40'
|
index % 2 === 0 ? 'bg-slate-800/20' : 'bg-slate-800/40'
|
||||||
}`}>
|
}`}>
|
||||||
<div className="flex justify-between items-start mb-2">
|
<div className="flex justify-between items-start mb-2">
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
<div className="font-medium text-white text-sm">{item.marca}</div>
|
<div className="font-medium text-white text-sm flex items-center gap-1.5">
|
||||||
|
{item.marca}
|
||||||
|
{naoCabe && (
|
||||||
|
<span className="text-[10px] bg-red-600 text-white font-bold px-1.5 py-0.5 rounded">
|
||||||
|
Excede Veículo
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
<div className="text-gray-300 text-xs">{item.fase}</div>
|
<div className="text-gray-300 text-xs">{item.fase}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex gap-1">
|
<div className="flex gap-1">
|
||||||
@@ -218,7 +234,13 @@ export const PecasRomaneioExpandido: React.FC<PecasRomaneioExpandidoProps> = ({
|
|||||||
<div className="text-gray-300 text-xs mb-2 line-clamp-2">
|
<div className="text-gray-300 text-xs mb-2 line-clamp-2">
|
||||||
{item.descricao}
|
{item.descricao}
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-3 gap-2 text-xs">
|
<div className="grid grid-cols-4 gap-2 text-xs">
|
||||||
|
<div>
|
||||||
|
<div className="text-gray-400">Comp:</div>
|
||||||
|
<div className={`font-mono font-medium ${naoCabe ? 'text-red-400 font-bold' : 'text-gray-300'}`}>
|
||||||
|
{item.comprimento ? `${item.comprimento}mm` : '-'}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div className="text-gray-400">Qtd:</div>
|
<div className="text-gray-400">Qtd:</div>
|
||||||
<div className="font-bold text-blue-400">{item.quantidade_expedida}</div>
|
<div className="font-bold text-blue-400">{item.quantidade_expedida}</div>
|
||||||
@@ -237,12 +259,18 @@ export const PecasRomaneioExpandido: React.FC<PecasRomaneioExpandidoProps> = ({
|
|||||||
// Layout desktop/tablet - table style
|
// Layout desktop/tablet - table style
|
||||||
<div className={`grid gap-3 text-sm p-3 border-b border-slate-700 hover:bg-slate-800/50 transition-colors ${
|
<div className={`grid gap-3 text-sm p-3 border-b border-slate-700 hover:bg-slate-800/50 transition-colors ${
|
||||||
index % 2 === 0 ? 'bg-slate-800/20' : ''
|
index % 2 === 0 ? 'bg-slate-800/20' : ''
|
||||||
} ${isTablet ? 'grid-cols-8' : 'grid-cols-10'}`}>
|
} ${isTablet ? 'grid-cols-9' : 'grid-cols-11'} ${naoCabe ? 'bg-red-950/20' : ''}`}>
|
||||||
<div className="font-medium text-white truncate">{item.marca}</div>
|
<div className="font-medium text-white truncate flex items-center gap-1">
|
||||||
|
{item.marca}
|
||||||
|
{naoCabe && <span title="Não cabe no veículo" className="text-red-400 text-xs">⚠️</span>}
|
||||||
|
</div>
|
||||||
<div className="text-gray-300 truncate">{item.fase}</div>
|
<div className="text-gray-300 truncate">{item.fase}</div>
|
||||||
<div className={`text-gray-300 truncate ${isTablet ? 'col-span-1' : 'col-span-2'}`}>
|
<div className={`text-gray-300 truncate ${isTablet ? 'col-span-1' : 'col-span-2'}`}>
|
||||||
{item.descricao}
|
{item.descricao}
|
||||||
</div>
|
</div>
|
||||||
|
<div className={`text-right font-mono text-xs ${naoCabe ? 'text-red-400 font-bold' : 'text-gray-300'}`}>
|
||||||
|
{item.comprimento ? `${item.comprimento}` : '-'}
|
||||||
|
</div>
|
||||||
<div className="text-center font-bold text-blue-400">
|
<div className="text-center font-bold text-blue-400">
|
||||||
{item.quantidade_expedida}
|
{item.quantidade_expedida}
|
||||||
</div>
|
</div>
|
||||||
@@ -280,7 +308,8 @@ export const PecasRomaneioExpandido: React.FC<PecasRomaneioExpandidoProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
))}
|
);
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ export function RomaneioForm({ romaneio, ofNumbers, selectedOF, onSave, onCancel
|
|||||||
peso_total_romaneio: romaneio?.peso_total_romaneio || 0,
|
peso_total_romaneio: romaneio?.peso_total_romaneio || 0,
|
||||||
previsao_kg: romaneio?.previsao_kg || 0,
|
previsao_kg: romaneio?.previsao_kg || 0,
|
||||||
maior_dimensao: romaneio?.maior_dimensao || '',
|
maior_dimensao: romaneio?.maior_dimensao || '',
|
||||||
|
comprimento_maximo_veiculo: romaneio?.comprimento_maximo_veiculo || 12000,
|
||||||
tipo_transporte: romaneio?.tipo_transporte || 'carro' as 'carro' | 'utilitario' | 'caminho_pequeno' | 'caminhao_trucado' | 'caminhao_munck' | 'carreta_12m' | 'carreta_15m' | 'especial',
|
tipo_transporte: romaneio?.tipo_transporte || 'carro' as 'carro' | 'utilitario' | 'caminho_pequeno' | 'caminhao_trucado' | 'caminhao_munck' | 'carreta_12m' | 'carreta_15m' | 'especial',
|
||||||
frete_tipo: (romaneio?.frete_tipo as 'terceiros' | 'proprio') || 'terceiros',
|
frete_tipo: (romaneio?.frete_tipo as 'terceiros' | 'proprio') || 'terceiros',
|
||||||
nome_motorista: romaneio?.nome_motorista || ''
|
nome_motorista: romaneio?.nome_motorista || ''
|
||||||
@@ -74,6 +75,7 @@ export function RomaneioForm({ romaneio, ofNumbers, selectedOF, onSave, onCancel
|
|||||||
peso_total_romaneio: romaneio.peso_total_romaneio || 0,
|
peso_total_romaneio: romaneio.peso_total_romaneio || 0,
|
||||||
previsao_kg: romaneio.previsao_kg || 0,
|
previsao_kg: romaneio.previsao_kg || 0,
|
||||||
maior_dimensao: romaneio.maior_dimensao || '',
|
maior_dimensao: romaneio.maior_dimensao || '',
|
||||||
|
comprimento_maximo_veiculo: romaneio.comprimento_maximo_veiculo || 12000,
|
||||||
tipo_transporte: romaneio.tipo_transporte || 'carro',
|
tipo_transporte: romaneio.tipo_transporte || 'carro',
|
||||||
frete_tipo: (romaneio.frete_tipo as 'terceiros' | 'proprio') || 'terceiros',
|
frete_tipo: (romaneio.frete_tipo as 'terceiros' | 'proprio') || 'terceiros',
|
||||||
nome_motorista: romaneio.nome_motorista || ''
|
nome_motorista: romaneio.nome_motorista || ''
|
||||||
@@ -92,6 +94,7 @@ export function RomaneioForm({ romaneio, ofNumbers, selectedOF, onSave, onCancel
|
|||||||
peso_total_romaneio: 0,
|
peso_total_romaneio: 0,
|
||||||
previsao_kg: 0,
|
previsao_kg: 0,
|
||||||
maior_dimensao: '',
|
maior_dimensao: '',
|
||||||
|
comprimento_maximo_veiculo: 12000,
|
||||||
tipo_transporte: 'carro',
|
tipo_transporte: 'carro',
|
||||||
frete_tipo: 'terceiros',
|
frete_tipo: 'terceiros',
|
||||||
nome_motorista: ''
|
nome_motorista: ''
|
||||||
@@ -374,7 +377,23 @@ export function RomaneioForm({ romaneio, ofNumbers, selectedOF, onSave, onCancel
|
|||||||
<Label htmlFor="tipo_transporte">Tipo de Transporte</Label>
|
<Label htmlFor="tipo_transporte">Tipo de Transporte</Label>
|
||||||
<Select
|
<Select
|
||||||
value={formData.tipo_transporte}
|
value={formData.tipo_transporte}
|
||||||
onValueChange={(value: any) => setFormData(prev => ({ ...prev, tipo_transporte: value }))}
|
onValueChange={(value: any) => {
|
||||||
|
const compPadrao = {
|
||||||
|
carro: 1500,
|
||||||
|
utilitario: 2500,
|
||||||
|
caminho_pequeno: 6000,
|
||||||
|
caminhao_trucado: 8000,
|
||||||
|
caminhao_munck: 7000,
|
||||||
|
carreta_12m: 12000,
|
||||||
|
carreta_15m: 15000,
|
||||||
|
especial: 18000
|
||||||
|
}[value] || 12000;
|
||||||
|
setFormData(prev => ({
|
||||||
|
...prev,
|
||||||
|
tipo_transporte: value,
|
||||||
|
comprimento_maximo_veiculo: compPadrao
|
||||||
|
}));
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<SelectTrigger>
|
<SelectTrigger>
|
||||||
<SelectValue />
|
<SelectValue />
|
||||||
@@ -389,6 +408,29 @@ export function RomaneioForm({ romaneio, ofNumbers, selectedOF, onSave, onCancel
|
|||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-2">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<Label htmlFor="comprimento_maximo_veiculo">Capacidade Máx. Peça (mm) *</Label>
|
||||||
|
{formData.comprimento_maximo_veiculo > 0 && (
|
||||||
|
<span className="text-xs font-semibold text-primary">
|
||||||
|
{(formData.comprimento_maximo_veiculo / 1000).toFixed(1)}m
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<Input
|
||||||
|
id="comprimento_maximo_veiculo"
|
||||||
|
type="number"
|
||||||
|
min="0"
|
||||||
|
step="100"
|
||||||
|
value={formData.comprimento_maximo_veiculo || ''}
|
||||||
|
onChange={(e) => setFormData(prev => ({ ...prev, comprimento_maximo_veiculo: parseFloat(e.target.value) || 0 }))}
|
||||||
|
placeholder="Ex: 10000 (10 metros)"
|
||||||
|
/>
|
||||||
|
<p className="text-[11px] text-muted-foreground">
|
||||||
|
Limite de comprimento para carregar peças neste veículo.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="frete_tipo">Tipo de Frete</Label>
|
<Label htmlFor="frete_tipo">Tipo de Frete</Label>
|
||||||
<Select
|
<Select
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ interface ComponentesPopupProps {
|
|||||||
peca: Peca;
|
peca: Peca;
|
||||||
}
|
}
|
||||||
|
|
||||||
type SortField = 'marca_componente' | 'descricao' | 'perfil' | 'peso_unitario' | 'quantidade_por_peca';
|
type SortField = 'marca_componente' | 'descricao' | 'perfil' | 'comprimento' | 'peso_unitario' | 'quantidade_por_peca';
|
||||||
type SortOrder = 'asc' | 'desc';
|
type SortOrder = 'asc' | 'desc';
|
||||||
|
|
||||||
export function ComponentesPopup({ isOpen, onClose, peca }: ComponentesPopupProps) {
|
export function ComponentesPopup({ isOpen, onClose, peca }: ComponentesPopupProps) {
|
||||||
@@ -46,6 +46,7 @@ export function ComponentesPopup({ isOpen, onClose, peca }: ComponentesPopupProp
|
|||||||
marca_componente: '',
|
marca_componente: '',
|
||||||
descricao: '',
|
descricao: '',
|
||||||
perfil: '',
|
perfil: '',
|
||||||
|
comprimento: 0,
|
||||||
peso_unitario: 0,
|
peso_unitario: 0,
|
||||||
quantidade_por_peca: 1
|
quantidade_por_peca: 1
|
||||||
});
|
});
|
||||||
@@ -55,6 +56,7 @@ export function ComponentesPopup({ isOpen, onClose, peca }: ComponentesPopupProp
|
|||||||
marca_componente: '',
|
marca_componente: '',
|
||||||
descricao: '',
|
descricao: '',
|
||||||
perfil: '',
|
perfil: '',
|
||||||
|
comprimento: 0,
|
||||||
peso_unitario: 0,
|
peso_unitario: 0,
|
||||||
quantidade_por_peca: 1
|
quantidade_por_peca: 1
|
||||||
});
|
});
|
||||||
@@ -119,6 +121,7 @@ export function ComponentesPopup({ isOpen, onClose, peca }: ComponentesPopupProp
|
|||||||
marca_componente: componente.marca_componente,
|
marca_componente: componente.marca_componente,
|
||||||
descricao: componente.descricao || '',
|
descricao: componente.descricao || '',
|
||||||
perfil: componente.perfil || '',
|
perfil: componente.perfil || '',
|
||||||
|
comprimento: componente.comprimento || 0,
|
||||||
peso_unitario: componente.peso_unitario,
|
peso_unitario: componente.peso_unitario,
|
||||||
quantidade_por_peca: componente.quantidade_por_peca
|
quantidade_por_peca: componente.quantidade_por_peca
|
||||||
});
|
});
|
||||||
@@ -173,7 +176,7 @@ export function ComponentesPopup({ isOpen, onClose, peca }: ComponentesPopupProp
|
|||||||
</CardTitle>
|
</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="space-y-3">
|
<CardContent className="space-y-3">
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-3">
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-6 gap-3">
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
<Label htmlFor="marca_componente" className="text-sm">Componente *</Label>
|
<Label htmlFor="marca_componente" className="text-sm">Componente *</Label>
|
||||||
<Input
|
<Input
|
||||||
@@ -208,6 +211,20 @@ export function ComponentesPopup({ isOpen, onClose, peca }: ComponentesPopupProp
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-1">
|
||||||
|
<Label htmlFor="comprimento" className="text-sm">Comp. (mm)</Label>
|
||||||
|
<Input
|
||||||
|
id="comprimento"
|
||||||
|
type="number"
|
||||||
|
step="1"
|
||||||
|
min="0"
|
||||||
|
value={formData.comprimento || ''}
|
||||||
|
onChange={(e) => setFormData(prev => ({ ...prev, comprimento: parseFloat(e.target.value) || 0 }))}
|
||||||
|
placeholder="Ex: 500"
|
||||||
|
className="h-8"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
<Label htmlFor="peso_unitario" className="text-sm">Peso Unitário</Label>
|
<Label htmlFor="peso_unitario" className="text-sm">Peso Unitário</Label>
|
||||||
<Input
|
<Input
|
||||||
@@ -331,6 +348,15 @@ export function ComponentesPopup({ isOpen, onClose, peca }: ComponentesPopupProp
|
|||||||
{getSortIcon('perfil')}
|
{getSortIcon('perfil')}
|
||||||
</div>
|
</div>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
|
<TableHead
|
||||||
|
className="cursor-pointer hover:bg-muted/50 select-none text-right px-2 py-1"
|
||||||
|
onClick={() => handleSort('comprimento')}
|
||||||
|
>
|
||||||
|
<div className="flex items-center justify-end gap-1 text-xs font-medium">
|
||||||
|
Comp. (mm)
|
||||||
|
{getSortIcon('comprimento')}
|
||||||
|
</div>
|
||||||
|
</TableHead>
|
||||||
<TableHead
|
<TableHead
|
||||||
className="cursor-pointer hover:bg-muted/50 select-none text-center px-2 py-1"
|
className="cursor-pointer hover:bg-muted/50 select-none text-center px-2 py-1"
|
||||||
onClick={() => handleSort('quantidade_por_peca')}
|
onClick={() => handleSort('quantidade_por_peca')}
|
||||||
@@ -366,6 +392,7 @@ export function ComponentesPopup({ isOpen, onClose, peca }: ComponentesPopupProp
|
|||||||
<TableCell className="font-medium px-2 py-1 text-sm">{componente.marca_componente}</TableCell>
|
<TableCell className="font-medium px-2 py-1 text-sm">{componente.marca_componente}</TableCell>
|
||||||
<TableCell className="px-2 py-1 text-sm">{componente.descricao || '-'}</TableCell>
|
<TableCell className="px-2 py-1 text-sm">{componente.descricao || '-'}</TableCell>
|
||||||
<TableCell className="px-2 py-1 text-sm">{componente.perfil || '-'}</TableCell>
|
<TableCell className="px-2 py-1 text-sm">{componente.perfil || '-'}</TableCell>
|
||||||
|
<TableCell className="text-right px-2 py-1 text-sm font-mono">{componente.comprimento ? `${componente.comprimento}` : '-'}</TableCell>
|
||||||
<TableCell className="text-center px-2 py-1 text-sm">{componente.quantidade_por_peca}</TableCell>
|
<TableCell className="text-center px-2 py-1 text-sm">{componente.quantidade_por_peca}</TableCell>
|
||||||
<TableCell className="text-center font-medium px-2 py-1 text-sm">
|
<TableCell className="text-center font-medium px-2 py-1 text-sm">
|
||||||
{calculateTotalQuantity(componente.quantidade_por_peca)}
|
{calculateTotalQuantity(componente.quantidade_por_peca)}
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ export function PecaForm({
|
|||||||
quantidade: 1,
|
quantidade: 1,
|
||||||
peso_unitario: 0,
|
peso_unitario: 0,
|
||||||
peso_total: 0,
|
peso_total: 0,
|
||||||
|
comprimento: 0,
|
||||||
tratamento_superficial: '',
|
tratamento_superficial: '',
|
||||||
material: '',
|
material: '',
|
||||||
perfil_principal: '',
|
perfil_principal: '',
|
||||||
@@ -71,6 +72,7 @@ export function PecaForm({
|
|||||||
quantidade: editingPeca.quantidade,
|
quantidade: editingPeca.quantidade,
|
||||||
peso_unitario: editingPeca.peso_unitario,
|
peso_unitario: editingPeca.peso_unitario,
|
||||||
peso_total: editingPeca.peso_total,
|
peso_total: editingPeca.peso_total,
|
||||||
|
comprimento: editingPeca.comprimento || 0,
|
||||||
tratamento_superficial: editingPeca.tratamento_superficial || '',
|
tratamento_superficial: editingPeca.tratamento_superficial || '',
|
||||||
material: editingPeca.material || '',
|
material: editingPeca.material || '',
|
||||||
perfil_principal: editingPeca.perfil_principal || '',
|
perfil_principal: editingPeca.perfil_principal || '',
|
||||||
@@ -85,6 +87,7 @@ export function PecaForm({
|
|||||||
quantidade: 1,
|
quantidade: 1,
|
||||||
peso_unitario: 0,
|
peso_unitario: 0,
|
||||||
peso_total: 0,
|
peso_total: 0,
|
||||||
|
comprimento: 0,
|
||||||
tratamento_superficial: '',
|
tratamento_superficial: '',
|
||||||
material: '',
|
material: '',
|
||||||
perfil_principal: '',
|
perfil_principal: '',
|
||||||
@@ -148,6 +151,7 @@ export function PecaForm({
|
|||||||
quantidade: 1,
|
quantidade: 1,
|
||||||
peso_unitario: 0,
|
peso_unitario: 0,
|
||||||
peso_total: 0,
|
peso_total: 0,
|
||||||
|
comprimento: 0,
|
||||||
tratamento_superficial: '',
|
tratamento_superficial: '',
|
||||||
material: '',
|
material: '',
|
||||||
perfil_principal: '',
|
perfil_principal: '',
|
||||||
@@ -246,6 +250,19 @@ export function PecaForm({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Label htmlFor="comprimento">Comprimento (mm)</Label>
|
||||||
|
<Input
|
||||||
|
id="comprimento"
|
||||||
|
type="number"
|
||||||
|
step="1"
|
||||||
|
min="0"
|
||||||
|
value={formData.comprimento || ''}
|
||||||
|
onChange={(e) => handleInputChange('comprimento', parseFloat(e.target.value) || 0)}
|
||||||
|
placeholder="Ex: 12000"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<Label htmlFor="tratamento_superficial">Tratamento Superficial</Label>
|
<Label htmlFor="tratamento_superficial">Tratamento Superficial</Label>
|
||||||
<Input
|
<Input
|
||||||
|
|||||||
@@ -88,6 +88,10 @@ export function TableHeaderSortable({
|
|||||||
<SortButton field="peso_total">Peso Total</SortButton>
|
<SortButton field="peso_total">Peso Total</SortButton>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
|
|
||||||
|
<TableHead className="w-20 px-2 text-right">
|
||||||
|
<SortButton field="comprimento">Comp. (mm)</SortButton>
|
||||||
|
</TableHead>
|
||||||
|
|
||||||
<TableHead className="w-16 px-2">
|
<TableHead className="w-16 px-2">
|
||||||
<span className="text-xs font-medium">Material</span>
|
<span className="text-xs font-medium">Material</span>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
|
|||||||
@@ -144,6 +144,10 @@ export function TableRow({
|
|||||||
{(peca.peso_total || (peca.quantidade * peca.peso_unitario)).toFixed(2)} kg
|
{(peca.peso_total || (peca.quantidade * peca.peso_unitario)).toFixed(2)} kg
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
||||||
|
<TableCell className="w-20 px-2 text-right font-mono font-medium text-foreground text-xs">
|
||||||
|
{peca.comprimento != null && Number(peca.comprimento) > 0 ? `${Number(peca.comprimento).toLocaleString('pt-BR')} mm` : '-'}
|
||||||
|
</TableCell>
|
||||||
|
|
||||||
<TableCell className="w-16 px-2 text-muted-foreground text-xs">
|
<TableCell className="w-16 px-2 text-muted-foreground text-xs">
|
||||||
{peca.material || '-'}
|
{peca.material || '-'}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
@@ -246,6 +250,7 @@ export function TableRow({
|
|||||||
<tr>
|
<tr>
|
||||||
<th className="p-2 pl-3">Marca {labels.componenteLabel}</th>
|
<th className="p-2 pl-3">Marca {labels.componenteLabel}</th>
|
||||||
<th className="p-2">Descrição / Perfil</th>
|
<th className="p-2">Descrição / Perfil</th>
|
||||||
|
<th className="p-2 text-right">Comp. (mm)</th>
|
||||||
<th className="p-2 text-center">Qtd / {labels.pecaLabel}</th>
|
<th className="p-2 text-center">Qtd / {labels.pecaLabel}</th>
|
||||||
<th className="p-2 text-center font-bold">Qtd Total no Lote</th>
|
<th className="p-2 text-center font-bold">Qtd Total no Lote</th>
|
||||||
<th className="p-2 text-right">Peso Unit. (kg)</th>
|
<th className="p-2 text-right">Peso Unit. (kg)</th>
|
||||||
@@ -269,6 +274,9 @@ export function TableRow({
|
|||||||
<td className="p-2 text-slate-700 dark:text-slate-300 font-medium">
|
<td className="p-2 text-slate-700 dark:text-slate-300 font-medium">
|
||||||
{comp.perfil || comp.descricao || '-'}
|
{comp.perfil || comp.descricao || '-'}
|
||||||
</td>
|
</td>
|
||||||
|
<td className="p-2 text-right font-mono text-slate-700 dark:text-slate-300">
|
||||||
|
{comp.comprimento != null && Number(comp.comprimento) > 0 ? `${Number(comp.comprimento).toLocaleString('pt-BR')} mm` : '-'}
|
||||||
|
</td>
|
||||||
<td className="p-2 text-center font-mono text-slate-600 dark:text-slate-400">
|
<td className="p-2 text-center font-mono text-slate-600 dark:text-slate-400">
|
||||||
{qtdPorPeca} un
|
{qtdPorPeca} un
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ export interface ComponentePeca {
|
|||||||
descricao: string | null;
|
descricao: string | null;
|
||||||
perfil: string | null;
|
perfil: string | null;
|
||||||
peso_unitario: number;
|
peso_unitario: number;
|
||||||
|
comprimento?: number | null;
|
||||||
quantidade_por_peca: number;
|
quantidade_por_peca: number;
|
||||||
created_at: string;
|
created_at: string;
|
||||||
updated_at: string;
|
updated_at: string;
|
||||||
@@ -21,6 +22,7 @@ export interface ComponenteFormData {
|
|||||||
descricao: string;
|
descricao: string;
|
||||||
perfil: string;
|
perfil: string;
|
||||||
peso_unitario: number;
|
peso_unitario: number;
|
||||||
|
comprimento?: number | null;
|
||||||
quantidade_por_peca: number;
|
quantidade_por_peca: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ export interface Peca {
|
|||||||
quantidade: number;
|
quantidade: number;
|
||||||
peso_unitario: number;
|
peso_unitario: number;
|
||||||
peso_total: number;
|
peso_total: number;
|
||||||
|
comprimento?: number | null;
|
||||||
tratamento_superficial: string;
|
tratamento_superficial: string;
|
||||||
material: string;
|
material: string;
|
||||||
perfil_principal: string;
|
perfil_principal: string;
|
||||||
@@ -430,6 +431,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),
|
||||||
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 || '',
|
||||||
@@ -470,6 +472,7 @@ export function usePecas() {
|
|||||||
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,
|
||||||
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
|
||||||
};
|
};
|
||||||
@@ -527,6 +530,7 @@ export function usePecas() {
|
|||||||
quantidade: peca.quantidade,
|
quantidade: peca.quantidade,
|
||||||
peso_unitario: peca.peso_unitario,
|
peso_unitario: peca.peso_unitario,
|
||||||
peso_total: peca.peso_total,
|
peso_total: peca.peso_total,
|
||||||
|
comprimento: peca.comprimento,
|
||||||
tratamento_superficial: peca.tratamento_superficial,
|
tratamento_superficial: peca.tratamento_superficial,
|
||||||
material: peca.material,
|
material: peca.material,
|
||||||
perfil_principal: peca.perfil_principal,
|
perfil_principal: peca.perfil_principal,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { Peca } from './usePecas';
|
|||||||
import { supabase } from '@/integrations/supabase/client';
|
import { supabase } from '@/integrations/supabase/client';
|
||||||
import { applyMarcaFilter } from '@/utils/rangeFilter';
|
import { applyMarcaFilter } from '@/utils/rangeFilter';
|
||||||
|
|
||||||
export type SortField = 'of_number' | 'etapa_fase' | 'marca' | 'descricao' | 'prioridade' | 'quantidade' | 'peso_unitario' | 'peso_total' | 'perfil_principal' | 'tem_componentes';
|
export type SortField = 'of_number' | 'etapa_fase' | 'marca' | 'descricao' | 'prioridade' | 'quantidade' | 'peso_unitario' | 'peso_total' | 'comprimento' | 'perfil_principal' | 'tem_componentes';
|
||||||
export type SortOrder = 'asc' | 'desc';
|
export type SortOrder = 'asc' | 'desc';
|
||||||
|
|
||||||
export const usePecasTable = (pecas: Peca[]) => {
|
export const usePecasTable = (pecas: Peca[]) => {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ export interface RomaneioExpedicao {
|
|||||||
peso_total_romaneio: number;
|
peso_total_romaneio: number;
|
||||||
previsao_kg?: number;
|
previsao_kg?: number;
|
||||||
maior_dimensao?: string;
|
maior_dimensao?: string;
|
||||||
|
comprimento_maximo_veiculo?: number;
|
||||||
tipo_transporte?: string;
|
tipo_transporte?: string;
|
||||||
frete_tipo?: string;
|
frete_tipo?: string;
|
||||||
nome_motorista?: string;
|
nome_motorista?: string;
|
||||||
@@ -62,6 +63,7 @@ export interface PecaPintura {
|
|||||||
marca: string;
|
marca: string;
|
||||||
etapa_fase?: string;
|
etapa_fase?: string;
|
||||||
descricao?: string;
|
descricao?: string;
|
||||||
|
comprimento?: number | null;
|
||||||
peso_unitario: number;
|
peso_unitario: number;
|
||||||
quantidade_produzida_pintura: number;
|
quantidade_produzida_pintura: number;
|
||||||
quantidade_ja_expedida: number;
|
quantidade_ja_expedida: number;
|
||||||
@@ -133,6 +135,7 @@ export const usePecasPintura = (ofNumber?: string) => {
|
|||||||
etapa_fase,
|
etapa_fase,
|
||||||
descricao,
|
descricao,
|
||||||
peso_unitario,
|
peso_unitario,
|
||||||
|
comprimento,
|
||||||
of_number
|
of_number
|
||||||
),
|
),
|
||||||
processos_fabricacao (
|
processos_fabricacao (
|
||||||
@@ -171,6 +174,7 @@ export const usePecasPintura = (ofNumber?: string) => {
|
|||||||
etapa_fase: peca.etapa_fase,
|
etapa_fase: peca.etapa_fase,
|
||||||
descricao: peca.descricao,
|
descricao: peca.descricao,
|
||||||
peso_unitario: peca.peso_unitario,
|
peso_unitario: peca.peso_unitario,
|
||||||
|
comprimento: peca.comprimento,
|
||||||
quantidade_produzida_pintura: apontamento.quantidade_produzida,
|
quantidade_produzida_pintura: apontamento.quantidade_produzida,
|
||||||
of_number: peca.of_number
|
of_number: peca.of_number
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -445,6 +445,7 @@ export type Database = {
|
|||||||
}
|
}
|
||||||
componentes_peca: {
|
componentes_peca: {
|
||||||
Row: {
|
Row: {
|
||||||
|
comprimento: number | null
|
||||||
created_at: string
|
created_at: string
|
||||||
descricao: string | null
|
descricao: string | null
|
||||||
id: string
|
id: string
|
||||||
@@ -457,6 +458,7 @@ export type Database = {
|
|||||||
user_id: string | null
|
user_id: string | null
|
||||||
}
|
}
|
||||||
Insert: {
|
Insert: {
|
||||||
|
comprimento?: number | null
|
||||||
created_at?: string
|
created_at?: string
|
||||||
descricao?: string | null
|
descricao?: string | null
|
||||||
id?: string
|
id?: string
|
||||||
@@ -469,6 +471,7 @@ export type Database = {
|
|||||||
user_id?: string | null
|
user_id?: string | null
|
||||||
}
|
}
|
||||||
Update: {
|
Update: {
|
||||||
|
comprimento?: number | null
|
||||||
created_at?: string
|
created_at?: string
|
||||||
descricao?: string | null
|
descricao?: string | null
|
||||||
id?: string
|
id?: string
|
||||||
@@ -2095,6 +2098,7 @@ export type Database = {
|
|||||||
}
|
}
|
||||||
pecas: {
|
pecas: {
|
||||||
Row: {
|
Row: {
|
||||||
|
comprimento: number | null
|
||||||
created_at: string
|
created_at: string
|
||||||
descricao: string | null
|
descricao: string | null
|
||||||
etapa_fase: string | null
|
etapa_fase: string | null
|
||||||
@@ -2114,6 +2118,7 @@ export type Database = {
|
|||||||
user_id: string | null
|
user_id: string | null
|
||||||
}
|
}
|
||||||
Insert: {
|
Insert: {
|
||||||
|
comprimento?: number | null
|
||||||
created_at?: string
|
created_at?: string
|
||||||
descricao?: string | null
|
descricao?: string | null
|
||||||
etapa_fase?: string | null
|
etapa_fase?: string | null
|
||||||
@@ -2133,6 +2138,7 @@ export type Database = {
|
|||||||
user_id?: string | null
|
user_id?: string | null
|
||||||
}
|
}
|
||||||
Update: {
|
Update: {
|
||||||
|
comprimento?: number | null
|
||||||
created_at?: string
|
created_at?: string
|
||||||
descricao?: string | null
|
descricao?: string | null
|
||||||
etapa_fase?: string | null
|
etapa_fase?: string | null
|
||||||
@@ -2737,6 +2743,7 @@ export type Database = {
|
|||||||
}
|
}
|
||||||
romaneios_expedicao: {
|
romaneios_expedicao: {
|
||||||
Row: {
|
Row: {
|
||||||
|
comprimento_maximo_veiculo: number | null
|
||||||
created_at: string
|
created_at: string
|
||||||
created_by: string | null
|
created_by: string | null
|
||||||
data_criacao: string | null
|
data_criacao: string | null
|
||||||
@@ -2759,6 +2766,7 @@ export type Database = {
|
|||||||
updated_at: string
|
updated_at: string
|
||||||
}
|
}
|
||||||
Insert: {
|
Insert: {
|
||||||
|
comprimento_maximo_veiculo?: number | null
|
||||||
created_at?: string
|
created_at?: string
|
||||||
created_by?: string | null
|
created_by?: string | null
|
||||||
data_criacao?: string | null
|
data_criacao?: string | null
|
||||||
@@ -2781,6 +2789,7 @@ export type Database = {
|
|||||||
updated_at?: string
|
updated_at?: string
|
||||||
}
|
}
|
||||||
Update: {
|
Update: {
|
||||||
|
comprimento_maximo_veiculo?: number | null
|
||||||
created_at?: string
|
created_at?: string
|
||||||
created_by?: string | null
|
created_by?: string | null
|
||||||
data_criacao?: string | null
|
data_criacao?: string | null
|
||||||
|
|||||||
Reference in New Issue
Block a user