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

247 行
7.4 KiB

  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();
  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;