FPSMS-frontend
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

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