生產工單BOM以及批號完善
This commit is contained in:
@@ -3,7 +3,7 @@ import { ArrowLeft, PackagePlus, AlertTriangle, Shield, Boxes } from "lucide-rea
|
||||
import { Button } from "@/Components/ui/button";
|
||||
import AuthenticatedLayout from "@/Layouts/AuthenticatedLayout";
|
||||
import { Head, Link, router } from "@inertiajs/react";
|
||||
import { Warehouse, WarehouseInventory, SafetyStockSetting, Product } from "@/types/warehouse";
|
||||
import { Warehouse, GroupedInventory, SafetyStockSetting, Product } from "@/types/warehouse";
|
||||
import InventoryToolbar from "@/Components/Warehouse/Inventory/InventoryToolbar";
|
||||
import InventoryTable from "@/Components/Warehouse/Inventory/InventoryTable";
|
||||
import { calculateLowStockCount } from "@/utils/inventory";
|
||||
@@ -24,7 +24,7 @@ import { Can } from "@/Components/Permission/Can";
|
||||
// 庫存頁面 Props
|
||||
interface Props {
|
||||
warehouse: Warehouse;
|
||||
inventories: WarehouseInventory[];
|
||||
inventories: GroupedInventory[];
|
||||
safetyStockSettings: SafetyStockSetting[];
|
||||
availableProducts: Product[];
|
||||
}
|
||||
@@ -41,17 +41,17 @@ export default function WarehouseInventoryPage({
|
||||
|
||||
// 篩選庫存列表
|
||||
const filteredInventories = useMemo(() => {
|
||||
return inventories.filter((item) => {
|
||||
// 搜尋條件:匹配商品名稱、編號或批號
|
||||
return inventories.filter((group) => {
|
||||
// 搜尋條件:匹配商品名稱、編號 或 該商品下任一批號
|
||||
const matchesSearch = !searchTerm ||
|
||||
item.productName.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||
(item.productCode && item.productCode.toLowerCase().includes(searchTerm.toLowerCase())) ||
|
||||
item.batchNumber.toLowerCase().includes(searchTerm.toLowerCase());
|
||||
group.productName.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||
(group.productCode && group.productCode.toLowerCase().includes(searchTerm.toLowerCase())) ||
|
||||
group.batches.some(b => b.batchNumber.toLowerCase().includes(searchTerm.toLowerCase()));
|
||||
|
||||
// 類型篩選 (需要比對 availableProducts 找到類型)
|
||||
let matchesType = true;
|
||||
if (typeFilter !== "all") {
|
||||
const product = availableProducts.find((p) => p.id === item.productId);
|
||||
const product = availableProducts.find((p) => p.id === group.productId);
|
||||
matchesType = product?.type === typeFilter;
|
||||
}
|
||||
|
||||
@@ -60,13 +60,24 @@ export default function WarehouseInventoryPage({
|
||||
}, [inventories, searchTerm, typeFilter, availableProducts]);
|
||||
|
||||
// 計算統計資訊
|
||||
const lowStockItems = calculateLowStockCount(inventories, warehouse.id, safetyStockSettings);
|
||||
const lowStockItems = useMemo(() => {
|
||||
const allBatches = inventories.flatMap(g => g.batches);
|
||||
return calculateLowStockCount(allBatches, warehouse.id, safetyStockSettings);
|
||||
}, [inventories, warehouse.id, safetyStockSettings]);
|
||||
|
||||
// 導航至流動紀錄頁
|
||||
const handleView = (inventoryId: string) => {
|
||||
router.visit(route('warehouses.inventory.history', { warehouse: warehouse.id, inventoryId: inventoryId }));
|
||||
};
|
||||
|
||||
// 導航至商品層級流動紀錄頁(顯示該商品所有批號的流水帳)
|
||||
const handleViewProduct = (productId: string) => {
|
||||
router.visit(route('warehouses.inventory.history', {
|
||||
warehouse: warehouse.id,
|
||||
productId: productId
|
||||
}));
|
||||
};
|
||||
|
||||
|
||||
const confirmDelete = (inventoryId: string) => {
|
||||
setDeleteId(inventoryId);
|
||||
@@ -90,6 +101,17 @@ export default function WarehouseInventoryPage({
|
||||
});
|
||||
};
|
||||
|
||||
const handleAdjust = (batchId: string, data: { operation: string; quantity: number; reason: string }) => {
|
||||
router.put(route("warehouses.inventory.update", { warehouse: warehouse.id, inventoryId: batchId }), data, {
|
||||
onSuccess: () => {
|
||||
toast.success("庫存已更新");
|
||||
},
|
||||
onError: () => {
|
||||
toast.error("庫存更新失敗");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<AuthenticatedLayout breadcrumbs={getInventoryBreadcrumbs(warehouse.id, warehouse.name)}>
|
||||
<Head title={`庫存管理 - ${warehouse.name}`} />
|
||||
@@ -158,7 +180,7 @@ export default function WarehouseInventoryPage({
|
||||
</div>
|
||||
|
||||
{/* 篩選工具列 */}
|
||||
<div className="mb-6 bg-white rounded-lg shadow-sm border p-4">
|
||||
<div className="mb-6">
|
||||
<InventoryToolbar
|
||||
searchTerm={searchTerm}
|
||||
onSearchChange={setSearchTerm}
|
||||
@@ -173,6 +195,8 @@ export default function WarehouseInventoryPage({
|
||||
inventories={filteredInventories}
|
||||
onView={handleView}
|
||||
onDelete={confirmDelete}
|
||||
onAdjust={handleAdjust}
|
||||
onViewProduct={handleViewProduct}
|
||||
/>
|
||||
</div>
|
||||
<AlertDialog open={!!deleteId} onOpenChange={(open) => !open && setDeleteId(null)}>
|
||||
|
||||
Reference in New Issue
Block a user