feat: 修正庫存與撥補單邏輯並整合文件
All checks were successful
Koori-ERP-Deploy-System / deploy-demo (push) Successful in 53s
Koori-ERP-Deploy-System / deploy-production (push) Has been skipped

1. 修復倉庫統計數據加總與樣式。
2. 修正可用庫存計算邏輯(排除不可銷售倉庫)。
3. 撥補單商品列表加入批號與效期顯示。
4. 修正撥補單儲存邏輯以支援精確批號轉移。
5. 整合 FEATURES.md 至 README.md。
This commit is contained in:
2026-01-26 14:59:24 +08:00
parent b0848a6bb8
commit 106de4e945
81 changed files with 4118 additions and 1023 deletions

View File

@@ -52,18 +52,18 @@ interface InventoryOption {
}
interface BomItem {
// Backend required
// 後端必填
inventory_id: string;
quantity_used: string;
unit_id: string;
// UI State
ui_warehouse_id: string; // Source Warehouse
// UI 狀態
ui_warehouse_id: string; // 來源倉庫
ui_product_id: string;
ui_input_quantity: string;
ui_selected_unit: 'base' | 'large';
// UI Helpers / Cache
// UI 輔助 / 快取
ui_product_name?: string;
ui_batch_number?: string;
ui_available_qty?: number;
@@ -134,13 +134,13 @@ export default function ProductionEdit({ productionOrder, products, warehouses }
const [selectedWarehouse, setSelectedWarehouse] = useState<string>(
productionOrder.warehouse_id ? String(productionOrder.warehouse_id) : ""
); // Output Warehouse
); // 產出倉庫
// Cache map: warehouse_id -> inventories
// 快取對照表:warehouse_id -> inventories
const [inventoryMap, setInventoryMap] = useState<Record<string, InventoryOption[]>>({});
const [loadingWarehouses, setLoadingWareStates] = useState<Record<string, boolean>>({});
// Helper to fetch warehouse data
// 獲取倉庫資料的輔助函式
const fetchWarehouseInventory = async (warehouseId: string) => {
if (!warehouseId || inventoryMap[warehouseId] || loadingWarehouses[warehouseId]) return;
@@ -168,7 +168,7 @@ export default function ProductionEdit({ productionOrder, products, warehouses }
ui_input_quantity: String(item.quantity_used), // 假設已存的資料是基本單位
ui_selected_unit: 'base',
// UI Helpers
// UI 輔助
ui_product_name: item.inventory?.product?.name,
ui_batch_number: item.inventory?.batch_number,
ui_available_qty: item.inventory?.quantity,
@@ -600,7 +600,7 @@ export default function ProductionEdit({ productionOrder, products, warehouses }
currentOptions.map(inv => [inv.product_id, { label: inv.product_name, value: String(inv.product_id) }])
).values());
// Fallback for initial state before fetch
// 在獲取前初始狀態的備案
const displayProductOptions = uniqueProductOptions.length > 0 ? uniqueProductOptions : (item.ui_product_name ? [{ label: item.ui_product_name, value: item.ui_product_id }] : []);
const batchOptions = currentOptions
@@ -610,7 +610,7 @@ export default function ProductionEdit({ productionOrder, products, warehouses }
value: String(inv.id)
}));
// Fallback
// 備案
const displayBatchOptions = batchOptions.length > 0 ? batchOptions : (item.inventory_id && item.ui_batch_number ? [{ label: item.ui_batch_number, value: item.inventory_id }] : []);