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.
 
 

903 line
26 KiB

  1. "use client";
  2. import {
  3. Button,
  4. CircularProgress,
  5. Grid,
  6. Stack,
  7. Tooltip,
  8. Typography,
  9. } from "@mui/material";
  10. import PlayArrowIcon from "@mui/icons-material/PlayArrow";
  11. import { useTranslation } from "react-i18next";
  12. import StyledDataGrid from "../StyledDataGrid";
  13. import { useCallback, useEffect, useMemo, useState } from "react";
  14. import {
  15. GridColDef,
  16. GridRowId,
  17. GridRowIdGetter,
  18. GridRowModel,
  19. GridRowModes,
  20. useGridApiRef,
  21. GridRenderEditCellParams,
  22. GridEditInputCell,
  23. GridRowParams,
  24. } from "@mui/x-data-grid";
  25. import DoneIcon from "@mui/icons-material/Done";
  26. import { GridRowSelectionModel } from "@mui/x-data-grid";
  27. import { useQrCodeScannerContext } from "../QrCodeScannerProvider/QrCodeScannerProvider";
  28. import {
  29. completeConsoPickOrder,
  30. CreateStockOutLine,
  31. createStockOutLine,
  32. fetchConsoStatus,
  33. fetchPickOrderLineClient,
  34. fetchStockOutLineClient,
  35. PickOrderApprovalInput,
  36. PickOrderQcInput,
  37. } from "@/app/api/pickOrder/actions";
  38. import {
  39. PickOrderLineWithSuggestedLot,
  40. StockOutLine,
  41. } from "@/app/api/pickOrder";
  42. import { Pageable } from "@/app/utils/fetchUtil";
  43. import { QrCodeInfo } from "@/app/api/qrcode";
  44. import { QrCode } from "../QrCode";
  45. import { fetchLotDetail, LotLineInfo } from "@/app/api/inventory/actions";
  46. import { GridRowModesModel } from "@mui/x-data-grid";
  47. import { stockOutLineStatusMap } from "@/app/utils/formatUtil";
  48. import { GridActionsCellItem } from "@mui/x-data-grid";
  49. import DoDisturbIcon from "@mui/icons-material/DoDisturb";
  50. import useUploadContext from "../UploadProvider/useUploadContext";
  51. import { FitAllCell } from "@/app/utils/gridUtil";
  52. import { QcItemWithChecks } from "@/app/api/qc";
  53. import QcForm from "./QcForm";
  54. import { fetchPickOrderQcResult, QcResult } from "@/app/api/qc/actions";
  55. import ShoppingCartIcon from "@mui/icons-material/ShoppingCart";
  56. import AutoFixNormalIcon from "@mui/icons-material/AutoFixNormal";
  57. import ApprovalForm from "./ApprovalForm";
  58. import InfoIcon from "@mui/icons-material/Info";
  59. import VerifiedIcon from "@mui/icons-material/Verified";
  60. import { isNullOrUndefined } from "html5-qrcode/esm/core";
  61. interface Props {
  62. qc: QcItemWithChecks[];
  63. consoCode: string;
  64. }
  65. interface IsLoadingModel {
  66. pickOrderLineTable: boolean;
  67. stockOutLineTable: boolean;
  68. }
  69. export type StockOutLineEntryError = {
  70. [field in keyof StockOutLine]?: string;
  71. };
  72. export type StockOutLineRow = Partial<
  73. StockOutLine & {
  74. id: number;
  75. isActive: boolean | undefined;
  76. _isNew: boolean;
  77. _error: StockOutLineEntryError;
  78. }
  79. >;
  80. class ProcessRowUpdateError extends Error {
  81. public readonly row: StockOutLineRow;
  82. public readonly errors: StockOutLineEntryError | undefined;
  83. constructor(
  84. row: StockOutLineRow,
  85. message?: string,
  86. errors?: StockOutLineEntryError,
  87. ) {
  88. super(message);
  89. this.row = row;
  90. this.errors = errors;
  91. Object.setPrototypeOf(this, ProcessRowUpdateError.prototype);
  92. }
  93. }
  94. export type formDefaultValues = StockOutLine &
  95. (PickOrderQcInput | PickOrderApprovalInput);
  96. const PickOrderDetail: React.FC<Props> = ({ consoCode, qc }) => {
  97. const { t } = useTranslation("pickOrder");
  98. const apiRef = useGridApiRef();
  99. const [qcResult, setQcResult] = useState([] as QcResult[]);
  100. const [selectedRow, setSelectedRow] = useState<GridRowSelectionModel>([]);
  101. const [currPol, setCurrPol] = useState<PickOrderLineWithSuggestedLot>();
  102. const [isChangeLotSolId, setIsChangeLotSolId] = useState<number | undefined>(
  103. undefined,
  104. );
  105. const [formDefaultValues, setFormDefaultValues] =
  106. useState<formDefaultValues>();
  107. const [isLoadingModel, setIsLoadingModel] = useState<IsLoadingModel>({
  108. pickOrderLineTable: false,
  109. stockOutLineTable: false,
  110. });
  111. const [polCriteriaArgs, setPolCriteriaArgs] = useState<Pageable>({
  112. pageNum: 1,
  113. pageSize: 10,
  114. });
  115. const [solCriteriaArgs, setSolCriteriaArgs] = useState<Pageable>({
  116. pageNum: 1,
  117. pageSize: 10,
  118. });
  119. const [polTotalCount, setPolTotalCount] = useState(0);
  120. const [solTotalCount, setSolTotalCount] = useState(0);
  121. const [rowModesModel, setRowModesModel] = useState<GridRowModesModel>({});
  122. const [btnIsLoading, setBtnIsLoading] = useState(false);
  123. const { setIsUploading } = useUploadContext();
  124. const [pickOrderLine, setPickOrderLine] = useState<
  125. PickOrderLineWithSuggestedLot[]
  126. >([]);
  127. const pickOrderLineColumns = useMemo<GridColDef[]>(
  128. () => [
  129. // {
  130. // field: "id",
  131. // headerName: "pickOrderLineId",
  132. // flex: 1,
  133. // },
  134. {
  135. field: "itemName",
  136. headerName: t("item"),
  137. flex: 1,
  138. },
  139. {
  140. field: "qty",
  141. headerName: t("qty"),
  142. flex: 1,
  143. },
  144. {
  145. field: "uom",
  146. headerName: t("uom"),
  147. flex: 1,
  148. },
  149. // {
  150. // field: "lotLineId",
  151. // headerName: "lotLineId",
  152. // flex: 1,
  153. // },
  154. {
  155. field: "warehouse",
  156. headerName: t("location"),
  157. flex: 1,
  158. renderCell: (params) => {
  159. // console.log(params.row.warehouse)
  160. return params.row.warehouse;
  161. if (isNullOrUndefined(params.row.warehouse)) {
  162. return <></>;
  163. } else {
  164. const warehouseList = JSON.parse(
  165. `{${params.row.warehouse}}`,
  166. ) as string[];
  167. return FitAllCell(warehouseList);
  168. }
  169. },
  170. },
  171. {
  172. field: "suggestedLotNo",
  173. headerName: t("suggestedLotNo"),
  174. flex: 1.2,
  175. renderCell: (params) => {
  176. return params.row.suggestedLotNo;
  177. if (isNullOrUndefined(params.row.suggestedLotNo)) return <></>;
  178. const suggestedLotNoList = JSON.parse(
  179. params.row.suggestedLotNo,
  180. ) as string[];
  181. return FitAllCell(suggestedLotNoList);
  182. },
  183. },
  184. {
  185. field: "status",
  186. headerName: t("status"),
  187. flex: 0.5,
  188. renderCell: (params) => {
  189. return t(`${params.row.status}`);
  190. },
  191. },
  192. ],
  193. [],
  194. );
  195. const [isDisableComplete, setIsDisableComplete] = useState(true);
  196. const [status, setStatus] = useState("");
  197. const getConsoStatus = useCallback(async () => {
  198. const status = await fetchConsoStatus(consoCode);
  199. console.log(status);
  200. setStatus(status.status);
  201. }, [fetchConsoStatus]);
  202. const fetchPickOrderLine = useCallback(
  203. async (params: Record<string, any>) => {
  204. setIsLoadingModel((prev) => ({
  205. ...prev,
  206. pickOrderLineTable: true,
  207. }));
  208. const res = await fetchPickOrderLineClient({
  209. ...params,
  210. consoCode: consoCode,
  211. });
  212. if (res) {
  213. console.log(res);
  214. console.log(res.records.every((line) => line.status == "completed"));
  215. setIsDisableComplete(res.records[0].poStatus === "completed");
  216. // setIsDisableComplete(() =>
  217. // res.records.every((line) => line.status !== "completed"),
  218. // );
  219. setPickOrderLine(res.records);
  220. setPolTotalCount(res.total);
  221. } else {
  222. console.log("error");
  223. console.log(res);
  224. }
  225. setIsLoadingModel((prev) => ({
  226. ...prev,
  227. pickOrderLineTable: false,
  228. }));
  229. },
  230. [consoCode],
  231. );
  232. const [stockOutLine, setStockOutLine] = useState<StockOutLine[]>([]);
  233. const getRowId = useCallback<GridRowIdGetter<StockOutLineRow>>(
  234. (row) => row.id as number,
  235. [],
  236. );
  237. const [qcOpen, setQcOpen] = useState(false);
  238. const [approvalOpen, setApprovalOpen] = useState(false);
  239. const closeQcModal = useCallback(() => {
  240. setQcOpen(false);
  241. }, []);
  242. const openQcModal = useCallback(() => {
  243. setQcOpen(true);
  244. }, []);
  245. const closeApprovalModal = useCallback(() => {
  246. setApprovalOpen(false);
  247. }, []);
  248. const openApprovalModal = useCallback(() => {
  249. setApprovalOpen(true);
  250. }, []);
  251. const triggerRefetch = useCallback(() => {
  252. setSelectedRow((prev) => prev);
  253. }, []);
  254. const handleDelete = useCallback(
  255. (id: GridRowId) => () => {
  256. setStockOutLine((prev) => prev.filter((e) => getRowId(e) !== id));
  257. },
  258. [getRowId],
  259. );
  260. const handleStart = useCallback(
  261. (id: GridRowId, params: any) => () => {
  262. setBtnIsLoading(true);
  263. setRowModesModel((prev) => ({
  264. ...prev,
  265. [id]: { mode: GridRowModes.View },
  266. }));
  267. setTimeout(async () => {
  268. // post stock in line
  269. const oldId = params.row.id;
  270. console.log(params.row);
  271. // console.log(currPol);
  272. const postData = {
  273. consoCode: consoCode,
  274. pickOrderLineId: params.row.pickOrderLineId,
  275. inventoryLotLineId: params.row.inventoryLotLineId,
  276. qty: params.row.qty,
  277. } as CreateStockOutLine;
  278. console.log(postData);
  279. // return
  280. console.log("triggering");
  281. const res = await createStockOutLine(postData);
  282. if (res) {
  283. console.log(res);
  284. setStockOutLine((prev) =>
  285. prev.map((p) =>
  286. p.id === oldId ? (res.entity as StockOutLine) : p,
  287. ),
  288. );
  289. }
  290. setBtnIsLoading(false);
  291. // do post directly to test
  292. // openStartModal();
  293. }, 500);
  294. },
  295. [consoCode],
  296. );
  297. useEffect(() => {
  298. console.log(stockOutLine);
  299. }, [stockOutLine]);
  300. const handleApproval = useCallback(
  301. (id: GridRowId, params: any) => async () => {
  302. setBtnIsLoading(true);
  303. console.log(params.row.qty);
  304. console.log(params.row);
  305. setFormDefaultValues({
  306. ...(params.row as StockOutLine),
  307. status: "lot-change",
  308. } as StockOutLine & PickOrderApprovalInput);
  309. setTimeout(() => {
  310. // open qc modal
  311. console.log("delayed");
  312. openApprovalModal();
  313. setBtnIsLoading(false);
  314. }, 200);
  315. },
  316. [openApprovalModal],
  317. );
  318. const handleLotChange = useCallback(
  319. (id: GridRowId, params: GridRowParams<any>) => async () => {
  320. setOpenScanner((prev) => !prev);
  321. console.log(id);
  322. setIsChangeLotSolId((prev) => {
  323. if (prev != undefined) return undefined;
  324. return id as number;
  325. });
  326. },
  327. [],
  328. );
  329. useEffect(() => {
  330. console.log(isChangeLotSolId);
  331. }, [isChangeLotSolId]);
  332. const getQcResult = useCallback(
  333. async (stockOutLineId: number): Promise<QcResult[]> => {
  334. const res = await fetchPickOrderQcResult(stockOutLineId);
  335. console.log("res");
  336. console.log(res);
  337. return res;
  338. },
  339. [],
  340. );
  341. const handleComplete = useCallback(
  342. (id: GridRowId, params: any) => async () => {
  343. setBtnIsLoading(true);
  344. setRowModesModel((prev) => ({
  345. ...prev,
  346. [id]: { mode: GridRowModes.View },
  347. }));
  348. getQcResult(id as number).then((qcResult) => {
  349. setQcResult(qcResult);
  350. });
  351. console.log(params.row.qty);
  352. console.log(params.row);
  353. setFormDefaultValues({
  354. ...(params.row as StockOutLine),
  355. qty: params.row.qty,
  356. status: "completed",
  357. } as StockOutLine & PickOrderQcInput);
  358. setTimeout(() => {
  359. // open qc modal
  360. console.log("delayed");
  361. openQcModal();
  362. setBtnIsLoading(false);
  363. }, 200);
  364. },
  365. [getQcResult, openQcModal],
  366. );
  367. const stockOutLineColumns = useMemo<GridColDef[]>(
  368. () => [
  369. {
  370. field: "itemName",
  371. headerName: t("item name"),
  372. flex: 1,
  373. },
  374. {
  375. field: "qty",
  376. headerName: t("qty"),
  377. editable: true,
  378. flex: 1,
  379. type: "number",
  380. // renderEditCell(params: GridRenderEditCellParams<StockOutLineRow>) {
  381. // const errorMessage =
  382. // params.row._error?.[params.field as keyof StockOutLineEntryError];
  383. // const content = (
  384. // <GridEditInputCell
  385. // {...params}
  386. // inputProps={{ min: 0 }}
  387. // />
  388. // );
  389. // return errorMessage ? (
  390. // <Tooltip title={t(errorMessage)}>
  391. // <Box width="100%">{content}</Box>
  392. // </Tooltip>
  393. // ) : (
  394. // content
  395. // );
  396. // },
  397. },
  398. {
  399. field: "lotNo",
  400. headerName: t("lotNo"),
  401. flex: 1,
  402. },
  403. {
  404. field: "status",
  405. headerName: t("status"),
  406. flex: 0.5,
  407. renderCell: (params) => {
  408. return t(`${params.row.status}`);
  409. },
  410. },
  411. {
  412. field: "actions",
  413. type: "actions",
  414. headerName: `${t("start")}
  415. | ${t("approval")}
  416. | ${t("lot change")}
  417. | ${t("checkout")}
  418. | ${t("delete")}`,
  419. flex: 1.5,
  420. cellClassName: "actions",
  421. getActions: (params) => {
  422. const status = params.row.status.toLowerCase();
  423. return [
  424. <GridActionsCellItem
  425. icon={<PlayArrowIcon />}
  426. label="start"
  427. sx={{
  428. color: "primary.main",
  429. // marginRight: 1,
  430. }}
  431. disabled={!(stockOutLineStatusMap[status] === 0)}
  432. // set _isNew to false after posting
  433. // or check status
  434. onClick={handleStart(params.row.id, params)}
  435. color="inherit"
  436. key="edit"
  437. />,
  438. <GridActionsCellItem
  439. icon={<VerifiedIcon />}
  440. label="approval"
  441. sx={{
  442. color: "primary.main",
  443. // marginRight: 1,
  444. }}
  445. disabled={stockOutLineStatusMap[status] !== 2}
  446. // set _isNew to false after posting
  447. // or check status
  448. onClick={handleApproval(params.row.id, params)} // start scanning for that row
  449. color="inherit"
  450. key="edit"
  451. />,
  452. <GridActionsCellItem
  453. icon={<AutoFixNormalIcon />}
  454. label="lot change" ///
  455. sx={{
  456. color: "primary.main",
  457. // marginRight: 1,
  458. }}
  459. disabled={stockOutLineStatusMap[status] !== 3}
  460. // set _isNew to false after posting
  461. // or check status
  462. onClick={handleLotChange(params.row.id, params)} // start scanning for that row
  463. color="inherit"
  464. key="edit"
  465. />,
  466. <GridActionsCellItem
  467. icon={<ShoppingCartIcon />}
  468. label="qcAndPick"
  469. sx={{
  470. color: "primary.main",
  471. // marginRight: 1,
  472. }}
  473. disabled={
  474. !params.row.inventoryLotLineId ||
  475. stockOutLineStatusMap[status] === 2 ||
  476. stockOutLineStatusMap[status] >= 4 ||
  477. stockOutLineStatusMap[status] === 0
  478. }
  479. // set _isNew to false after posting
  480. // or check status
  481. onClick={handleComplete(params.row.id, params)}
  482. color="inherit"
  483. key="edit"
  484. />,
  485. <GridActionsCellItem
  486. key={1}
  487. icon={<DoDisturbIcon />}
  488. label="Delete"
  489. sx={{
  490. color: "error.main",
  491. }}
  492. disabled={stockOutLineStatusMap[status] > 0}
  493. onClick={handleDelete(params.row.id)}
  494. />,
  495. // <GridActionsCellItem
  496. // icon={<InfoIcon />}
  497. // label="debug button"
  498. // sx={{
  499. // color: "error.main",
  500. // }}
  501. // onClick={() => console.log(params.row)}
  502. // />,
  503. ];
  504. },
  505. },
  506. ],
  507. [t, handleStart, handleApproval, handleLotChange, handleComplete, handleDelete],
  508. );
  509. const fetchStockOutLine = useCallback(
  510. async (params: Record<string, any>, selectedRow: GridRowSelectionModel) => {
  511. const _selectedRow = selectedRow as number[];
  512. console.log(params);
  513. console.log(_selectedRow);
  514. // fetch
  515. const res = await fetchStockOutLineClient(_selectedRow[0]);
  516. console.log(res);
  517. // set state
  518. setStockOutLine(res);
  519. },
  520. [],
  521. );
  522. const addRow = useCallback(
  523. (qrcode: LotLineInfo) => {
  524. const newEntry = {
  525. id: Date.now(),
  526. _isNew: true,
  527. itemId: qrcode.itemId,
  528. itemName: qrcode.itemName,
  529. itemNo: qrcode.itemNo,
  530. lotNo: qrcode.lotNo,
  531. inventoryLotLineId: qrcode.inventoryLotLineId,
  532. qty: 0,
  533. pickOrderLineId: selectedRow[0] as number,
  534. status: "draft",
  535. };
  536. setStockOutLine((prev) => [...prev, newEntry]);
  537. setRowModesModel((model) => ({
  538. ...model,
  539. [getRowId(newEntry)]: {
  540. mode: GridRowModes.Edit,
  541. },
  542. }));
  543. },
  544. [getRowId, selectedRow],
  545. );
  546. // need modify this later
  547. const changeRow = useCallback(
  548. (id: number, qrcode: LotLineInfo) => {
  549. console.log(stockOutLine);
  550. console.log(stockOutLine.find((line) => line.id === id));
  551. const rowToSave = {
  552. ...stockOutLine.find((line) => line.id === id),
  553. itemId: qrcode.itemId,
  554. itemName: qrcode.itemName,
  555. itemNo: qrcode.itemNo,
  556. lotNo: qrcode.lotNo,
  557. inventoryLotLineId: qrcode.inventoryLotLineId,
  558. };
  559. console.log(rowToSave);
  560. const newEntries = stockOutLine.map((e) =>
  561. getRowId(e) === id ? rowToSave : e,
  562. );
  563. setStockOutLine(newEntries as StockOutLine[]);
  564. },
  565. [stockOutLine, getRowId],
  566. );
  567. /// handle refetch all data
  568. useEffect(() => {
  569. if (!qcOpen || !approvalOpen) {
  570. triggerRefetch();
  571. getConsoStatus();
  572. fetchPickOrderLine(polCriteriaArgs);
  573. // getConsoStatus()
  574. }
  575. if (selectedRow.length > 0) fetchStockOutLine(solCriteriaArgs, selectedRow);
  576. }, [qcOpen, approvalOpen, solCriteriaArgs, selectedRow, triggerRefetch, polCriteriaArgs, getConsoStatus, fetchStockOutLine, fetchPickOrderLine]);
  577. const getLotDetail = useCallback(
  578. async (stockInLineId: number): Promise<LotLineInfo> => {
  579. const res = await fetchLotDetail(stockInLineId);
  580. console.log("res");
  581. console.log(res);
  582. return res;
  583. },
  584. [],
  585. );
  586. const [isOpenScanner, setOpenScanner] = useState(false);
  587. const onOpenScanner = useCallback(() => {
  588. setOpenScanner((prev) => !prev);
  589. }, []);
  590. const scanner = useQrCodeScannerContext();
  591. useEffect(() => {
  592. if (isOpenScanner && !scanner.isScanning) {
  593. scanner.startScan();
  594. } else if (!isOpenScanner && scanner.isScanning) {
  595. scanner.stopScan();
  596. }
  597. }, [isOpenScanner, scanner]);
  598. const homemade_Qrcode = {
  599. // stockInLineId: 156, // eggs
  600. // stockInLineId: 162, // chicken wings
  601. // stockInLineId: 168, // sesame
  602. warehouseId: 2
  603. };
  604. useEffect(() => {
  605. if (scanner.values.length > 0) {
  606. console.log(scanner.values[0]);
  607. const data: QrCodeInfo = JSON.parse(scanner.values[0]);
  608. console.log(data);
  609. if (data.stockInLineId) {
  610. setIsUploading(true);
  611. // fetch
  612. getLotDetail(data.stockInLineId).then((qrcode) => {
  613. // add row
  614. if (isChangeLotSolId) {
  615. changeRow(isChangeLotSolId, qrcode);
  616. } else {
  617. addRow(qrcode);
  618. }
  619. });
  620. setIsUploading(false);
  621. }
  622. scanner.resetScan();
  623. }
  624. }, [
  625. isChangeLotSolId,
  626. scanner.values,
  627. selectedRow,
  628. changeRow,
  629. addRow,
  630. getLotDetail,
  631. scanner,
  632. setIsUploading,
  633. ]);
  634. // const mannuallyAddRow = useCallback(() => {
  635. // getLotDetail(homemade_Qrcode.stockInLineId).then((qrcode) => {
  636. // addRow(qrcode);
  637. // // scanner.resetScan();
  638. // });
  639. // }, [addRow, getLotDetail, homemade_Qrcode.stockInLineId]);
  640. const validation = useCallback(
  641. (
  642. newRow: GridRowModel<StockOutLineRow>,
  643. // rowModel: GridRowSelectionModel
  644. ): StockOutLineEntryError | undefined => {
  645. const error: StockOutLineEntryError = {};
  646. const checkQty = currPol?.qty;
  647. console.log(newRow);
  648. if (!newRow.qty || newRow.qty <= 0) {
  649. error["qty"] = t("illegal qty");
  650. }
  651. return Object.keys(error).length > 0 ? error : undefined;
  652. },
  653. [currPol?.qty, t],
  654. );
  655. const processRowUpdate = useCallback(
  656. (
  657. newRow: GridRowModel<StockOutLineRow>,
  658. originalRow: GridRowModel<StockOutLineRow>,
  659. ) => {
  660. const errors = validation(newRow); // change to validation
  661. console.log(newRow);
  662. if (errors) {
  663. throw new ProcessRowUpdateError(
  664. originalRow,
  665. "validation error",
  666. errors,
  667. );
  668. }
  669. const { _isNew, _error, ...updatedRow } = newRow;
  670. const rowToSave = {
  671. ...updatedRow,
  672. } satisfies StockOutLineRow;
  673. console.log(rowToSave);
  674. const newEntries = stockOutLine.map((e) =>
  675. getRowId(e) === getRowId(originalRow) ? rowToSave : e,
  676. );
  677. console.log(newEntries);
  678. setStockOutLine(newEntries as StockOutLine[]);
  679. return rowToSave;
  680. },
  681. [getRowId, stockOutLine, validation],
  682. );
  683. const onProcessRowUpdateError = useCallback(
  684. (updateError: ProcessRowUpdateError) => {
  685. const errors = updateError.errors;
  686. const oldRow = updateError.row;
  687. apiRef.current.updateRows([{ ...oldRow, _error: errors }]);
  688. },
  689. [apiRef],
  690. );
  691. const handleCompleteOrder = useCallback(async () => {
  692. const res = await completeConsoPickOrder(consoCode);
  693. if (res.message === "completed") {
  694. console.log(res);
  695. window.location.reload()
  696. // completed
  697. triggerRefetch();
  698. // setIsCompletedOrder(false)
  699. } else {
  700. // not completed
  701. triggerRefetch();
  702. }
  703. }, [consoCode, triggerRefetch]);
  704. return (
  705. <>
  706. <Stack spacing={2}>
  707. <Grid container xs={12} justifyContent="start">
  708. <Grid item xs={12}>
  709. <Typography variant="h4" marginInlineEnd={2}>
  710. {consoCode} - {status}
  711. </Typography>
  712. </Grid>
  713. <Grid item xs={8}>
  714. <Button
  715. // onClick={buttonData.onClick}
  716. disabled={isDisableComplete}
  717. color={"info"}
  718. startIcon={<DoneIcon />}
  719. onClick={handleCompleteOrder}
  720. >
  721. {t("Complete Pick Order")}
  722. </Button>
  723. </Grid>
  724. <Grid
  725. item
  726. xs={4}
  727. display="flex"
  728. justifyContent="end"
  729. alignItems="end"
  730. >
  731. {/* <Button
  732. onClick={mannuallyAddRow}
  733. disabled={selectedRow.length === 0}
  734. >
  735. {isOpenScanner ? t("manual scanning") : t("manual scan")}
  736. </Button> */}
  737. <Button
  738. onClick={onOpenScanner}
  739. disabled={isDisableComplete ?? selectedRow.length === 0}
  740. >
  741. {isOpenScanner ? t("binding") : t("bind")}
  742. </Button>
  743. </Grid>
  744. {/* homemade qrcode for testing purpose */}
  745. {/* <Grid
  746. item
  747. xs={12}
  748. style={{ display: "flex", justifyContent: "center" }}
  749. >
  750. <QrCode
  751. content={homemade_Qrcode}
  752. sx={{ width: 200, height: 200 }}
  753. />
  754. </Grid> */}
  755. </Grid>
  756. <Grid container xs={12} justifyContent="space-between">
  757. {/* <Grid item xs={12} sx={{ height: 400 }}>
  758. <StyledDataGrid rows={pickOrderLine} columns={columns} />
  759. </Grid> */}
  760. <Grid item xs={12} sx={{ height: 400 }}>
  761. {isLoadingModel.pickOrderLineTable && pickOrderLine == undefined ? (
  762. <CircularProgress size={40} />
  763. ) : (
  764. <StyledDataGrid
  765. rows={pickOrderLine}
  766. columns={pickOrderLineColumns}
  767. rowSelectionModel={selectedRow}
  768. onRowSelectionModelChange={(newRowSelectionModel) => {
  769. setIsChangeLotSolId(undefined)
  770. setSelectedRow(newRowSelectionModel);
  771. if (newRowSelectionModel && newRowSelectionModel.length > 0) {
  772. const pol = pickOrderLine.find(
  773. (item) => item.id === newRowSelectionModel[0],
  774. );
  775. console.log(pol);
  776. setCurrPol(pol);
  777. }
  778. }}
  779. initialState={{
  780. pagination: {
  781. paginationModel: { pageSize: 10, page: 0 },
  782. },
  783. }}
  784. pageSizeOptions={[10, 25, 50, 100]}
  785. onPaginationModelChange={async (model, details) => {
  786. setPolCriteriaArgs({
  787. pageNum: model.page + 1,
  788. pageSize: model.pageSize,
  789. });
  790. }}
  791. rowCount={polTotalCount}
  792. />
  793. )}
  794. </Grid>
  795. <Grid item xs={12} sx={{ height: 400 }}>
  796. {isChangeLotSolId}
  797. <StyledDataGrid
  798. apiRef={apiRef}
  799. rows={stockOutLine}
  800. columns={stockOutLineColumns}
  801. rowModesModel={rowModesModel}
  802. onRowModesModelChange={setRowModesModel}
  803. disableColumnMenu
  804. editMode="row"
  805. processRowUpdate={processRowUpdate}
  806. onProcessRowUpdateError={onProcessRowUpdateError}
  807. isCellEditable={(params) => {
  808. const status = params.row.status.toLowerCase();
  809. return (
  810. stockOutLineStatusMap[status] === 0 ||
  811. stockOutLineStatusMap[status] === 3
  812. );
  813. }}
  814. initialState={{
  815. pagination: {
  816. paginationModel: { pageSize: 10, page: 0 },
  817. },
  818. }}
  819. pageSizeOptions={[10, 25, 50, 100]}
  820. onPaginationModelChange={async (model, details) => {
  821. setSolCriteriaArgs({
  822. pageNum: model.page + 1,
  823. pageSize: model.pageSize,
  824. });
  825. }}
  826. rowCount={solTotalCount}
  827. />
  828. </Grid>
  829. </Grid>
  830. </Stack>
  831. {/* modals */}
  832. {qcOpen && formDefaultValues != undefined && (
  833. <QcForm
  834. qcDefaultValues={formDefaultValues as StockOutLine & PickOrderQcInput}
  835. qc={qc}
  836. disabled={false}
  837. open={qcOpen}
  838. onClose={closeQcModal}
  839. />
  840. )}
  841. {approvalOpen && formDefaultValues != undefined && (
  842. <ApprovalForm
  843. approvalDefaultValues={
  844. formDefaultValues as StockOutLine & PickOrderApprovalInput
  845. }
  846. disabled={false}
  847. open={approvalOpen}
  848. onClose={closeApprovalModal}
  849. />
  850. )}
  851. </>
  852. );
  853. };
  854. export default PickOrderDetail;