feat(inventory): 支援庫存新增不使用批號模式與自動累加邏輯
This commit is contained in:
@@ -548,7 +548,7 @@ export default function AddInventoryPage({ warehouse, products }: Props) {
|
||||
<TableCell>
|
||||
<div className="space-y-2">
|
||||
<SearchableSelect
|
||||
value={item.batchMode === 'new' ? 'new_batch' : (item.inventoryId || "")}
|
||||
value={item.batchMode === 'none' ? 'no_batch' : (item.batchMode === 'new' ? 'new_batch' : (item.inventoryId || ""))}
|
||||
onValueChange={(value) => {
|
||||
if (value === 'new_batch') {
|
||||
handleUpdateItem(item.tempId, {
|
||||
@@ -557,6 +557,15 @@ export default function AddInventoryPage({ warehouse, products }: Props) {
|
||||
originCountry: 'TW',
|
||||
expiryDate: undefined
|
||||
});
|
||||
} else if (value === 'no_batch') {
|
||||
// 嘗試匹配現有的 NO-BATCH 紀錄
|
||||
const existingNoBatch = (batchesCache[item.productId]?.batches || []).find(b => b.batchNumber === 'NO-BATCH');
|
||||
handleUpdateItem(item.tempId, {
|
||||
batchMode: 'none',
|
||||
inventoryId: existingNoBatch?.inventoryId || undefined,
|
||||
originCountry: 'TW',
|
||||
expiryDate: undefined
|
||||
});
|
||||
} else {
|
||||
const selectedBatch = (batchesCache[item.productId]?.batches || []).find(b => b.inventoryId === value);
|
||||
handleUpdateItem(item.tempId, {
|
||||
@@ -568,9 +577,10 @@ export default function AddInventoryPage({ warehouse, products }: Props) {
|
||||
}
|
||||
}}
|
||||
options={[
|
||||
{ label: "📦 不使用批號 (自動累加)", value: "no_batch" },
|
||||
{ label: "+ 建立新批號", value: "new_batch" },
|
||||
...(batchesCache[item.productId]?.batches || []).map(b => ({
|
||||
label: `${b.batchNumber} - 庫存: ${b.quantity}`,
|
||||
label: `${b.batchNumber === 'NO-BATCH' ? '(無批號紀錄)' : b.batchNumber} - 庫存: ${b.quantity}`,
|
||||
value: b.inventoryId
|
||||
}))
|
||||
]}
|
||||
@@ -582,50 +592,55 @@ export default function AddInventoryPage({ warehouse, products }: Props) {
|
||||
{errors[`item-${index}-batch`]}
|
||||
</p>
|
||||
)}
|
||||
|
||||
{item.batchMode === 'new' && (
|
||||
<>
|
||||
<div className="flex items-center gap-2 mt-2">
|
||||
<div className="flex-1">
|
||||
<Input
|
||||
value={item.originCountry || ""}
|
||||
onChange={(e) => {
|
||||
const val = e.target.value.toUpperCase().slice(0, 2);
|
||||
handleUpdateItem(item.tempId, { originCountry: val });
|
||||
}}
|
||||
maxLength={2}
|
||||
placeholder="產地"
|
||||
className="h-8 text-xs text-center border-gray-300"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex-[3] text-xs bg-primary-50/50 text-primary-main px-2 py-1 rounded border border-primary-200/50 font-mono overflow-hidden whitespace-nowrap">
|
||||
{getBatchPreview(item.productId, product?.code, item.originCountry || 'TW', inboundDate)}
|
||||
</div>
|
||||
<div className="flex items-center gap-2 mt-2">
|
||||
<div className="flex-1">
|
||||
<Input
|
||||
value={item.originCountry || ""}
|
||||
onChange={(e) => {
|
||||
const val = e.target.value.toUpperCase().slice(0, 2);
|
||||
handleUpdateItem(item.tempId, { originCountry: val });
|
||||
}}
|
||||
maxLength={2}
|
||||
placeholder="產地"
|
||||
className="h-8 text-xs text-center border-gray-300"
|
||||
/>
|
||||
</div>
|
||||
{/* 新增效期輸入 (在新增批號模式下) */}
|
||||
<div className="mt-2 flex items-center gap-2">
|
||||
<span className="text-xs text-gray-500 whitespace-nowrap">效期:</span>
|
||||
<div className="relative flex-1">
|
||||
<Calendar className="absolute left-2.5 top-2.5 h-3.5 w-3.5 text-gray-400 pointer-events-none" />
|
||||
<Input
|
||||
type="date"
|
||||
value={item.expiryDate || ""}
|
||||
onChange={(e) =>
|
||||
handleUpdateItem(item.tempId, {
|
||||
expiryDate: e.target.value,
|
||||
})
|
||||
}
|
||||
className="h-8 pl-8 text-xs border-gray-300 w-full"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex-[3] text-xs bg-primary-50/50 text-primary-main px-2 py-1 rounded border border-primary-200/50 font-mono overflow-hidden whitespace-nowrap">
|
||||
{getBatchPreview(item.productId, product?.code, item.originCountry || 'TW', inboundDate)}
|
||||
</div>
|
||||
</>
|
||||
</div>
|
||||
)}
|
||||
{/* 新增效期輸入 (僅在建立新批號模式下) */}
|
||||
{item.batchMode === 'new' && (
|
||||
<div className="mt-2 flex items-center gap-2">
|
||||
<span className="text-xs text-gray-500 whitespace-nowrap">效期:</span>
|
||||
<div className="relative flex-1">
|
||||
<Calendar className="absolute left-2.5 top-2.5 h-3.5 w-3.5 text-gray-400 pointer-events-none" />
|
||||
<Input
|
||||
type="date"
|
||||
value={item.expiryDate || ""}
|
||||
onChange={(e) =>
|
||||
handleUpdateItem(item.tempId, {
|
||||
expiryDate: e.target.value,
|
||||
})
|
||||
}
|
||||
className="h-8 pl-8 text-xs border-gray-300 w-full"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{item.batchMode === 'none' && (
|
||||
<div className="mt-1 px-2 py-1 bg-amber-50 text-amber-700 text-[10px] rounded border border-amber-100 flex items-center gap-1">
|
||||
<span className="shrink-0 font-bold">INFO</span>
|
||||
系統將自動累加至該商品的通用庫存紀錄
|
||||
</div>
|
||||
)}
|
||||
|
||||
{item.batchMode === 'existing' && item.inventoryId && (
|
||||
<div className="flex flax-col gap-1 mt-1">
|
||||
<div className="text-xs text-gray-500 font-mono">
|
||||
效期: {item.expiryDate || '未設定'}
|
||||
效期: {item.expiryDate || '無效期紀錄'}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -174,7 +174,7 @@ export interface InboundItem {
|
||||
largeUnit?: string;
|
||||
conversionRate?: number;
|
||||
selectedUnit?: 'base' | 'large';
|
||||
batchMode?: 'existing' | 'new'; // 批號模式
|
||||
batchMode?: 'existing' | 'new' | 'none'; // 批號模式
|
||||
inventoryId?: string; // 選擇現有批號時的 ID
|
||||
batchNumber?: string;
|
||||
originCountry?: string; // 新增產地
|
||||
|
||||
Reference in New Issue
Block a user