FPSMS-frontend
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

QrModal.tsx 7.5 KiB

1年前
1年前
1年前
1年前
11 个月前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
1年前
11 个月前
1年前
1年前
1年前
1年前
1年前
1年前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. "use client";
  2. import {
  3. Box,
  4. Button,
  5. Grid,
  6. Modal,
  7. ModalProps,
  8. Stack,
  9. Typography,
  10. } from "@mui/material";
  11. import { useCallback, useEffect, useMemo, useState } from "react";
  12. import { GridRowModesModel, GridRowSelectionModel } from "@mui/x-data-grid";
  13. import ReactQrCodeScanner, {
  14. ScannerConfig,
  15. } from "../ReactQrCodeScanner/ReactQrCodeScanner";
  16. import { FormProvider, SubmitHandler, useForm } from "react-hook-form";
  17. import {
  18. fetchStockInLineInfo,
  19. ModalFormInput,
  20. StockInLineEntry,
  21. updateStockInLine,
  22. } from "@/app/api/po/actions";
  23. import PutAwayForm from "./PutAwayForm";
  24. import { StockInLine } from "@/app/api/po";
  25. import { WarehouseResult } from "@/app/api/warehouse";
  26. import { QrCodeInfo } from "@/app/api/qrcode";
  27. import { Check } from "@mui/icons-material";
  28. import { useTranslation } from "react-i18next";
  29. import { useSearchParams } from "next/navigation";
  30. import { useQrCodeScannerContext } from "../QrCodeScannerProvider/QrCodeScannerProvider";
  31. interface Props extends Omit<ModalProps, "children"> {
  32. warehouse: WarehouseResult[];
  33. }
  34. const style = {
  35. position: "absolute",
  36. top: "50%",
  37. left: "50%",
  38. transform: "translate(-50%, -50%)",
  39. bgcolor: "background.paper",
  40. pt: 5,
  41. px: 5,
  42. pb: 10,
  43. width: "auto",
  44. };
  45. const QrModal: React.FC<Props> = ({ open, onClose, warehouse }) => {
  46. const { t } = useTranslation("purchaseOrder");
  47. const [serverError, setServerError] = useState("");
  48. const params = useSearchParams();
  49. const formProps = useForm<ModalFormInput>({
  50. defaultValues: {
  51. status: "received",
  52. // acceptedQty
  53. // ...itemDetail,
  54. },
  55. });
  56. const errors = formProps.formState.errors;
  57. const closeHandler = useCallback<NonNullable<ModalProps["onClose"]>>(
  58. (...args) => {
  59. onClose?.(...args);
  60. setItemDetail(undefined);
  61. setStockInLineId(undefined);
  62. // reset();
  63. },
  64. [onClose],
  65. );
  66. const [stockInLineId, setStockInLineId] = useState<number>();
  67. const scannerConfig = useMemo<ScannerConfig>(
  68. () => ({
  69. onUpdate: (err, result) => {
  70. if (result) {
  71. const data: QrCodeInfo = JSON.parse(result.getText());
  72. console.log(data);
  73. if (data.stockInLineId) {
  74. console.log("still got in");
  75. console.log(data.stockInLineId);
  76. setStockInLineId(data.stockInLineId);
  77. }
  78. } else return;
  79. },
  80. }),
  81. [],
  82. );
  83. // QR Code Scanner
  84. const scanner = useQrCodeScannerContext();
  85. useEffect(() => {
  86. if (open && !scanner.isScanning) {
  87. scanner.startScan();
  88. } else if (!open && scanner.isScanning) {
  89. scanner.stopScan();
  90. }
  91. }, [open]);
  92. useEffect(() => {
  93. if (scanner.values.length > 0 && !Boolean(itemDetail)) {
  94. console.log(scanner.values[0]);
  95. const data: QrCodeInfo = JSON.parse(scanner.values[0]);
  96. console.log(data);
  97. if (data.stockInLineId) {
  98. console.log("still got in");
  99. console.log(data.stockInLineId);
  100. setStockInLineId(data.stockInLineId);
  101. }
  102. scanner.resetScan();
  103. }
  104. }, [scanner.values]);
  105. const [itemDetail, setItemDetail] = useState<StockInLine>();
  106. const [rowModesModel, setRowModesModel] = useState<GridRowModesModel>({});
  107. const [rowSelectionModel, setRowSelectionModel] = useState<GridRowSelectionModel>([]);
  108. const [disabledSubmit, setDisabledSubmit] = useState(false);
  109. const [unavailableText, setUnavailableText] = useState<string | undefined>(
  110. undefined,
  111. );
  112. const fetchStockInLine = useCallback(
  113. async (stockInLineId: number) => {
  114. setUnavailableText(undefined);
  115. const res = await fetchStockInLineInfo(stockInLineId);
  116. if (res.status.toLowerCase() === "received") {
  117. console.log(res.acceptedQty);
  118. formProps.setValue("acceptedQty", res.acceptedQty);
  119. setDisabledSubmit(false);
  120. setItemDetail(res);
  121. } else if (res.status.toLowerCase() === "completed") {
  122. setDisabledSubmit(true);
  123. } else {
  124. //
  125. setUnavailableText("Item Not Available");
  126. setDisabledSubmit(true);
  127. }
  128. },
  129. [formProps, itemDetail, fetchStockInLineInfo],
  130. );
  131. useEffect(() => {
  132. if (stockInLineId) fetchStockInLine(stockInLineId);
  133. }, [stockInLineId]);
  134. const onSubmit = useCallback<SubmitHandler<ModalFormInput>>(
  135. async (data, event) => {
  136. const hasErrors = false;
  137. console.log("errors");
  138. console.log(errors);
  139. console.log("data");
  140. console.log(data);
  141. console.log("itemDetail");
  142. console.log(itemDetail);
  143. try {
  144. // add checking
  145. // const qty = data.sampleRate
  146. //////////////////////// modify this mess later //////////////////////
  147. const args = {
  148. id: itemDetail?.id,
  149. purchaseOrderId: parseInt(params.get("id")!),
  150. purchaseOrderLineId: itemDetail?.purchaseOrderLineId,
  151. itemId: itemDetail?.itemId,
  152. acceptedQty: data.acceptedQty,
  153. warehouseId: data.warehouseId,
  154. status: data.status,
  155. // ...data,
  156. // productionDate: productionDate,
  157. } as StockInLineEntry & ModalFormInput;
  158. //////////////////////////////////////////////////////////////////////
  159. console.log(args);
  160. // return
  161. if (hasErrors) {
  162. setServerError(t("An error has occurred. Please try again later."));
  163. return false;
  164. }
  165. // return;
  166. const res = await updateStockInLine(args);
  167. if (Boolean(res.id)) {
  168. // update entries
  169. console.log(res);
  170. // add loading
  171. closeHandler({}, "backdropClick");
  172. }
  173. console.log(res);
  174. // if (res)
  175. } catch (e) {
  176. // server error
  177. setServerError(t("An error has occurred. Please try again later."));
  178. console.log(e);
  179. }
  180. },
  181. [t, itemDetail],
  182. );
  183. return (
  184. <FormProvider {...formProps}>
  185. <Modal open={open} onClose={closeHandler}>
  186. <Box
  187. sx={style}
  188. component="form"
  189. onSubmit={formProps.handleSubmit(onSubmit)}
  190. >
  191. <Grid container xs={12}>
  192. <Grid item xs={12}>
  193. {itemDetail != undefined ? (
  194. unavailableText != undefined ? (
  195. <Typography variant="h4" marginInlineEnd={2}>
  196. {unavailableText}
  197. </Typography>
  198. ) : (
  199. <>
  200. <PutAwayForm
  201. itemDetail={itemDetail}
  202. warehouse={warehouse}
  203. disabled={false}
  204. setRowModesModel={setRowModesModel}
  205. setRowSelectionModel={setRowSelectionModel}
  206. />
  207. <Stack direction="row" justifyContent="flex-end" gap={1}>
  208. <Button
  209. name="submit"
  210. variant="contained"
  211. startIcon={<Check />}
  212. type="submit"
  213. disabled={disabledSubmit}
  214. >
  215. {t("submit")}
  216. </Button>
  217. </Stack>
  218. </>
  219. )
  220. ) : (
  221. // <ReactQrCodeScanner scannerConfig={scannerConfig} />
  222. <Typography variant="h4">
  223. {t(
  224. "Will start binding procedure after scanning item qr code.",
  225. )}
  226. </Typography>
  227. )}
  228. </Grid>
  229. </Grid>
  230. </Box>
  231. </Modal>
  232. </FormProvider>
  233. );
  234. };
  235. export default QrModal;