/** * 庫存計算相關工具函式 */ import { WarehouseInventory, WarehouseStats, SafetyStockSetting, SafetyStockStatus } from "../types/warehouse"; /** * 計算倉庫的總庫存數量 */ export const calculateTotalQuantity = ( inventories: WarehouseInventory[], warehouseId: string ): number => { return inventories .filter((inv) => inv.warehouseId === warehouseId) .reduce((sum, inv) => sum + inv.quantity, 0); }; /** * 按商品分組計算總庫存 */ export const calculateProductTotalStock = ( inventories: WarehouseInventory[], productId: string ): number => { return inventories .filter((inv) => inv.productId === productId) .reduce((sum, inv) => sum + inv.quantity, 0); }; /** * 計算安全庫存狀態 */ export const getSafetyStockStatus = ( currentStock: number, safetyStock: number | null | undefined ): SafetyStockStatus => { if (!safetyStock || safetyStock === 0) return "正常"; const ratio = currentStock / safetyStock; if (ratio >= 1.2) return "正常"; if (ratio >= 1.0) return "接近"; return "低於"; }; /** * 檢查商品是否低於安全庫存 */ export const isProductLowStock = ( inventories: WarehouseInventory[], productId: string, safetyStockSettings: SafetyStockSetting[] ): boolean => { const setting = safetyStockSettings.find((s) => s.productId === productId); if (!setting) return false; const totalStock = calculateProductTotalStock(inventories, productId); return totalStock < setting.safetyStock; }; /** * 計算低庫存警告數量(按商品計算) */ export const calculateLowStockCount = ( inventories: WarehouseInventory[], warehouseId: string, safetyStockSettings: SafetyStockSetting[] ): number => { // 取得該倉庫的所有庫存 const warehouseInventories = inventories.filter( (inv) => String(inv.warehouseId) === String(warehouseId) ); // 取得該倉庫的安全庫存設定 const warehouseSettings = safetyStockSettings.filter( (s) => String(s.warehouseId) === String(warehouseId) ); // 計算有多少商品低於安全庫存 let lowStockCount = 0; warehouseSettings.forEach((setting) => { // 找出該設定對應的商品庫存 // 注意:這裡假設一個商品在同一個倉庫只有一種庫存紀錄 (warehouse_inventory table) // 如果有批號區分,則需要加總所有該商品的數量 const productTotalStock = warehouseInventories .filter(inv => String(inv.productId) === String(setting.productId)) .reduce((sum, inv) => sum + inv.quantity, 0); // 只有當安全庫存設定存在時才進行判斷 (後端已過濾掉 null) // 若設定為 0,則表示允許庫存為 0,不會觸發警告 (除非庫存為負) if (productTotalStock < setting.safetyStock) { lowStockCount++; } }); return lowStockCount; }; /** * 計算待撥補需求數量(按商品計算) */ export const calculateReplenishmentNeeded = ( inventories: WarehouseInventory[], warehouseId: string, safetyStockSettings: SafetyStockSetting[] ): number => { // 取得該倉庫的所有庫存 const warehouseInventories = inventories.filter( (inv) => inv.warehouseId === warehouseId ); // 取得該倉庫的安全庫存設定 const warehouseSettings = safetyStockSettings.filter( (s) => s.warehouseId === warehouseId ); // 計算需要撥補的總量 let replenishmentNeeded = 0; warehouseSettings.forEach((setting) => { const productTotalStock = calculateProductTotalStock( warehouseInventories, setting.productId ); if (productTotalStock < setting.safetyStock) { replenishmentNeeded += setting.safetyStock - productTotalStock; } }); return replenishmentNeeded; }; /** * 計算倉庫統計資訊 */ export const calculateWarehouseStats = ( inventories: WarehouseInventory[], warehouseId: string, safetyStockSettings: SafetyStockSetting[] ): WarehouseStats => { return { totalQuantity: calculateTotalQuantity(inventories, warehouseId), lowStockCount: calculateLowStockCount(inventories, warehouseId, safetyStockSettings), replenishmentNeeded: calculateReplenishmentNeeded(inventories, warehouseId, safetyStockSettings), }; }; /** * 檢查倉庫是否有庫存警告 */ export const hasWarehouseWarning = ( inventories: WarehouseInventory[], warehouseId: string, safetyStockSettings: SafetyStockSetting[] ): boolean => { return calculateLowStockCount(inventories, warehouseId, safetyStockSettings) > 0; }; /** * 過濾倉庫的庫存 */ export const filterWarehouseInventories = ( inventories: WarehouseInventory[], warehouseId: string ): WarehouseInventory[] => { return inventories.filter((inv) => inv.warehouseId === warehouseId); };