FPSMS-frontend
Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 

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