From 743dc55687ed457fdd13a7b9b178df3f5870ade9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Faleiros?= Date: Wed, 12 Aug 2026 14:59:24 -0300 Subject: [PATCH] Return open orders to cut plan --- src/pages/ProductionOrders.tsx | 41 ++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/src/pages/ProductionOrders.tsx b/src/pages/ProductionOrders.tsx index 3869fc3..90f6b1b 100644 --- a/src/pages/ProductionOrders.tsx +++ b/src/pages/ProductionOrders.tsx @@ -1,6 +1,6 @@ import { Fragment, type FormEvent, useCallback, useEffect, useMemo, useState } from 'react'; -import { Link, useOutletContext } from 'react-router-dom'; -import { ArrowLeft, CheckCircle2, ChevronDown, ChevronUp, ClipboardList, Clock3, Download, PackageCheck, PlayCircle, Search, XCircle } from 'lucide-react'; +import { Link, useNavigate, useOutletContext } from 'react-router-dom'; +import { ArrowLeft, CheckCircle2, ChevronDown, ChevronUp, ClipboardList, Clock3, Download, PackageCheck, PlayCircle, Search, Undo2, XCircle } from 'lucide-react'; import DateRangePicker from '../components/DateRangePicker'; import PaginationControls from '../components/PaginationControls'; import RefreshStatus from '../components/RefreshStatus'; @@ -121,6 +121,7 @@ const ProductionOrders = () => { refreshInterval: number; setRefreshInterval: (interval: number) => void; }>(); + const navigate = useNavigate(); const [searchTerm, setSearchTerm] = useState(''); const [statusFilter, setStatusFilter] = useState('all'); const [summary, setSummary] = useState(emptySummary); @@ -219,6 +220,25 @@ const ProductionOrders = () => { } }; + const returnOrderToCutPlan = async (order: ProductionOrderItem) => { + if (order.status !== 'open' || (order.integrationStatus || '').toLowerCase() !== 'local') return; + const orderNumber = order.number || `#${order.id}`; + if (!window.confirm(`Devolver a OP ${orderNumber} ao Plano de Corte?\n\nA OP será cancelada, preservando o histórico. A necessidade voltará para o Plano de Corte e poderá ser gerada novamente quando você decidir.`)) return; + + setBusyStatusOrderId(order.id); + setStatusMessage(''); + try { + await updateProductionOrderStatus(order.id, 'canceled'); + setSelectedOrderId(null); + setStatusMessage(`OP ${orderNumber} devolvida ao Plano de Corte.`); + navigate('/supplies/cutting'); + } catch (error) { + setStatusMessage(error instanceof Error ? error.message : 'Não foi possível devolver a OP ao Plano de Corte.'); + } finally { + setBusyStatusOrderId(null); + } + }; + const refreshSupplyLots = async () => { const supplySummary = await fetchSupplySummary(); setSupplyLots(supplySummary.lots); @@ -267,11 +287,17 @@ const ProductionOrders = () => { exportToCSV(exportData, `ordens_producao_${new Date().toISOString().split('T')[0]}.csv`); }; - const renderOrderDetails = (order: ProductionOrderItem) => ( + const renderOrderDetails = (order: ProductionOrderItem) => { + const canReturnToCutPlan = order.status === 'open' && (order.integrationStatus || '').toLowerCase() === 'local'; + + return (
-
-

Detalhes da OP

-

{order.number || `OP #${order.id}`} · {order.productDescription}

+
+
+

Detalhes da OP

+

{order.number || `OP #${order.id}`} · {order.productDescription}

+
+ {canReturnToCutPlan && }
@@ -302,7 +328,8 @@ const ProductionOrders = () => { {(order.steps.length > 0 || order.notes || order.supplier || order.lotCode || order.rollQuantity || order.fabricKg || order.ribKg || order.yieldPiecesPerKg) &&

Informações adicionais

{(order.supplier || order.lotCode || order.rollQuantity || order.fabricKg || order.ribKg || order.yieldPiecesPerKg) &&
{order.supplier &&
Fornecedor
{order.supplier}
}{order.lotCode &&
Lote
{order.lotCode}
}{order.rollQuantity !== null &&
Rolos
{formatQuantity(order.rollQuantity)}
}{order.fabricKg !== null &&
Malha
{formatQuantity(order.fabricKg)} kg
}{order.ribKg !== null &&
Ribana
{formatQuantity(order.ribKg)} kg
}{order.yieldPiecesPerKg !== null &&
Rendimento
{formatQuantity(order.yieldPiecesPerKg)} un./kg
}
}{order.steps.length > 0 &&

Etapas

{order.steps.map(step =>
{step.name}{formatDate(step.startDate)} - {formatDate(step.endDate)}
)}
}{order.notes &&

{order.notes}

}
}
- ); + ); + }; return (