Kaynağa Gözat

For my testing use, use the cam instead of barcode scanner for putaway

reset-do-picking-order
[email protected] 2 hafta önce
ebeveyn
işleme
9d00348946
3 değiştirilmiş dosya ile 235 ekleme ve 0 silme
  1. +37
    -0
      src/app/(main)/putAwayCam/page.tsx
  2. +179
    -0
      src/components/PutAwayScan/PutAwayCamScan.tsx
  3. +19
    -0
      src/components/PutAwayScan/PutAwayCamScanWrapper.tsx

+ 37
- 0
src/app/(main)/putAwayCam/page.tsx Dosyayı Görüntüle

@@ -0,0 +1,37 @@
import PutAwayCamScanWrapper from "@/components/PutAwayScan/PutAwayCamScanWrapper";
import { I18nProvider, getServerI18n } from "@/i18n";
import Stack from "@mui/material/Stack";
import Typography from "@mui/material/Typography";
import { Metadata } from "next";
import { Suspense } from "react";

export const metadata: Metadata = {
title: "Put Away Camera",
};

const PutAwayCamPage: React.FC = async () => {
const { t } = await getServerI18n("putAway");

return (
<>
<Stack
direction="row"
justifyContent="space-between"
flexWrap="wrap"
rowGap={2}
>
<Typography variant="h4" marginInlineEnd={2}>
{t("Put Away")}
</Typography>
</Stack>
<I18nProvider namespaces={["putAway", "purchaseOrder", "common"]}>
<Suspense fallback={<PutAwayCamScanWrapper.Loading />}>
<PutAwayCamScanWrapper />
</Suspense>
</I18nProvider>
</>
);
};

export default PutAwayCamPage;


+ 179
- 0
src/components/PutAwayScan/PutAwayCamScan.tsx Dosyayı Görüntüle

@@ -0,0 +1,179 @@
"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import { Box, Paper, Typography } from "@mui/material";
import ReactQrCodeScanner, {
ScannerConfig,
defaultScannerConfig,
} from "../ReactQrCodeScanner/ReactQrCodeScanner";
import { WarehouseResult } from "@/app/api/warehouse";
import { useTranslation } from "react-i18next";
import { QrCodeScanner as QrCodeIcon } from "@mui/icons-material";
import PutAwayModal from "./PutAwayModal";
import PutAwayReviewGrid from "./PutAwayReviewGrid";
import type { PutAwayRecord } from ".";
import type { QrCodeScanner as QrCodeScannerType } from "../QrCodeScannerProvider/QrCodeScannerProvider";

type Props = {
warehouse: WarehouseResult[];
};

type ScanStatusType = "pending" | "scanning";

const dummyScanner: QrCodeScannerType = {
values: [],
isScanning: false,
startScan: () => {},
stopScan: () => {},
resetScan: () => {},
result: undefined,
state: "pending",
error: undefined,
};

const PutAwayCamScan: React.FC<Props> = ({ warehouse }) => {
const { t } = useTranslation("putAway");

const [scanStatus, setScanStatus] = useState<ScanStatusType>("pending");
const [openPutAwayModal, setOpenPutAwayModal] = useState(false);
const [scannedSilId, setScannedSilId] = useState<number>(0);
const [scannedWareHouseId, setScannedWareHouseId] = useState<number>(0);
const [putAwayHistory, setPutAwayHistory] = useState<PutAwayRecord[]>([]);

const addPutAwayHistory = (putAwayData: PutAwayRecord) => {
const newPutaway = { ...putAwayData, id: putAwayHistory.length + 1 };
setPutAwayHistory((prev) => [...prev, newPutaway]);
};

const handleSetDefaultWarehouseId = useCallback((warehouseId: number) => {
if (scannedWareHouseId === 0) {
setScannedWareHouseId(warehouseId);
}
}, [scannedWareHouseId]);

const handleScan = useCallback(
(rawText: string) => {
if (!rawText) return;

setScanStatus("scanning");

const trySetNumeric = (value: unknown) => {
const num = Number(value);
if (!Number.isFinite(num) || num <= 0) return false;
if (scannedSilId === 0) {
setScannedSilId(num);
} else if (scannedWareHouseId === 0) {
setScannedWareHouseId(num);
}
return true;
};

// 1) Try JSON payload first
try {
const data = JSON.parse(rawText) as any;
if (data) {
if (scannedSilId === 0) {
if (data.stockInLineId && trySetNumeric(data.stockInLineId)) return;
if (data.value && trySetNumeric(data.value)) return;
} else {
if (data.warehouseId && trySetNumeric(data.warehouseId)) return;
if (data.value && trySetNumeric(data.value)) return;
}
}
} catch {
// Not JSON – fall through to numeric parsing
}

// 2) Fallback: plain numeric content
if (trySetNumeric(rawText)) return;
},
[scannedSilId, scannedWareHouseId],
);

useEffect(() => {
if (scannedSilId > 0) {
setOpenPutAwayModal(true);
setScanStatus("pending");
}
}, [scannedSilId]);

const closeModal = () => {
setScannedSilId(0);
setScannedWareHouseId(0);
setOpenPutAwayModal(false);
setScanStatus("pending");
};

const displayText = useMemo(() => {
if (scanStatus === "scanning") {
return t("Scanning");
}
if (scannedSilId > 0) {
return t("Scanned, opening detail");
}
return t("Pending scan");
}, [scanStatus, scannedSilId, t]);

const scannerConfig: ScannerConfig = {
...defaultScannerConfig,
onUpdate: (_err, result) => {
if (result) {
handleScan(result.getText());
}
},
};

return (
<>
<Paper
sx={{
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
textAlign: "center",
gap: 2,
p: 2,
}}
>
<Typography variant="h4" sx={{ mb: 1 }}>
{displayText}
</Typography>
<QrCodeIcon sx={{ fontSize: 80, mb: 1 }} color="primary" />
<Box
sx={{
width: "100%",
maxWidth: 480,
aspectRatio: "4 / 3",
overflow: "hidden",
}}
>
<ReactQrCodeScanner scannerConfig={scannerConfig} />
</Box>
</Paper>

{putAwayHistory.length > 0 && (
<>
<Typography variant="h5" sx={{ mt: 3, mb: 1 }}>
{t("putAwayHistory")}
</Typography>
<PutAwayReviewGrid putAwayHistory={putAwayHistory} />
</>
)}

<PutAwayModal
open={openPutAwayModal}
onClose={closeModal}
warehouse={warehouse}
stockInLineId={scannedSilId}
warehouseId={scannedWareHouseId}
scanner={dummyScanner}
addPutAwayHistory={addPutAwayHistory}
onSetDefaultWarehouseId={handleSetDefaultWarehouseId}
/>
</>
);
};

export default PutAwayCamScan;


+ 19
- 0
src/components/PutAwayScan/PutAwayCamScanWrapper.tsx Dosyayı Görüntüle

@@ -0,0 +1,19 @@
import React from "react";
import GeneralLoading from "../General/GeneralLoading";
import PutAwayCamScan from "./PutAwayCamScan";
import { fetchWarehouseList } from "@/app/api/warehouse";

interface SubComponents {
Loading: typeof GeneralLoading;
}

const PutAwayCamScanWrapper: React.FC & SubComponents = async () => {
const [warehouse] = await Promise.all([fetchWarehouseList()]);

return <PutAwayCamScan warehouse={warehouse} />;
};

PutAwayCamScanWrapper.Loading = GeneralLoading;

export default PutAwayCamScanWrapper;


Yükleniyor…
İptal
Kaydet