FPSMS-frontend
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 

372 řádky
10 KiB

  1. import {
  2. Autocomplete,
  3. Box,
  4. Button,
  5. CircularProgress,
  6. FormControl,
  7. Grid,
  8. Modal,
  9. ModalProps,
  10. TextField,
  11. Typography,
  12. } from "@mui/material";
  13. import { GridToolbarContainer } from "@mui/x-data-grid";
  14. import {
  15. FooterPropsOverrides,
  16. GridColDef,
  17. GridRowSelectionModel,
  18. useGridApiRef,
  19. } from "@mui/x-data-grid";
  20. import { useCallback, useEffect, useMemo, useState } from "react";
  21. import { useTranslation } from "react-i18next";
  22. import StyledDataGrid from "../StyledDataGrid";
  23. import SearchResults, {
  24. Column,
  25. defaultPagingController,
  26. } from "../SearchResults/SearchResults";
  27. import {
  28. ByItemsSummary,
  29. ConsoPickOrderResult,
  30. PickOrderLine,
  31. PickOrderResult,
  32. } from "@/app/api/pickOrder";
  33. import { useRouter, useSearchParams } from "next/navigation";
  34. import ConsolidatePickOrderItemSum from "./ConsolidatePickOrderItemSum";
  35. import ConsolidatePickOrderSum from "./ConsolidatePickOrderSum";
  36. import { GridInputRowSelectionModel } from "@mui/x-data-grid";
  37. import {
  38. fetchConsoDetail,
  39. fetchConsoPickOrderClient,
  40. releasePickOrder,
  41. ReleasePickOrderInputs,
  42. } from "@/app/api/pickOrder/actions";
  43. import { EditNote } from "@mui/icons-material";
  44. import { fetchNameList, NameList } from "@/app/api/user/actions";
  45. import { useField } from "@mui/x-date-pickers/internals";
  46. import {
  47. FormProvider,
  48. SubmitErrorHandler,
  49. SubmitHandler,
  50. useForm,
  51. } from "react-hook-form";
  52. import { pickOrderStatusMap } from "@/app/utils/formatUtil";
  53. interface Props {
  54. filterArgs: Record<string, any>;
  55. }
  56. const style = {
  57. position: "absolute",
  58. top: "50%",
  59. left: "50%",
  60. transform: "translate(-50%, -50%)",
  61. bgcolor: "background.paper",
  62. pt: 5,
  63. px: 5,
  64. pb: 10,
  65. // width: 1500,
  66. width: { xs: "100%", sm: "100%", md: "100%" },
  67. };
  68. interface DisableButton {
  69. releaseBtn: boolean;
  70. removeBtn: boolean;
  71. }
  72. const ConsolidatedPickOrders: React.FC<Props> = ({ filterArgs }) => {
  73. const { t } = useTranslation("pickOrder");
  74. const router = useRouter();
  75. const apiRef = useGridApiRef();
  76. const [filteredPickOrders, setFilteredPickOrders] = useState(
  77. [] as ConsoPickOrderResult[],
  78. );
  79. const [isLoading, setIsLoading] = useState(false);
  80. const [modalOpen, setModalOpen] = useState(false); //change back to false
  81. const [consoCode, setConsoCode] = useState<string | undefined>(); ///change back to undefined
  82. const [revertIds, setRevertIds] = useState<GridInputRowSelectionModel>([]);
  83. const [totalCount, setTotalCount] = useState<number>();
  84. const [usernameList, setUsernameList] = useState<NameList[]>([]);
  85. const [byPickOrderRows, setByPickOrderRows] = useState<
  86. Omit<PickOrderResult, "items">[] | undefined
  87. >(undefined);
  88. const [byItemsRows, setByItemsRows] = useState<ByItemsSummary[] | undefined>(
  89. undefined,
  90. );
  91. const [disableRelease, setDisableRelease] = useState<boolean>(true);
  92. const formProps = useForm<ReleasePickOrderInputs>();
  93. const errors = formProps.formState.errors;
  94. const openDetailModal = useCallback((consoCode: string) => {
  95. setConsoCode(consoCode);
  96. setModalOpen(true);
  97. }, []);
  98. const closeDetailModal = useCallback(() => {
  99. setModalOpen(false);
  100. setConsoCode(undefined);
  101. }, []);
  102. const onDetailClick = useCallback(
  103. (pickOrder: any) => {
  104. console.log(pickOrder);
  105. const status = pickOrder.status;
  106. if (pickOrderStatusMap[status] >= 3) {
  107. router.push(`/pickOrder/detail?consoCode=${pickOrder.consoCode}`);
  108. } else {
  109. openDetailModal(pickOrder.consoCode);
  110. }
  111. },
  112. [router, openDetailModal],
  113. );
  114. const columns = useMemo<Column<ConsoPickOrderResult>[]>(
  115. () => [
  116. {
  117. name: "id",
  118. label: t("Detail"),
  119. onClick: onDetailClick,
  120. buttonIcon: <EditNote />,
  121. },
  122. {
  123. name: "consoCode",
  124. label: t("consoCode"),
  125. },
  126. {
  127. name: "status",
  128. label: t("status"),
  129. renderCell: (params: any) => t(params.status),
  130. },
  131. ],
  132. [onDetailClick, t],
  133. );
  134. const [pagingController, setPagingController] = useState(
  135. defaultPagingController,
  136. );
  137. // pass conso code back to assign
  138. // pass user back to assign
  139. const fetchNewPageConsoPickOrder = useCallback(
  140. async (
  141. pagingController: Record<string, number>,
  142. filterArgs: Record<string, number>,
  143. ) => {
  144. setIsLoading(true);
  145. const params = {
  146. ...pagingController,
  147. ...filterArgs,
  148. };
  149. const res = await fetchConsoPickOrderClient(params);
  150. if (res) {
  151. console.log(res);
  152. setFilteredPickOrders(res.records);
  153. setTotalCount(res.total);
  154. }
  155. setIsLoading(false);
  156. },
  157. [],
  158. );
  159. useEffect(() => {
  160. fetchNewPageConsoPickOrder(pagingController, filterArgs);
  161. }, [fetchNewPageConsoPickOrder, pagingController, filterArgs]);
  162. const isReleasable = useCallback((itemList: ByItemsSummary[]): boolean => {
  163. let isReleasable = true;
  164. for (const item of itemList) {
  165. isReleasable = item.requiredQty >= item.availableQty;
  166. if (!isReleasable) return isReleasable;
  167. }
  168. return isReleasable;
  169. }, []);
  170. const fetchConso = useCallback(
  171. async (consoCode: string) => {
  172. const res = await fetchConsoDetail(consoCode);
  173. const nameListRes = await fetchNameList();
  174. if (res) {
  175. console.log(res);
  176. setByPickOrderRows(res.pickOrders);
  177. // for testing
  178. // for (const item of res.items) {
  179. // item.availableQty = 1000;
  180. // }
  181. setByItemsRows(res.items);
  182. setDisableRelease(isReleasable(res.items));
  183. } else {
  184. console.log("error");
  185. console.log(res);
  186. }
  187. if (nameListRes) {
  188. console.log(nameListRes);
  189. setUsernameList(nameListRes);
  190. }
  191. },
  192. [isReleasable],
  193. );
  194. const closeHandler = useCallback<NonNullable<ModalProps["onClose"]>>(
  195. (...args) => {
  196. closeDetailModal();
  197. // reset();
  198. },
  199. [closeDetailModal],
  200. );
  201. const onChange = useCallback(
  202. (event: React.SyntheticEvent, newValue: NameList) => {
  203. console.log(newValue);
  204. formProps.setValue("assignTo", newValue.id);
  205. },
  206. [formProps],
  207. );
  208. const onSubmit = useCallback<SubmitHandler<ReleasePickOrderInputs>>(
  209. async (data, event) => {
  210. console.log(data);
  211. try {
  212. const res = await releasePickOrder(data);
  213. console.log(res);
  214. if (res.consoCode.length > 0) {
  215. console.log(res);
  216. router.push(`/pickOrder/detail?consoCode=${res.consoCode}`);
  217. } else {
  218. console.log(res);
  219. }
  220. } catch (error) {
  221. console.log(error);
  222. }
  223. },
  224. [router],
  225. );
  226. const onSubmitError = useCallback<SubmitErrorHandler<ReleasePickOrderInputs>>(
  227. (errors) => {},
  228. [],
  229. );
  230. const handleConsolidate_revert = useCallback(() => {
  231. console.log(revertIds);
  232. }, [revertIds]);
  233. useEffect(() => {
  234. if (consoCode) {
  235. fetchConso(consoCode);
  236. formProps.setValue("consoCode", consoCode);
  237. }
  238. }, [consoCode, fetchConso, formProps]);
  239. return (
  240. <>
  241. <Grid
  242. container
  243. rowGap={1}
  244. // direction="column"
  245. alignItems="center"
  246. justifyContent="center"
  247. >
  248. <Grid item xs={12}>
  249. {isLoading ? (
  250. <CircularProgress size={40} />
  251. ) : (
  252. <SearchResults<ConsoPickOrderResult>
  253. items={filteredPickOrders}
  254. columns={columns}
  255. pagingController={pagingController}
  256. setPagingController={setPagingController}
  257. totalCount={totalCount}
  258. />
  259. )}
  260. </Grid>
  261. </Grid>
  262. {consoCode != undefined ? (
  263. <Modal open={modalOpen} onClose={closeHandler}>
  264. <FormProvider {...formProps}>
  265. <Box
  266. sx={{ ...style, maxHeight: 800 }}
  267. component="form"
  268. onSubmit={formProps.handleSubmit(onSubmit, onSubmitError)}
  269. >
  270. <Grid container>
  271. <Grid item xs={8}>
  272. <Typography mb={2} variant="h4">
  273. {consoCode}
  274. </Typography>
  275. </Grid>
  276. <Grid
  277. item
  278. xs={4}
  279. display="flex"
  280. justifyContent="end"
  281. alignItems="end"
  282. >
  283. <FormControl fullWidth>
  284. <Autocomplete
  285. disableClearable
  286. fullWidth
  287. getOptionLabel={(option) => option.name}
  288. options={usernameList}
  289. onChange={onChange}
  290. renderInput={(params) => <TextField {...params} />}
  291. />
  292. </FormControl>
  293. </Grid>
  294. </Grid>
  295. <Box
  296. sx={{
  297. height: 400,
  298. overflowY: "auto",
  299. }}
  300. >
  301. <Grid container>
  302. <Grid item xs={12} sx={{ mt: 2 }}>
  303. <ConsolidatePickOrderSum
  304. rows={byPickOrderRows}
  305. setRows={setByPickOrderRows}
  306. consoCode={consoCode}
  307. revertIds={revertIds}
  308. setRevertIds={setRevertIds}
  309. />
  310. </Grid>
  311. <Grid item xs={12}>
  312. <ConsolidatePickOrderItemSum
  313. rows={byItemsRows}
  314. setRows={setByItemsRows}
  315. />
  316. </Grid>
  317. </Grid>
  318. </Box>
  319. <Grid container>
  320. <Grid
  321. item
  322. xs={12}
  323. display="flex"
  324. justifyContent="end"
  325. alignItems="end"
  326. >
  327. <Button
  328. disabled={(revertIds as number[]).length < 1}
  329. variant="outlined"
  330. onClick={handleConsolidate_revert}
  331. sx={{ mr: 1 }}
  332. >
  333. {t("remove")}
  334. </Button>
  335. <Button
  336. disabled={disableRelease}
  337. variant="outlined"
  338. // onClick={handleRelease}
  339. type="submit"
  340. >
  341. {t("release")}
  342. </Button>
  343. </Grid>
  344. </Grid>
  345. </Box>
  346. </FormProvider>
  347. </Modal>
  348. ) : undefined}
  349. </>
  350. );
  351. };
  352. export default ConsolidatedPickOrders;