Organize quality under supplies
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { Outlet, Link, useLocation } from 'react-router-dom';
|
import { Outlet, Link, useLocation } from 'react-router-dom';
|
||||||
import { LayoutDashboard, Users, BarChart3, ChevronLeft, ChevronRight, Package, LogOut, Megaphone, Grid3X3, Shield, ShieldCheck, Moon, Sun, Tags, Boxes, ClipboardList, Menu, X, BriefcaseBusiness, Radio } from 'lucide-react';
|
import { LayoutDashboard, Users, BarChart3, ChevronLeft, ChevronRight, Package, LogOut, Megaphone, Grid3X3, Shield, Moon, Sun, Tags, Boxes, ClipboardList, Menu, X, BriefcaseBusiness, Radio } from 'lucide-react';
|
||||||
import type { DateRange, OrderData } from '../types';
|
import type { DateRange, OrderData } from '../types';
|
||||||
import { isSuperAdmin, logout } from '../dataService';
|
import { isSuperAdmin, logout } from '../dataService';
|
||||||
import { rangeForLastDays } from '../dateRanges';
|
import { rangeForLastDays } from '../dateRanges';
|
||||||
@@ -83,7 +83,6 @@ const Layout = () => {
|
|||||||
{ name: 'Suprimentos', href: '/supplies', icon: Boxes },
|
{ name: 'Suprimentos', href: '/supplies', icon: Boxes },
|
||||||
{ name: 'Planos de Produção', href: '/production-plans', icon: ClipboardList },
|
{ name: 'Planos de Produção', href: '/production-plans', icon: ClipboardList },
|
||||||
{ name: 'Ordens de Produção', href: '/production-orders', icon: Package },
|
{ name: 'Ordens de Produção', href: '/production-orders', icon: Package },
|
||||||
{ name: 'Qualidade', href: '/production-quality', icon: ShieldCheck },
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useMemo, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import { Link, useOutletContext, useSearchParams } from 'react-router-dom';
|
import { Link, useOutletContext, useSearchParams } from 'react-router-dom';
|
||||||
import { AlertTriangle, ArrowLeft, ArrowRight, Check, ChevronDown, ClipboardList, Download, Eye, Layers3, Pencil, RotateCcw, Ruler, Save as SaveIcon, Scissors, Search, Settings2, UserRound, X } from 'lucide-react';
|
import { AlertTriangle, ArrowLeft, ArrowRight, Check, ChevronDown, ClipboardList, Download, Eye, Layers3, Pencil, RotateCcw, Ruler, Save as SaveIcon, Scissors, Search, Settings2, UserRound, X } from 'lucide-react';
|
||||||
import DateRangePicker from '../components/DateRangePicker';
|
import DateRangePicker from '../components/DateRangePicker';
|
||||||
@@ -394,10 +394,10 @@ const Cutting = () => {
|
|||||||
};
|
};
|
||||||
}, [cutPlan.needRows, materialReadinessByProductId]);
|
}, [cutPlan.needRows, materialReadinessByProductId]);
|
||||||
|
|
||||||
const getPreviewQuantity = (row: CutPlanSkuRow) => {
|
const getPreviewQuantity = useCallback((row: CutPlanSkuRow) => {
|
||||||
const override = Number((previewQuantityOverrides[row.id] || '').replace(',', '.'));
|
const override = Number((previewQuantityOverrides[row.id] || '').replace(',', '.'));
|
||||||
return Number.isFinite(override) && override > 0 ? Math.round(override) : row.suggestedCutQuantity;
|
return Number.isFinite(override) && override > 0 ? Math.round(override) : row.suggestedCutQuantity;
|
||||||
};
|
}, [previewQuantityOverrides]);
|
||||||
|
|
||||||
const selectedPreviewRows = useMemo(() => {
|
const selectedPreviewRows = useMemo(() => {
|
||||||
const selectedIds = new Set(selectedPreviewRowIds);
|
const selectedIds = new Set(selectedPreviewRowIds);
|
||||||
@@ -405,7 +405,7 @@ const Cutting = () => {
|
|||||||
}, [rowsAvailableForOrder, selectedPreviewRowIds]);
|
}, [rowsAvailableForOrder, selectedPreviewRowIds]);
|
||||||
const orderPreviewTotalUnits = useMemo(() => (
|
const orderPreviewTotalUnits = useMemo(() => (
|
||||||
selectedPreviewRows.reduce((total, row) => total + getPreviewQuantity(row), 0)
|
selectedPreviewRows.reduce((total, row) => total + getPreviewQuantity(row), 0)
|
||||||
), [previewQuantityOverrides, selectedPreviewRows]);
|
), [getPreviewQuantity, selectedPreviewRows]);
|
||||||
const selectedResponsibleUser = useMemo(() => (
|
const selectedResponsibleUser = useMemo(() => (
|
||||||
operationalUsers.find((user) => user.id === productionPlanForm.responsibleUserId && user.name === productionPlanForm.responsibleName) || null
|
operationalUsers.find((user) => user.id === productionPlanForm.responsibleUserId && user.name === productionPlanForm.responsibleName) || null
|
||||||
), [operationalUsers, productionPlanForm.responsibleName, productionPlanForm.responsibleUserId]);
|
), [operationalUsers, productionPlanForm.responsibleName, productionPlanForm.responsibleUserId]);
|
||||||
@@ -434,7 +434,7 @@ const Cutting = () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
return Array.from(requirements.values()).sort((a, b) => a.label.localeCompare(b.label, 'pt-BR'));
|
return Array.from(requirements.values()).sort((a, b) => a.label.localeCompare(b.label, 'pt-BR'));
|
||||||
}, [compositionsByProductId, previewQuantityOverrides, selectedPreviewRows]);
|
}, [compositionsByProductId, getPreviewQuantity, selectedPreviewRows]);
|
||||||
|
|
||||||
const selectedLotReservations = useMemo(() => (
|
const selectedLotReservations = useMemo(() => (
|
||||||
selectedMaterialRequirements.flatMap(requirement => {
|
selectedMaterialRequirements.flatMap(requirement => {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import {
|
|||||||
Save,
|
Save,
|
||||||
Search,
|
Search,
|
||||||
Scissors,
|
Scissors,
|
||||||
|
ShieldCheck,
|
||||||
Truck,
|
Truck,
|
||||||
Trash2,
|
Trash2,
|
||||||
Warehouse,
|
Warehouse,
|
||||||
@@ -416,6 +417,7 @@ const SuppliesHub = () => {
|
|||||||
<ModuleCard title="Ordens de compra" description="Formalize pedidos de materiais, fornecedor, prazo e valor antes do recebimento." icon={ClipboardList} to="/supplies/purchase-orders" meta="Criar e acompanhar OCs" />
|
<ModuleCard title="Ordens de compra" description="Formalize pedidos de materiais, fornecedor, prazo e valor antes do recebimento." icon={ClipboardList} to="/supplies/purchase-orders" meta="Criar e acompanhar OCs" />
|
||||||
<ModuleCard title="Planejamento de malha" description="Organize a fila de matéria-prima para abastecer compras e corte." icon={Ruler} to="/supplies/fabric-planning" />
|
<ModuleCard title="Planejamento de malha" description="Organize a fila de matéria-prima para abastecer compras e corte." icon={Ruler} to="/supplies/fabric-planning" />
|
||||||
<ModuleCard title="Transformações e perdas" description="Planeje tecelagem, tinturaria, cores e perda esperada sem alterar o estoque físico." icon={Factory} to="/supplies/material-transformations" />
|
<ModuleCard title="Transformações e perdas" description="Planeje tecelagem, tinturaria, cores e perda esperada sem alterar o estoque físico." icon={Factory} to="/supplies/material-transformations" />
|
||||||
|
<ModuleCard title="Qualidade da malha" description="Acompanhe furos, perdas e origem dos defeitos por lote, posto e OP." icon={ShieldCheck} to="/production-quality" />
|
||||||
<ModuleCard title="Prioridades de estoque" description="Analise reposição, cobertura e itens que precisam de revisão de cadastro." icon={PackageSearch} to="/supplies/current-planning" />
|
<ModuleCard title="Prioridades de estoque" description="Analise reposição, cobertura e itens que precisam de revisão de cadastro." icon={PackageSearch} to="/supplies/current-planning" />
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
Reference in New Issue
Block a user