diff --git a/src/components/InventorySearch/InventoryLotLineTable.tsx b/src/components/InventorySearch/InventoryLotLineTable.tsx index 14d0ba4..551f1cf 100644 --- a/src/components/InventorySearch/InventoryLotLineTable.tsx +++ b/src/components/InventorySearch/InventoryLotLineTable.tsx @@ -16,6 +16,7 @@ import { Autocomplete } from "@mui/material"; import { WarehouseResult } from "@/app/api/warehouse"; import { fetchWarehouseListClient } from "@/app/api/warehouse/client"; import { createStockTransfer } from "@/app/api/inventory/actions"; +import { msg, msgError } from "@/components/Swal/CustomAlerts"; interface Props { inventoryLotLines: InventoryLotLineResult[] | null; @@ -23,9 +24,10 @@ interface Props { pagingController: typeof defaultPagingController; totalCount: number; inventory: InventoryResult | null; + onStockTransferSuccess?: () => void | Promise; } -const InventoryLotLineTable: React.FC = ({ inventoryLotLines, pagingController, setPagingController, totalCount, inventory }) => { +const InventoryLotLineTable: React.FC = ({ inventoryLotLines, pagingController, setPagingController, totalCount, inventory, onStockTransferSuccess }) => { const { t } = useTranslation(["inventory"]); const { setIsUploading } = useUploadContext(); const [stockTransferModalOpen, setStockTransferModalOpen] = useState(false); @@ -44,6 +46,10 @@ const InventoryLotLineTable: React.FC = ({ inventoryLotLines, pagingContr } }, [stockTransferModalOpen]); + const availableLotLines = useMemo( + () => (inventoryLotLines ?? []).filter((line) => line.status?.toLowerCase() === "available"), + [inventoryLotLines] + ); const originalQty = selectedLotLine?.availableQty || 0; const remainingQty = originalQty - qtyToBeTransferred; @@ -67,7 +73,7 @@ const InventoryLotLineTable: React.FC = ({ inventoryLotLines, pagingContr setStartLocation(lotLine.warehouse.code || ""); setTargetLocation(null); setTargetLocationInput(""); - setQtyToBeTransferred(0); + setQtyToBeTransferred(lotLine.availableQty >= 1 ? 1 : 0); }, [], ); @@ -197,7 +203,7 @@ const InventoryLotLineTable: React.FC = ({ inventoryLotLines, pagingContr }, []); const handleSubmitStockTransfer = useCallback(async () => { - if (!selectedLotLine || !targetLocation || qtyToBeTransferred <= 0) { + if (!selectedLotLine || !targetLocation || qtyToBeTransferred < 1) { return; } @@ -213,26 +219,24 @@ const InventoryLotLineTable: React.FC = ({ inventoryLotLines, pagingContr const response = await createStockTransfer(request); if (response && response.type === "success") { - alert(t("Stock transfer successful")); + msg(t("Stock transfer successful")); handleCloseStockTransferModal(); - - // Refresh the inventory lot lines list - window.location.reload(); // Or use your preferred refresh method + await onStockTransferSuccess?.(); } else { throw new Error(response?.message || t("Failed to transfer stock")); } } catch (error: any) { console.error("Error transferring stock:", error); - alert(error?.message || t("Failed to transfer stock. Please try again.")); + msgError(error?.message || t("Failed to transfer stock. Please try again.")); } finally { setIsUploading(false); } - }, [selectedLotLine, targetLocation, qtyToBeTransferred, handleCloseStockTransferModal, setIsUploading, t]); +}, [selectedLotLine, targetLocation, qtyToBeTransferred, handleCloseStockTransferModal, setIsUploading, t, onStockTransferSuccess]); return <> {inventory ? `${t("Item selected")}: ${inventory.itemCode} | ${inventory.itemName} (${t(inventory.itemType)})` : t("No items are selected yet.")} - items={inventoryLotLines ?? []} + items={availableLotLines} columns={columns} pagingController={pagingController} setPagingController={setPagingController} @@ -366,10 +370,11 @@ const InventoryLotLineTable: React.FC = ({ inventoryLotLines, pagingContr value={qtyToBeTransferred} onChange={(e) => { const value = parseInt(e.target.value) || 0; + const minValue = 1; const maxValue = Math.max(0, originalQty); - setQtyToBeTransferred(Math.min(Math.max(0, value), maxValue)); + setQtyToBeTransferred(Math.min(Math.max(minValue, value), maxValue)); }} - inputProps={{ min: 0, max: originalQty, step: 1 }} + inputProps={{ min: 1, max: originalQty, step: 1 }} InputLabelProps={{ shrink: true, sx: { fontSize: "0.9375rem" }, @@ -414,7 +419,7 @@ const InventoryLotLineTable: React.FC = ({ inventoryLotLines, pagingContr fontSize: '0.9375rem', }} onClick={handleSubmitStockTransfer} - disabled={!selectedLotLine || !targetLocation || qtyToBeTransferred <= 0 || qtyToBeTransferred > originalQty} + disabled={!selectedLotLine || !targetLocation || qtyToBeTransferred < 1 || qtyToBeTransferred > originalQty} > {t("Submit")} diff --git a/src/components/InventorySearch/InventorySearch.tsx b/src/components/InventorySearch/InventorySearch.tsx index 4110b8f..dcb4b2e 100644 --- a/src/components/InventorySearch/InventorySearch.tsx +++ b/src/components/InventorySearch/InventorySearch.tsx @@ -248,6 +248,9 @@ const InventorySearch: React.FC = ({ inventories }) => { setPagingController={setInventoryLotLinesPagingController} totalCount={inventoryLotLinesTotalCount} inventory={selectedInventory} + onStockTransferSuccess={() => + refetchInventoryLotLineData(selectedInventory?.itemId ?? null, "search", inventoryLotLinesPagingController) + } /> ); diff --git a/src/components/Swal/CustomAlerts.tsx b/src/components/Swal/CustomAlerts.tsx index 6596837..823f879 100644 --- a/src/components/Swal/CustomAlerts.tsx +++ b/src/components/Swal/CustomAlerts.tsx @@ -28,6 +28,26 @@ export const msg = (title: SweetAlertTitle) => { }); }; +export const msgError = (title: SweetAlertTitle) => { + Swal.mixin({ + toast: true, + position: "bottom-end", + showConfirmButton: false, + timer: 3000, + timerProgressBar: true, + didOpen: (toast) => { + toast.onmouseenter = Swal.stopTimer; + toast.onmouseleave = Swal.resumeTimer; + }, + customClass: { + container: 'swal2-custom-zindex', + }, + }).fire({ + icon: "error", + title: title, + }); +}; + export const popup = (options: SweetAlertOptions) => { Swal.fire(options); }; diff --git a/src/i18n/zh/inventory.json b/src/i18n/zh/inventory.json index 7d7f502..51d32a8 100644 --- a/src/i18n/zh/inventory.json +++ b/src/i18n/zh/inventory.json @@ -203,6 +203,10 @@ "End Date": "結束日期", "Loading": "加載中", "adj": "調整", - "nor": "正常" + "nor": "正常", + + "Stock transfer successful": "庫存調撥成功", + "Failed to transfer stock": "庫存調撥失敗", + "Failed to transfer stock. Please try again.": "轉倉失敗,請重試。" }