FPSMS-frontend
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 

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