diff --git a/src/pages/Supplies.tsx b/src/pages/Supplies.tsx
index 75495b2..ac9963a 100644
--- a/src/pages/Supplies.tsx
+++ b/src/pages/Supplies.tsx
@@ -9,6 +9,7 @@ import {
ClipboardCheck,
ClipboardList,
Download,
+ Eye,
Link as LinkIcon,
Package,
PackageSearch,
@@ -2099,26 +2100,55 @@ const getNeedDisplayName = (need: SupplyPurchaseNeed) => (
need.material.replace(/^Cadastrar (consumo|rendimento):\s*/i, '')
);
-const getNeedPendingLabel = (need: SupplyPurchaseNeed) => {
- if (!need.missingReference) return purchaseStatusLabels[need.status];
- return /^Cadastrar rendimento:/i.test(need.material) ? 'Rendimento' : 'Referência';
-};
-
const hasNegativeMaterialBalance = (need: SupplyPurchaseNeed) => need.stockKg < 0;
-type PurchaseNeedTab = 'materials' | 'services' | 'mapping';
+type PurchaseNeedTab = 'materials' | 'services';
type MaterialPurchaseFilter = 'to_buy' | 'negative_balance' | 'no_stock' | 'all';
const sumNeedProducts = (
need: SupplyPurchaseNeed,
- field: 'suggestedQuantity' | 'quantitySold' | 'stockQuantity'
+ field: 'suggestedQuantity'
) => (
(need.products || []).reduce((total, product) => total + Number(product[field] || 0), 0)
);
-const countImpactedSkus = (needs: SupplyPurchaseNeed[]) => (
- new Set(needs.flatMap(need => (need.products || []).map(product => product.productId).filter(Boolean))).size
-);
+const AffectedProducts = ({ products }: { products: SupplyPurchaseNeed['products'] }) => {
+ if (!products?.length) return null;
+
+ return (
+
+
Produtos afetados
+ {products.slice(0, 3).map(product => (
+
+
+ #{product.productId} · {product.name}
+
+
+
+
+
+
+
+
+ ))}
+ {products.length > 3 &&
+{products.length - 3} SKUs}
+
+ );
+};
const PurchaseMaterialQueue = ({ needs }: { needs: SupplyPurchaseNeed[] }) => (
<>
@@ -2192,22 +2222,7 @@ const PurchaseMaterialQueue = ({ needs }: { needs: SupplyPurchaseNeed[] }) => (
- {products.length > 0 && (
-
- Produtos afetados
- {products.slice(0, 3).map(product => (
-
- #{product.productId} · {product.name}
-
- ))}
- {products.length > 3 && +{products.length - 3} SKUs}
-
- )}
+
);
})}
@@ -2264,85 +2279,7 @@ const PurchaseServiceQueue = ({ needs }: { needs: SupplyPurchaseNeed[] }) => (
- {products.length > 0 && (
-
- Produtos afetados
- {products.slice(0, 3).map(product => (
-
- #{product.productId} · {product.name}
-
- ))}
- {products.length > 3 && +{products.length - 3} SKUs}
-
- )}
-
- );
- })}
-
- >
-);
-
-const PurchaseMappingQueue = ({ needs }: { needs: SupplyPurchaseNeed[] }) => (
- <>
-
-
- SKU sem composição confiável
- Impacto antes de comprar
- Correção
-
-
-
- {needs.map(need => {
- const referenceProduct = need.products?.[0];
- const productName = referenceProduct?.name || getNeedDisplayName(need);
- const productId = referenceProduct?.productId || '';
- const soldQuantity = referenceProduct?.quantitySold ?? sumNeedProducts(need, 'quantitySold');
- const stockQuantity = referenceProduct?.stockQuantity ?? sumNeedProducts(need, 'stockQuantity');
-
- return (
-
-
-
- {productId ? (
-
{productName}
- ) : (
-
{productName}
- )}
-
- {productId ? `SKU ${productId}` : 'SKU não informado'}
- {getNeedPendingLabel(need)}
-
-
-
-
-
-
Vendido
-
{formatNumber(soldQuantity, 0)} un.
-
-
-
Estoque produto
-
{formatNumber(stockQuantity, 0)} un.
-
-
-
Necessidade estimada
-
{formatNeedQuantity(need, need.purchaseKg)}
-
-
-
-
- {referenceProduct ? (
-
-
- Mapear consumo
-
- ) : (
-
SKU necessário para corrigir
- )}
-
-
+
);
})}
@@ -2357,7 +2294,7 @@ const PurchaseNeedsScreen = () => {
const [search, setSearch] = useState('');
const requestedTab = searchParams.get('tab');
const requestedFilter = searchParams.get('filter');
- const activeTab: PurchaseNeedTab = requestedTab === 'services' || requestedTab === 'mapping' ? requestedTab : 'materials';
+ const activeTab: PurchaseNeedTab = requestedTab === 'services' ? 'services' : 'materials';
const materialFilter: MaterialPurchaseFilter = requestedFilter === 'negative_balance' || requestedFilter === 'no_stock' || requestedFilter === 'all' ? requestedFilter : 'to_buy';
const [currentPage, setCurrentPage] = useState(1);
const [itemsPerPage, setItemsPerPage] = useState(10);
@@ -2395,7 +2332,6 @@ const PurchaseNeedsScreen = () => {
const materialNeeds = summary.purchaseNeeds.filter(need => !need.missingReference && !isServicePurchaseNeed(need));
const serviceNeeds = summary.purchaseNeeds.filter(need => !need.missingReference && isServicePurchaseNeed(need));
- const mappingNeeds = summary.purchaseNeeds.filter(need => need.missingReference);
const purchaseNeeds = materialNeeds.filter(need => need.purchaseKg > 0);
const negativeBalanceNeeds = materialNeeds.filter(hasNegativeMaterialBalance);
const noStockNeeds = materialNeeds.filter(need => need.stockKg === 0 && need.purchaseKg > 0);
@@ -2411,7 +2347,7 @@ const PurchaseNeedsScreen = () => {
if (a.status !== b.status) return a.status === 'critical' ? -1 : b.status === 'critical' ? 1 : 0;
return b.purchaseKg - a.purchaseKg;
})
- : activeTab === 'services' ? serviceNeeds : mappingNeeds;
+ : serviceNeeds;
const normalizedSearch = normalizeSearch(search);
const visibleNeeds = activeNeeds.filter(need => (
!normalizedSearch || normalizeSearch(`${need.material} ${getNeedDisplayName(need)} ${need.suppliers.join(' ')} ${need.colors.join(' ')} ${(need.products || []).map(product => `${product.productId} ${product.name}`).join(' ')}`).includes(normalizedSearch)
@@ -2422,9 +2358,8 @@ const PurchaseNeedsScreen = () => {
const paginatedNeeds = visibleNeeds.slice(startIndex, startIndex + itemsPerPage);
const purchaseItemCount = purchaseNeeds.length;
const suggestedPurchaseSummary = summarizePurchaseNeeds(purchaseNeeds);
- const impactedSkuCount = countImpactedSkus(mappingNeeds);
const pageTitle = 'Necessidade de Compra';
- const pageSubtitle = 'Materiais, serviços terceirizados e pendências de cadastro em filas separadas.';
+ const pageSubtitle = 'Materiais e serviços terceirizados para execução; pendências de cadastro ficam em Dados para revisar.';
const materialFilters: Array<{ id: MaterialPurchaseFilter; label: string; description: string; count: number }> = [
{ id: 'to_buy', label: 'Comprar agora', description: 'Materiais com saldo insuficiente para a demanda.', count: purchaseItemCount },
{ id: 'negative_balance', label: 'Saldo negativo', description: 'Divergências de estoque que precisam de conferência.', count: negativeBalanceNeeds.length },
@@ -2432,17 +2367,15 @@ const PurchaseNeedsScreen = () => {
{ id: 'all', label: 'Todos os materiais', description: 'Inclui itens cobertos para auditoria da conta.', count: materialNeeds.length },
];
const activeMaterialFilter = materialFilters.find(filter => filter.id === materialFilter);
- const panelTitle = activeTab === 'materials' ? activeMaterialFilter?.label || 'Compra de materiais' : activeTab === 'services' ? 'Serviços terceirizados' : 'Pendências de composição';
+ const panelTitle = activeTab === 'materials' ? activeMaterialFilter?.label || 'Compra de materiais' : 'Serviços terceirizados';
const panelSubtitle = activeTab === 'materials'
? activeMaterialFilter?.description || 'Demanda de produto → material → saldo disponível → quantidade para comprar.'
- : activeTab === 'services'
- ? 'Necessidades de beneficiamento e serviços. Não entram no total de compra de materiais.'
- : 'SKUs sem consumo confiável. Corrija o cadastro antes de usar estes valores para comprar.';
+ : 'Necessidades de beneficiamento e serviços. Não entram no total de compra de materiais.';
return (
-
+
-
@@ -2488,7 +2412,6 @@ const PurchaseNeedsScreen = () => {
type="button"
onClick={() => exportCsv(`necessidade-${activeTab}.csv`, visibleNeeds.map(need => ({
material: getNeedDisplayName(need),
- pendencia: need.missingReference ? getNeedPendingLabel(need) : '',
planejado: need.plannedKg,
estoque: need.stockKg,
pendente: need.pendingKg,
@@ -2511,7 +2434,6 @@ const PurchaseNeedsScreen = () => {
{[
{ id: 'materials' as const, label: `Compra (${purchaseItemCount})` },
{ id: 'services' as const, label: `Serviços (${serviceNeeds.length})` },
- { id: 'mapping' as const, label: `Mapear dados (${mappingNeeds.length})` },
].map(tab => (
@@ -2556,8 +2478,6 @@ const PurchaseNeedsScreen = () => {
{activeTab === 'materials' ? (
- ) : activeTab === 'mapping' ? (
-
) : (
)}
@@ -2568,7 +2488,7 @@ const PurchaseNeedsScreen = () => {
totalPages={totalPages}
pageSize={itemsPerPage}
pageSizeOptions={[10, 20, 50, 100]}
- itemLabel={activeTab === 'materials' ? 'materiais' : activeTab === 'services' ? 'serviços' : 'pendências'}
+ itemLabel={activeTab === 'materials' ? 'materiais' : 'serviços'}
pageSizeLabel="itens por página"
startIndex={startIndex}
endIndex={Math.min(startIndex + itemsPerPage, visibleNeeds.length)}