|
|
@@ -16,6 +16,7 @@ import { Autocomplete } from "@mui/material"; |
|
|
import { WarehouseResult } from "@/app/api/warehouse"; |
|
|
import { WarehouseResult } from "@/app/api/warehouse"; |
|
|
import { fetchWarehouseListClient } from "@/app/api/warehouse/client"; |
|
|
import { fetchWarehouseListClient } from "@/app/api/warehouse/client"; |
|
|
import { createStockTransfer } from "@/app/api/inventory/actions"; |
|
|
import { createStockTransfer } from "@/app/api/inventory/actions"; |
|
|
|
|
|
import { msg, msgError } from "@/components/Swal/CustomAlerts"; |
|
|
|
|
|
|
|
|
interface Props { |
|
|
interface Props { |
|
|
inventoryLotLines: InventoryLotLineResult[] | null; |
|
|
inventoryLotLines: InventoryLotLineResult[] | null; |
|
|
@@ -23,9 +24,10 @@ interface Props { |
|
|
pagingController: typeof defaultPagingController; |
|
|
pagingController: typeof defaultPagingController; |
|
|
totalCount: number; |
|
|
totalCount: number; |
|
|
inventory: InventoryResult | null; |
|
|
inventory: InventoryResult | null; |
|
|
|
|
|
onStockTransferSuccess?: () => void | Promise<void>; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const InventoryLotLineTable: React.FC<Props> = ({ inventoryLotLines, pagingController, setPagingController, totalCount, inventory }) => { |
|
|
|
|
|
|
|
|
const InventoryLotLineTable: React.FC<Props> = ({ inventoryLotLines, pagingController, setPagingController, totalCount, inventory, onStockTransferSuccess }) => { |
|
|
const { t } = useTranslation(["inventory"]); |
|
|
const { t } = useTranslation(["inventory"]); |
|
|
const { setIsUploading } = useUploadContext(); |
|
|
const { setIsUploading } = useUploadContext(); |
|
|
const [stockTransferModalOpen, setStockTransferModalOpen] = useState(false); |
|
|
const [stockTransferModalOpen, setStockTransferModalOpen] = useState(false); |
|
|
@@ -44,6 +46,10 @@ const InventoryLotLineTable: React.FC<Props> = ({ inventoryLotLines, pagingContr |
|
|
} |
|
|
} |
|
|
}, [stockTransferModalOpen]); |
|
|
}, [stockTransferModalOpen]); |
|
|
|
|
|
|
|
|
|
|
|
const availableLotLines = useMemo( |
|
|
|
|
|
() => (inventoryLotLines ?? []).filter((line) => line.status?.toLowerCase() === "available"), |
|
|
|
|
|
[inventoryLotLines] |
|
|
|
|
|
); |
|
|
const originalQty = selectedLotLine?.availableQty || 0; |
|
|
const originalQty = selectedLotLine?.availableQty || 0; |
|
|
const remainingQty = originalQty - qtyToBeTransferred; |
|
|
const remainingQty = originalQty - qtyToBeTransferred; |
|
|
|
|
|
|
|
|
@@ -67,7 +73,7 @@ const InventoryLotLineTable: React.FC<Props> = ({ inventoryLotLines, pagingContr |
|
|
setStartLocation(lotLine.warehouse.code || ""); |
|
|
setStartLocation(lotLine.warehouse.code || ""); |
|
|
setTargetLocation(null); |
|
|
setTargetLocation(null); |
|
|
setTargetLocationInput(""); |
|
|
setTargetLocationInput(""); |
|
|
setQtyToBeTransferred(0); |
|
|
|
|
|
|
|
|
setQtyToBeTransferred(lotLine.availableQty >= 1 ? 1 : 0); |
|
|
}, |
|
|
}, |
|
|
[], |
|
|
[], |
|
|
); |
|
|
); |
|
|
@@ -197,7 +203,7 @@ const InventoryLotLineTable: React.FC<Props> = ({ inventoryLotLines, pagingContr |
|
|
}, []); |
|
|
}, []); |
|
|
|
|
|
|
|
|
const handleSubmitStockTransfer = useCallback(async () => { |
|
|
const handleSubmitStockTransfer = useCallback(async () => { |
|
|
if (!selectedLotLine || !targetLocation || qtyToBeTransferred <= 0) { |
|
|
|
|
|
|
|
|
if (!selectedLotLine || !targetLocation || qtyToBeTransferred < 1) { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@@ -213,26 +219,24 @@ const InventoryLotLineTable: React.FC<Props> = ({ inventoryLotLines, pagingContr |
|
|
const response = await createStockTransfer(request); |
|
|
const response = await createStockTransfer(request); |
|
|
|
|
|
|
|
|
if (response && response.type === "success") { |
|
|
if (response && response.type === "success") { |
|
|
alert(t("Stock transfer successful")); |
|
|
|
|
|
|
|
|
msg(t("Stock transfer successful")); |
|
|
handleCloseStockTransferModal(); |
|
|
handleCloseStockTransferModal(); |
|
|
|
|
|
|
|
|
// Refresh the inventory lot lines list |
|
|
|
|
|
window.location.reload(); // Or use your preferred refresh method |
|
|
|
|
|
|
|
|
await onStockTransferSuccess?.(); |
|
|
} else { |
|
|
} else { |
|
|
throw new Error(response?.message || t("Failed to transfer stock")); |
|
|
throw new Error(response?.message || t("Failed to transfer stock")); |
|
|
} |
|
|
} |
|
|
} catch (error: any) { |
|
|
} catch (error: any) { |
|
|
console.error("Error transferring stock:", error); |
|
|
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 { |
|
|
} finally { |
|
|
setIsUploading(false); |
|
|
setIsUploading(false); |
|
|
} |
|
|
} |
|
|
}, [selectedLotLine, targetLocation, qtyToBeTransferred, handleCloseStockTransferModal, setIsUploading, t]); |
|
|
|
|
|
|
|
|
}, [selectedLotLine, targetLocation, qtyToBeTransferred, handleCloseStockTransferModal, setIsUploading, t, onStockTransferSuccess]); |
|
|
|
|
|
|
|
|
return <> |
|
|
return <> |
|
|
<Typography variant="h6">{inventory ? `${t("Item selected")}: ${inventory.itemCode} | ${inventory.itemName} (${t(inventory.itemType)})` : t("No items are selected yet.")}</Typography> |
|
|
<Typography variant="h6">{inventory ? `${t("Item selected")}: ${inventory.itemCode} | ${inventory.itemName} (${t(inventory.itemType)})` : t("No items are selected yet.")}</Typography> |
|
|
<SearchResults<InventoryLotLineResult> |
|
|
<SearchResults<InventoryLotLineResult> |
|
|
items={inventoryLotLines ?? []} |
|
|
|
|
|
|
|
|
items={availableLotLines} |
|
|
columns={columns} |
|
|
columns={columns} |
|
|
pagingController={pagingController} |
|
|
pagingController={pagingController} |
|
|
setPagingController={setPagingController} |
|
|
setPagingController={setPagingController} |
|
|
@@ -366,10 +370,11 @@ const InventoryLotLineTable: React.FC<Props> = ({ inventoryLotLines, pagingContr |
|
|
value={qtyToBeTransferred} |
|
|
value={qtyToBeTransferred} |
|
|
onChange={(e) => { |
|
|
onChange={(e) => { |
|
|
const value = parseInt(e.target.value) || 0; |
|
|
const value = parseInt(e.target.value) || 0; |
|
|
|
|
|
const minValue = 1; |
|
|
const maxValue = Math.max(0, originalQty); |
|
|
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={{ |
|
|
InputLabelProps={{ |
|
|
shrink: true, |
|
|
shrink: true, |
|
|
sx: { fontSize: "0.9375rem" }, |
|
|
sx: { fontSize: "0.9375rem" }, |
|
|
@@ -414,7 +419,7 @@ const InventoryLotLineTable: React.FC<Props> = ({ inventoryLotLines, pagingContr |
|
|
fontSize: '0.9375rem', |
|
|
fontSize: '0.9375rem', |
|
|
}} |
|
|
}} |
|
|
onClick={handleSubmitStockTransfer} |
|
|
onClick={handleSubmitStockTransfer} |
|
|
disabled={!selectedLotLine || !targetLocation || qtyToBeTransferred <= 0 || qtyToBeTransferred > originalQty} |
|
|
|
|
|
|
|
|
disabled={!selectedLotLine || !targetLocation || qtyToBeTransferred < 1 || qtyToBeTransferred > originalQty} |
|
|
> |
|
|
> |
|
|
{t("Submit")} |
|
|
{t("Submit")} |
|
|
</Button> |
|
|
</Button> |
|
|
|