FPSMS-frontend
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

250 行
6.9 KiB

  1. "use client";
  2. import { PurchaseQcCheck, PurchaseQCInput } from "@/app/api/po/actions";
  3. import {
  4. Box,
  5. Card,
  6. CardContent,
  7. Grid,
  8. Stack,
  9. TextField,
  10. Tooltip,
  11. Typography,
  12. } from "@mui/material";
  13. import { useFormContext } from "react-hook-form";
  14. import { useTranslation } from "react-i18next";
  15. import StyledDataGrid from "../StyledDataGrid";
  16. import { useCallback, useMemo, useState } from "react";
  17. import {
  18. GridColDef,
  19. GridRowIdGetter,
  20. GridRowModel,
  21. useGridApiContext,
  22. GridRenderCellParams,
  23. GridRenderEditCellParams,
  24. useGridApiRef,
  25. } from "@mui/x-data-grid";
  26. import InputDataGrid from "../InputDataGrid";
  27. import { TableRow } from "../InputDataGrid/InputDataGrid";
  28. import TwoLineCell from "./TwoLineCell";
  29. import QcSelect from "./QcSelect";
  30. import { QcItemWithChecks } from "@/app/api/qc";
  31. import { GridEditInputCell } from "@mui/x-data-grid";
  32. import { StockInLine } from "@/app/api/po";
  33. interface Props {
  34. itemDetail: StockInLine;
  35. qc: QcItemWithChecks[];
  36. }
  37. type EntryError =
  38. | {
  39. [field in keyof PurchaseQcCheck]?: string;
  40. }
  41. | undefined;
  42. type PoQcRow = TableRow<Partial<PurchaseQcCheck>, EntryError>;
  43. const QcForm: React.FC<Props> = ({
  44. qc,
  45. itemDetail,
  46. }) => {
  47. const { t } = useTranslation();
  48. const apiRef = useGridApiRef();
  49. const {
  50. register,
  51. formState: { errors, defaultValues, touchedFields },
  52. watch,
  53. control,
  54. setValue,
  55. getValues,
  56. reset,
  57. resetField,
  58. setError,
  59. clearErrors,
  60. } = useFormContext<PurchaseQCInput>();
  61. console.log(itemDetail)
  62. const [recordQty, setRecordQty] = useState(0)
  63. const columns = useMemo<GridColDef[]>(
  64. () => [
  65. {
  66. field: "qcCheckId",
  67. headerName: "qc Check",
  68. flex: 1,
  69. editable: true,
  70. valueFormatter(params) {
  71. const row = params.id ? params.api.getRow<PoQcRow>(params.id) : null;
  72. if (!row) {
  73. return null;
  74. }
  75. const Qc = qc.find((q) => q.id === row.qcCheckId);
  76. return Qc ? `${Qc.code} - ${Qc.name}` : t("Please select QC");
  77. },
  78. renderCell(params: GridRenderCellParams<PoQcRow, number>) {
  79. console.log(params.value);
  80. return <TwoLineCell>{params.formattedValue}</TwoLineCell>;
  81. },
  82. renderEditCell(params: GridRenderEditCellParams<PoQcRow, number>) {
  83. const errorMessage =
  84. params.row._error?.[params.field as keyof PurchaseQcCheck];
  85. console.log(errorMessage);
  86. const content = (
  87. <QcSelect
  88. allQcs={qc}
  89. value={params.row.qcCheckId}
  90. onQcSelect={async (qcCheckId) => {
  91. await params.api.setEditCellValue({
  92. id: params.id,
  93. field: "qcCheckId",
  94. value: qcCheckId,
  95. });
  96. }}
  97. />
  98. );
  99. return errorMessage ? (
  100. <Tooltip title={t(errorMessage)}>
  101. <Box width="100%">{content}</Box>
  102. </Tooltip>
  103. ) : (
  104. content
  105. );
  106. },
  107. },
  108. {
  109. field: "qty",
  110. headerName: "qty",
  111. flex: 1,
  112. editable: true,
  113. type: "number",
  114. renderEditCell(params: GridRenderEditCellParams<PoQcRow>) {
  115. // const recordQty = params.row.qty
  116. // if (recordQty !== undefined) {
  117. // setUnrecordQty((prev) => prev - recordQty)
  118. // }
  119. const errorMessage =
  120. params.row._error?.[params.field as keyof PurchaseQcCheck];
  121. const content = <GridEditInputCell {...params} />;
  122. return errorMessage ? (
  123. <Tooltip title={t(errorMessage)}>
  124. <Box width="100%">{content}</Box>
  125. </Tooltip>
  126. ) : (
  127. content
  128. );
  129. },
  130. },
  131. ],
  132. []
  133. );
  134. const validation = useCallback(
  135. (newRow: GridRowModel<PoQcRow>): EntryError => {
  136. const error: EntryError = {};
  137. const { qcCheckId, qty } = newRow;
  138. if (!qcCheckId || qcCheckId <= 0) {
  139. error["qcCheckId"] = "select qc";
  140. }
  141. if (!qty || qty <= 0) {
  142. error["qty"] = "enter a qty";
  143. }
  144. if (qty && qty > itemDetail.acceptedQty) {
  145. error["qty"] = "qty too big";
  146. }
  147. return Object.keys(error).length > 0 ? error : undefined;
  148. },
  149. []
  150. );
  151. return (
  152. <Grid container justifyContent="flex-start" alignItems="flex-start">
  153. <Grid item xs={12}>
  154. <Typography variant="h6" display="block" marginBlockEnd={1}>
  155. {t("Qc Detail")}
  156. </Typography>
  157. </Grid>
  158. <Grid
  159. container
  160. justifyContent="flex-start"
  161. alignItems="flex-start"
  162. spacing={2}
  163. sx={{ mt: 0.5 }}
  164. >
  165. <Grid item xs={6}>
  166. <TextField
  167. label={t("Total qty")}
  168. fullWidth
  169. value={itemDetail.acceptedQty}
  170. disabled
  171. // {...register("sampleRate", {
  172. // required: "sampleRate required!",
  173. // })}
  174. // error={Boolean(errors.sampleRate)}
  175. // helperText={errors.sampleRate?.message}
  176. />
  177. </Grid>
  178. <Grid item xs={6}>
  179. <TextField
  180. label={t("Total record qty")}
  181. fullWidth
  182. value={recordQty}
  183. disabled
  184. // {...register("sampleRate", {
  185. // required: "sampleRate required!",
  186. // })}
  187. // error={Boolean(errors.sampleRate)}
  188. // helperText={errors.sampleRate?.message}
  189. />
  190. </Grid>
  191. <Grid item xs={4}>
  192. <TextField
  193. label={t("sampleRate")}
  194. fullWidth
  195. {...register("sampleRate", {
  196. required: "sampleRate required!",
  197. })}
  198. error={Boolean(errors.sampleRate)}
  199. helperText={errors.sampleRate?.message}
  200. />
  201. </Grid>
  202. <Grid item xs={4}>
  203. <TextField
  204. label={t("sampleWeight")}
  205. fullWidth
  206. {...register("sampleWeight", {
  207. required: "sampleWeight required!",
  208. })}
  209. error={Boolean(errors.sampleWeight)}
  210. helperText={errors.sampleWeight?.message}
  211. />
  212. </Grid>
  213. <Grid item xs={4}>
  214. <TextField
  215. label={t("totalWeight")}
  216. fullWidth
  217. {...register("totalWeight", {
  218. required: "totalWeight required!",
  219. })}
  220. error={Boolean(errors.totalWeight)}
  221. helperText={errors.totalWeight?.message}
  222. />
  223. </Grid>
  224. </Grid>
  225. <Grid
  226. container
  227. justifyContent="flex-start"
  228. alignItems="flex-start"
  229. spacing={2}
  230. sx={{ mt: 0.5 }}
  231. >
  232. <Grid item xs={12}>
  233. <InputDataGrid<PurchaseQCInput, PurchaseQcCheck, EntryError>
  234. apiRef={apiRef}
  235. checkboxSelection={false}
  236. _formKey={"qcCheck"}
  237. columns={columns}
  238. validateRow={validation}
  239. />
  240. </Grid>
  241. </Grid>
  242. </Grid>
  243. );
  244. };
  245. export default QcForm;