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.

QcFormOld.tsx 9.1 KiB

9 月之前
4 月之前
7 月之前
8 月之前
8 月之前
8 月之前
8 月之前
8 月之前
8 月之前
9 月之前
8 月之前
8 月之前
9 月之前
8 月之前
8 月之前
8 月之前
4 月之前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. "use client";
  2. import { PurchaseQcResult, 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, useEffect, 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 { GridEditInputCell } from "@mui/x-data-grid";
  31. import { StockInLine } from "@/app/api/po";
  32. import { stockInLineStatusMap } from "@/app/utils/formatUtil";
  33. import { fetchQcItemCheck, fetchQcResult } from "@/app/api/qc/actions";
  34. import { QcItemWithChecks } from "@/app/api/qc";
  35. import axios from "@/app/(main)/axios/axiosInstance";
  36. import { NEXT_PUBLIC_API_URL } from "@/config/api";
  37. import axiosInstance from "@/app/(main)/axios/axiosInstance";
  38. interface Props {
  39. itemDetail: StockInLine;
  40. qc: QcItemWithChecks[];
  41. disabled: boolean;
  42. }
  43. type EntryError =
  44. | {
  45. [field in keyof PurchaseQcResult]?: string;
  46. }
  47. | undefined;
  48. type PoQcRow = TableRow<Partial<PurchaseQcResult>, EntryError>;
  49. // fetchQcItemCheck
  50. const QcFormOld: React.FC<Props> = ({ qc, itemDetail, disabled }) => {
  51. const { t } = useTranslation("purchaseOrder");
  52. const apiRef = useGridApiRef();
  53. const {
  54. register,
  55. formState: { errors, defaultValues, touchedFields },
  56. watch,
  57. control,
  58. setValue,
  59. getValues,
  60. reset,
  61. resetField,
  62. setError,
  63. clearErrors,
  64. } = useFormContext<PurchaseQCInput>();
  65. console.log(itemDetail);
  66. console.log(defaultValues);
  67. //// validate form
  68. const accQty = watch("acceptedQty");
  69. const validateForm = useCallback(() => {
  70. console.log(accQty);
  71. if (accQty > itemDetail.acceptedQty) {
  72. setError("acceptedQty", {
  73. message: `${t("acceptedQty must not greater than")} ${
  74. itemDetail.acceptedQty
  75. }`,
  76. type: "required",
  77. });
  78. }
  79. if (accQty < 1) {
  80. setError("acceptedQty", {
  81. message: t("minimal value is 1"),
  82. type: "required",
  83. });
  84. }
  85. if (isNaN(accQty)) {
  86. setError("acceptedQty", {
  87. message: t("value must be a number"),
  88. type: "required",
  89. });
  90. }
  91. }, [accQty]);
  92. useEffect(() => {
  93. clearErrors();
  94. validateForm();
  95. }, [clearErrors, validateForm]);
  96. const columns = useMemo<GridColDef[]>(
  97. () => [
  98. {
  99. field: "qcItemId",
  100. headerName: t("qc Check"),
  101. flex: 1,
  102. editable: !disabled,
  103. valueFormatter(params) {
  104. const row = params.id ? params.api.getRow<PoQcRow>(params.id) : null;
  105. if (!row) {
  106. return null;
  107. }
  108. const Qc = qc.find((q) => q.id === row.qcItemId);
  109. return Qc ? `${Qc.code} - ${Qc.name}` : t("Please select QC");
  110. },
  111. renderCell(params: GridRenderCellParams<PoQcRow, number>) {
  112. console.log(params.value);
  113. return <TwoLineCell>{params.formattedValue}</TwoLineCell>;
  114. },
  115. renderEditCell(params: GridRenderEditCellParams<PoQcRow, number>) {
  116. const errorMessage =
  117. params.row._error?.[params.field as keyof PurchaseQcResult];
  118. console.log(errorMessage);
  119. const content = (
  120. <QcSelect
  121. allQcs={qc}
  122. value={params.row.qcItemId}
  123. onQcSelect={async (qcItemId) => {
  124. await params.api.setEditCellValue({
  125. id: params.id,
  126. field: "qcItemId",
  127. value: qcItemId,
  128. });
  129. // await params.api.setEditCellValue({
  130. // id: params.id,
  131. // field: "type",
  132. // value: "determine1",
  133. // });
  134. }}
  135. />
  136. );
  137. return errorMessage ? (
  138. <Tooltip title={errorMessage}>
  139. <Box width="100%">{content}</Box>
  140. </Tooltip>
  141. ) : (
  142. content
  143. );
  144. },
  145. },
  146. {
  147. field: "failQty",
  148. headerName: t("failQty"),
  149. flex: 1,
  150. editable: !disabled,
  151. type: "number",
  152. renderEditCell(params: GridRenderEditCellParams<PoQcRow>) {
  153. // const recordQty = params.row.qty
  154. // if (recordQty !== undefined) {
  155. // setUnrecordQty((prev) => prev - recordQty)
  156. // }
  157. const errorMessage =
  158. params.row._error?.[params.field as keyof PurchaseQcResult];
  159. const content = <GridEditInputCell {...params} />;
  160. return errorMessage ? (
  161. <Tooltip title={t(errorMessage)}>
  162. <Box width="100%">{content}</Box>
  163. </Tooltip>
  164. ) : (
  165. content
  166. );
  167. },
  168. },
  169. ],
  170. [qc],
  171. );
  172. /// validate datagrid
  173. const validation = useCallback(
  174. (newRow: GridRowModel<PoQcRow>): EntryError => {
  175. const error: EntryError = {};
  176. const { qcItemId, failQty } = newRow;
  177. if (!qcItemId || qcItemId <= 0) {
  178. error["qcItemId"] = t("select qc");
  179. }
  180. if (!failQty || failQty <= 0) {
  181. error["failQty"] = t("enter a failQty");
  182. }
  183. if (failQty && failQty > itemDetail.acceptedQty) {
  184. error["failQty"] = t("qty too big");
  185. }
  186. return Object.keys(error).length > 0 ? error : undefined;
  187. },
  188. [],
  189. );
  190. useEffect(() => {
  191. console.log(itemDetail);
  192. const status = "receiving";
  193. // switch (itemDetail.status) {
  194. // case 'pending':
  195. // status = "receiving"
  196. // break;
  197. // }
  198. setValue("status", status);
  199. }, [itemDetail]);
  200. return (
  201. <Grid container justifyContent="flex-start" alignItems="flex-start">
  202. <Grid item xs={12}>
  203. <Typography variant="h6" display="block" marginBlockEnd={1}>
  204. {t("Qc Detail")}
  205. </Typography>
  206. </Grid>
  207. <Grid
  208. container
  209. justifyContent="flex-start"
  210. alignItems="flex-start"
  211. spacing={2}
  212. sx={{ mt: 0.5 }}
  213. >
  214. <Grid item xs={12} lg={12}>
  215. <TextField
  216. label={t("accepted Qty")}
  217. fullWidth
  218. // value={itemDetail.acceptedQty}
  219. {...register("acceptedQty", {
  220. required: "acceptedQty required!",
  221. valueAsNumber: true,
  222. max: itemDetail.acceptedQty,
  223. })}
  224. disabled={disabled}
  225. error={Boolean(errors.acceptedQty)}
  226. helperText={errors.acceptedQty?.message}
  227. />
  228. </Grid>
  229. {/* <Grid item xs={12} lg={6}>
  230. <TextField
  231. label={t("Total record qty")}
  232. fullWidth
  233. value={recordQty}
  234. disabled
  235. // {...register("sampleRate", {
  236. // required: "sampleRate required!",
  237. // })}
  238. // error={Boolean(errors.sampleRate)}
  239. // helperText={errors.sampleRate?.message}
  240. />
  241. </Grid> */}
  242. {/* <Grid item xs={12} lg={6}>
  243. <TextField
  244. label={t("sampleRate")}
  245. fullWidth
  246. // defaultValue={1}
  247. {...register("sampleRate", {
  248. required: "sampleRate required!",
  249. valueAsNumber: true,
  250. })}
  251. disabled={disabled}
  252. error={Boolean(errors.sampleRate)}
  253. helperText={errors.sampleRate?.message}
  254. />
  255. </Grid>
  256. <Grid item xs={12} lg={6}>
  257. <TextField
  258. label={t("sampleWeight")}
  259. fullWidth
  260. // defaultValue={1}
  261. {...register("sampleWeight", {
  262. required: "sampleWeight required!",
  263. valueAsNumber: true,
  264. })}
  265. disabled={disabled}
  266. error={Boolean(errors.sampleWeight)}
  267. helperText={errors.sampleWeight?.message}
  268. />
  269. </Grid>
  270. <Grid item xs={12} lg={6}>
  271. <TextField
  272. label={t("totalWeight")}
  273. fullWidth
  274. // defaultValue={1}
  275. {...register("totalWeight", {
  276. required: "totalWeight required!",
  277. valueAsNumber: true,
  278. })}
  279. disabled={disabled}
  280. error={Boolean(errors.totalWeight)}
  281. helperText={errors.totalWeight?.message}
  282. />
  283. </Grid> */}
  284. </Grid>
  285. <Grid
  286. container
  287. justifyContent="flex-start"
  288. alignItems="flex-start"
  289. spacing={2}
  290. sx={{ mt: 0.5 }}
  291. >
  292. <Grid item xs={12}>
  293. <InputDataGrid<PurchaseQCInput, PurchaseQcResult, EntryError>
  294. apiRef={apiRef}
  295. checkboxSelection={false}
  296. _formKey={"qcResult"}
  297. columns={columns}
  298. validateRow={validation}
  299. needAdd={
  300. itemDetail.status === "qc" || itemDetail.status === "pending"
  301. }
  302. />
  303. </Grid>
  304. </Grid>
  305. </Grid>
  306. );
  307. };
  308. export default QcFormOld;