fix(Inventory): 修復庫存列表批號欄位與新增庫存頁面儲位欄位遺失問題,並還原批號輸入佈局

This commit is contained in:
2026-02-06 17:35:50 +08:00
parent e018b75783
commit f22df90e01
8 changed files with 48 additions and 8 deletions

View File

@@ -98,6 +98,7 @@ class InventoryController extends Controller
'safetyStock' => null, // 批號層級不再有安全庫存
'status' => '正常',
'batchNumber' => $inv->batch_number ?? 'BATCH-' . $inv->id,
'location' => $inv->location,
'expiryDate' => $inv->expiry_date ? $inv->expiry_date->format('Y-m-d') : null,
'lastInboundDate' => $inv->lastIncomingTransaction ? ($inv->lastIncomingTransaction->actual_time ? $inv->lastIncomingTransaction->actual_time->format('Y-m-d') : $inv->lastIncomingTransaction->created_at->format('Y-m-d')) : null,
'lastOutboundDate' => $inv->lastOutgoingTransaction ? ($inv->lastOutgoingTransaction->actual_time ? $inv->lastOutgoingTransaction->actual_time->format('Y-m-d') : $inv->lastOutgoingTransaction->created_at->format('Y-m-d')) : null,
@@ -171,6 +172,7 @@ class InventoryController extends Controller
'items.*.inventoryId' => 'required_if:items.*.batchMode,existing|nullable|exists:inventories,id',
'items.*.originCountry' => 'required_if:items.*.batchMode,new|nullable|string|max:2',
'items.*.expiryDate' => 'nullable|date',
'items.*.location' => 'nullable|string|max:50',
]);
return DB::transaction(function () use ($validated, $warehouse) {
@@ -233,6 +235,7 @@ class InventoryController extends Controller
'quantity' => 0,
'unit_cost' => $item['unit_cost'] ?? 0, // 新增
'total_value' => 0, // 稍後計算
'location' => $item['location'] ?? null,
'arrival_date' => $validated['inboundDate'],
'expiry_date' => $item['expiryDate'] ?? null,
'origin_country' => $originCountry,

View File

@@ -34,7 +34,9 @@ class InventoryDataSheet implements FromArray, WithHeadings, WithTitle, ShouldAu
'商品代號',
'商品名稱',
'數量',
'單位',
'入庫單價',
'儲位/貨道',
'批號',
'產地',
'效期',
@@ -56,14 +58,22 @@ class InventoryInstructionSheet implements FromArray, WithHeadings, WithTitle, S
['商品代號', '擇一輸入', '若條碼未填寫,系統會依據代號匹配商品'],
['商品名稱', '選填', '僅供對照參考,匯入時系統會自動忽略此欄位內容'],
['數量', '必填', '入庫的商品數量,須為大於 0 的數字'],
['單位', '必填', '單位 (如:個、件)'],
['入庫單價', '選填', '未填寫時將預設使用商品的「採購成本價」'],
['儲位/貨道', '選填', '一般倉庫請填寫「儲位(位址)」,販賣機倉庫請填寫「貨道編號」(如: A1)'],
['批號', '選填', '如需批次控管請填寫,若留空系統會自動標記為 "NO-BATCH"'],
['產地', '選填', '商品的生產地資訊 (如TW)'],
['效期', '選填', '格式請務必使用 YYYY-MM-DD (例如: 2026-12-31)'],
['', '', ''],
['匹配規則說明', '', '1. 系統會優先比對「商品條碼」。'],
['', '', '2. 若條碼欄位為空,則嘗試比對「商品代號」。'],
['', '', '3. 若上述兩者皆無法匹配到既有商品,該列資料將匯入失敗。'],
['倉庫類型參考', '', '系統支援以下倉庫性質:'],
['標準倉', '', '一般總倉、儲備倉'],
['生產倉', '', '加工廠、中央廚房、原材料存放處'],
['門市倉', '', '前台通路、店舖銷售現場'],
['販賣機', '', 'IoT 自動販賣機設備,建議搭配「貨道」填寫'],
['', '', ''],
['匹配與匯入規則', '', '1. 系統會優先比對「商品條碼」,其次為「商品代號」。'],
['', '', '2. 庫存將匯入至您在匯入前於系統介面所選擇的目標倉庫。'],
['', '', '3. 若需區分不同貨道或批次,請分行填寫。'],
];
}

View File

@@ -55,18 +55,20 @@ class InventoryImport implements ToModel, WithHeadingRow, WithValidation, WithMa
$quantity = (float) $row['數量'];
$unitCost = isset($row['入庫單價']) ? (float) $row['入庫單價'] : ($product->cost_price ?? 0);
$location = $row['儲位/貨道'] ?? null;
// 批號邏輯:若 Excel 留空則使用 NO-BATCH
$batchNumber = !empty($row['批號']) ? $row['批號'] : 'NO-BATCH';
$originCountry = $row['產地'] ?? 'TW';
$expiryDate = !empty($row['效期']) ? $row['效期'] : null;
return DB::transaction(function () use ($product, $quantity, $unitCost, $batchNumber, $originCountry, $expiryDate) {
return DB::transaction(function () use ($product, $quantity, $unitCost, $location, $batchNumber, $originCountry, $expiryDate) {
// 使用與 InventoryController 相同的 firstOrNew 邏輯
$inventory = $this->warehouse->inventories()->withTrashed()->firstOrNew(
[
'product_id' => $product->id,
'batch_number' => $batchNumber
'batch_number' => $batchNumber,
'location' => $location, // 加入儲位/貨道作為區分關鍵字
],
[
'quantity' => 0,
@@ -114,7 +116,10 @@ class InventoryImport implements ToModel, WithHeadingRow, WithValidation, WithMa
'商品條碼' => ['nullable', 'string'],
'商品代號' => ['nullable', 'string'],
'數量' => ['required', 'numeric', 'min:0.01'],
'單位' => ['required', 'string'],
'入庫單價' => ['nullable', 'numeric', 'min:0'],
'儲位/貨道' => ['nullable', 'string', 'max:50'],
'批號' => ['nullable', 'string'],
'效期' => ['nullable', 'date'],
'產地' => ['nullable', 'string', 'max:2'],
];