FPSMS-frontend
Você não pode selecionar mais de 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.
 
 
 

288 linhas
9.2 KiB

  1. "use client";
  2. // 修改为 PickOrder 相关的导入
  3. import { GetPickOrderLineInfo } from "@/app/api/pickOrder/actions";
  4. import { QcItemWithChecks } from "@/app/api/qc";
  5. import { PurchaseQcResult } from "@/app/api/po/actions";
  6. import {
  7. Box,
  8. Button,
  9. Grid,
  10. Modal,
  11. ModalProps,
  12. Stack,
  13. Typography,
  14. Table,
  15. TableBody,
  16. TableCell,
  17. TableContainer,
  18. TableHead,
  19. TableRow,
  20. Paper,
  21. } from "@mui/material";
  22. import { Dispatch, SetStateAction, useCallback, useEffect, useState } from "react";
  23. import { FormProvider, SubmitHandler, useForm } from "react-hook-form";
  24. import { useTranslation } from "react-i18next";
  25. import { dummyQCData, QcData } from "../PoDetail/dummyQcTemplate";
  26. import { submitDialogWithWarning } from "../Swal/CustomAlerts";
  27. const style = {
  28. position: "absolute",
  29. top: "50%",
  30. left: "50%",
  31. transform: "translate(-50%, -50%)",
  32. bgcolor: "background.paper",
  33. pt: 5,
  34. px: 5,
  35. pb: 10,
  36. display: "block",
  37. width: { xs: "60%", sm: "60%", md: "60%" },
  38. };
  39. // 修改接口定义
  40. interface CommonProps extends Omit<ModalProps, "children"> {
  41. itemDetail: GetPickOrderLineInfo & {
  42. pickOrderCode: string;
  43. qcResult?: PurchaseQcResult[]
  44. };
  45. setItemDetail: Dispatch<
  46. SetStateAction<
  47. | (GetPickOrderLineInfo & {
  48. pickOrderCode: string;
  49. warehouseId?: number;
  50. })
  51. | undefined
  52. >
  53. >;
  54. qc?: QcItemWithChecks[];
  55. warehouse?: any[];
  56. }
  57. interface Props extends CommonProps {
  58. itemDetail: GetPickOrderLineInfo & {
  59. pickOrderCode: string;
  60. qcResult?: PurchaseQcResult[]
  61. };
  62. }
  63. // 修改组件名称
  64. const PickQcStockInModalVer2: React.FC<Props> = ({
  65. open,
  66. onClose,
  67. itemDetail,
  68. setItemDetail,
  69. qc,
  70. warehouse,
  71. }) => {
  72. console.log(warehouse);
  73. // 修改翻译键
  74. const {
  75. t,
  76. i18n: { language },
  77. } = useTranslation("pickOrder");
  78. const [qcItems, setQcItems] = useState(dummyQCData)
  79. const formProps = useForm<any>({
  80. defaultValues: {
  81. ...itemDetail,
  82. },
  83. });
  84. const closeHandler = useCallback<NonNullable<ModalProps["onClose"]>>(
  85. (...args) => {
  86. onClose?.(...args);
  87. },
  88. [onClose],
  89. );
  90. // QC submission handler
  91. const onSubmitQc = useCallback<SubmitHandler<any>>(
  92. async (data, event) => {
  93. console.log("QC Submission:", event!.nativeEvent);
  94. // Get QC data from the shared form context
  95. const qcAccept = data.qcAccept;
  96. const acceptQty = data.acceptQty;
  97. // Validate QC data
  98. const validationErrors : string[] = [];
  99. // Check if all QC items have results
  100. const itemsWithoutResult = qcItems.filter(item => item.isPassed === undefined);
  101. if (itemsWithoutResult.length > 0) {
  102. validationErrors.push(`${t("QC items without result")}: ${itemsWithoutResult.map(item => item.qcItem).join(', ')}`);
  103. }
  104. // Check if failed items have failed quantity
  105. const failedItemsWithoutQty = qcItems.filter(item =>
  106. item.isPassed === false && (!item.failedQty || item.failedQty <= 0)
  107. );
  108. if (failedItemsWithoutQty.length > 0) {
  109. validationErrors.push(`${t("Failed items must have failed quantity")}: ${failedItemsWithoutQty.map(item => item.qcItem).join(', ')}`);
  110. }
  111. // Check if accept quantity is valid
  112. if (acceptQty === undefined || acceptQty <= 0) {
  113. validationErrors.push("Accept quantity must be greater than 0");
  114. }
  115. if (validationErrors.length > 0) {
  116. console.error("QC Validation failed:", validationErrors);
  117. alert(`未完成品檢: ${validationErrors}`);
  118. return;
  119. }
  120. const qcData = {
  121. qcAccept: qcAccept,
  122. acceptQty: acceptQty,
  123. qcItems: qcItems.map(item => ({
  124. id: item.id,
  125. qcItem: item.qcItem,
  126. qcDescription: item.qcDescription,
  127. isPassed: item.isPassed,
  128. failedQty: (item.failedQty && !item.isPassed) || 0,
  129. remarks: item.remarks || ''
  130. }))
  131. };
  132. console.log("QC Data for submission:", qcData);
  133. // await submitQcData(qcData);
  134. if (!qcData.qcItems.every((qc) => qc.isPassed) && qcData.qcAccept) {
  135. submitDialogWithWarning(() => {
  136. console.log("QC accepted with failed items");
  137. onClose();
  138. }, t, {title:"有不合格檢查項目,確認接受收貨?", confirmButtonText: "Confirm", html: ""});
  139. return;
  140. }
  141. if (qcData.qcAccept) {
  142. console.log("QC accepted");
  143. onClose();
  144. } else {
  145. console.log("QC rejected");
  146. onClose();
  147. }
  148. },
  149. [qcItems, onClose, t],
  150. );
  151. const handleQcItemChange = useCallback((index: number, field: keyof QcData, value: any) => {
  152. setQcItems(prev => prev.map((item, i) =>
  153. i === index ? { ...item, [field]: value } : item
  154. ));
  155. }, []);
  156. return (
  157. <>
  158. <FormProvider {...formProps}>
  159. <Modal open={open} onClose={closeHandler}>
  160. <Box
  161. sx={{
  162. ...style,
  163. padding: 2,
  164. maxHeight: "90vh",
  165. overflowY: "auto",
  166. marginLeft: 3,
  167. marginRight: 3,
  168. }}
  169. >
  170. <Grid container justifyContent="flex-start" alignItems="flex-start">
  171. <Grid item xs={12}>
  172. <Typography variant="h6" display="block" marginBlockEnd={1}>
  173. GroupA - {itemDetail.pickOrderCode}
  174. </Typography>
  175. <Typography variant="body2" color="text.secondary" marginBlockEnd={2}>
  176. 記錄探測溫度的時間,請在1小時內完成出庫,以保障食品安全 監察方法、日闸檢查、嗅覺檢查和使用適當的食物温度計椒鱼食物溫度是否符合指標
  177. </Typography>
  178. </Grid>
  179. {/* QC 表格 */}
  180. <Grid item xs={12}>
  181. <TableContainer component={Paper}>
  182. <Table>
  183. <TableHead>
  184. <TableRow>
  185. <TableCell>QC模板代號</TableCell>
  186. <TableCell>檢查項目</TableCell>
  187. <TableCell>QC Result</TableCell>
  188. <TableCell>Failed Qty</TableCell>
  189. <TableCell>Remarks</TableCell>
  190. </TableRow>
  191. </TableHead>
  192. <TableBody>
  193. {qcItems.map((item, index) => (
  194. <TableRow key={item.id}>
  195. <TableCell>{item.id}</TableCell>
  196. <TableCell>{item.qcDescription}</TableCell>
  197. <TableCell>
  198. <select
  199. value={item.isPassed === undefined ? '' : item.isPassed ? 'pass' : 'fail'}
  200. onChange={(e) => handleQcItemChange(index, 'isPassed', e.target.value === 'pass')}
  201. >
  202. <option value="">Select</option>
  203. <option value="pass">Pass</option>
  204. <option value="fail">Fail</option>
  205. </select>
  206. </TableCell>
  207. <TableCell>
  208. <input
  209. type="number"
  210. value={item.failedQty || 0}
  211. onChange={(e) => handleQcItemChange(index, 'failedQty', parseInt(e.target.value) || 0)}
  212. disabled={item.isPassed !== false}
  213. />
  214. </TableCell>
  215. <TableCell>
  216. <input
  217. type="text"
  218. value={item.remarks || ''}
  219. onChange={(e) => handleQcItemChange(index, 'remarks', e.target.value)}
  220. />
  221. </TableCell>
  222. </TableRow>
  223. ))}
  224. </TableBody>
  225. </Table>
  226. </TableContainer>
  227. </Grid>
  228. {/* 按钮 */}
  229. <Grid item xs={12} sx={{ mt: 2 }}>
  230. <Stack direction="row" justifyContent="flex-end" gap={1}>
  231. <Button
  232. variant="contained"
  233. color="success"
  234. onClick={formProps.handleSubmit(onSubmitQc)}
  235. >
  236. QC Accept
  237. </Button>
  238. <Button
  239. variant="contained"
  240. color="warning"
  241. onClick={() => {
  242. console.log("Sort to accept");
  243. onClose();
  244. }}
  245. >
  246. Sort to Accept
  247. </Button>
  248. <Button
  249. variant="contained"
  250. color="error"
  251. onClick={() => {
  252. console.log("Reject and pick another lot");
  253. onClose();
  254. }}
  255. >
  256. Reject and Pick Another Lot
  257. </Button>
  258. </Stack>
  259. </Grid>
  260. </Grid>
  261. </Box>
  262. </Modal>
  263. </FormProvider>
  264. </>
  265. );
  266. };
  267. export default PickQcStockInModalVer2;