diff --git a/src/pages/Cutting.tsx b/src/pages/Cutting.tsx index aa6ad69..653800d 100644 --- a/src/pages/Cutting.tsx +++ b/src/pages/Cutting.tsx @@ -163,6 +163,7 @@ const Cutting = () => { const [isOrderPreviewOpen, setIsOrderPreviewOpen] = useState(false); const [previewPage, setPreviewPage] = useState(1); const [previewItemsPerPage, setPreviewItemsPerPage] = useState(10); + const [selectedPreviewRowIds, setSelectedPreviewRowIds] = useState([]); const [editingCutRow, setEditingCutRow] = useState(null); const [quickCutEdit, setQuickCutEdit] = useState({}); const [isQuickCutEditSaving, setIsQuickCutEditSaving] = useState(false); @@ -374,17 +375,24 @@ const Cutting = () => { }; }, [cutPlan.needRows, materialReadinessByProductId]); + const selectedPreviewRows = useMemo(() => { + const selectedIds = new Set(selectedPreviewRowIds); + return rowsAvailableForOrder.filter(row => selectedIds.has(row.id)); + }, [rowsAvailableForOrder, selectedPreviewRowIds]); const orderPreviewTotalUnits = useMemo(() => ( - rowsAvailableForOrder.reduce((total, row) => total + row.suggestedCutQuantity, 0) - ), [rowsAvailableForOrder]); + selectedPreviewRows.reduce((total, row) => total + row.suggestedCutQuantity, 0) + ), [selectedPreviewRows]); const previewRowsWithIssues = useMemo(() => ( - rowsAvailableForOrder.filter(row => row.issues.length).length - ), [rowsAvailableForOrder]); + selectedPreviewRows.filter(row => row.issues.length).length + ), [selectedPreviewRows]); const previewTotalPages = Math.ceil(rowsAvailableForOrder.length / previewItemsPerPage); const safePreviewPage = Math.min(previewPage, previewTotalPages || 1); const previewStartIndex = (safePreviewPage - 1) * previewItemsPerPage; const paginatedPreviewRows = rowsAvailableForOrder.slice(previewStartIndex, previewStartIndex + previewItemsPerPage); + const selectedPreviewRowIdSet = useMemo(() => new Set(selectedPreviewRowIds), [selectedPreviewRowIds]); + const areAllPreviewRowsSelected = rowsAvailableForOrder.length > 0 && selectedPreviewRows.length === rowsAvailableForOrder.length; + const areAllPagePreviewRowsSelected = paginatedPreviewRows.length > 0 && paginatedPreviewRows.every(row => selectedPreviewRowIdSet.has(row.id)); const totalPages = Math.ceil(filteredRows.length / itemsPerPage); const safeCurrentPage = Math.min(currentPage, totalPages || 1); @@ -610,12 +618,38 @@ const Cutting = () => { setGenerationMessage(''); setPreviewPage(1); + setSelectedPreviewRowIds(rowsAvailableForOrder.map(row => row.id)); setIsOrderPreviewOpen(true); }; + const setPreviewSelection = (rows: CutPlanSkuRow[]) => { + setSelectedPreviewRowIds(rows.map(row => row.id)); + }; + + const togglePreviewRow = (productId: string) => { + setSelectedPreviewRowIds(current => ( + current.includes(productId) + ? current.filter(id => id !== productId) + : [...current, productId] + )); + }; + + const togglePreviewPage = () => { + const pageIds = paginatedPreviewRows.map(row => row.id); + setSelectedPreviewRowIds(current => { + const currentIds = new Set(current); + if (pageIds.every(id => currentIds.has(id))) { + pageIds.forEach(id => currentIds.delete(id)); + } else { + pageIds.forEach(id => currentIds.add(id)); + } + return Array.from(currentIds); + }); + }; + const generateProductionOrders = async () => { - if (!rowsAvailableForOrder.length) { - setGenerationMessage('Não há SKU com necessidade e materiais disponíveis no filtro atual.'); + if (!selectedPreviewRows.length) { + setGenerationMessage('Selecione pelo menos um SKU para gerar as ordens de produção.'); return; } @@ -626,7 +660,7 @@ const Cutting = () => { const orderReference = `Plano de corte ${formatDateKey(dateRange.start)} a ${formatDateKey(dateRange.end)} · ${targetCoverageDays} dias`; try { - const result = await createProductionOrders(rowsAvailableForOrder.map(row => ({ + const result = await createProductionOrders(selectedPreviewRows.map(row => ({ status: 'open', orderReference, issueDate, @@ -785,7 +819,7 @@ const Cutting = () => {

Prévia das OPs

- Serão criadas ordens locais para as necessidades do filtro atual. + Escolha os SKUs para criar ordens locais das necessidades do filtro atual.

+ + + + +
- +
- - - - - + + + + + + + @@ -829,7 +874,8 @@ const Cutting = () => { {paginatedPreviewRows.map(row => ( - + +
Produto Cortar agora Demanda
togglePreviewRow(row.id)} aria-label={`Selecionar ${row.name}`} className="h-4 w-4 accent-brand-primary cursor-pointer" />
{row.name}
@@ -883,11 +929,11 @@ const Cutting = () => {