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.
 
 

322 lines
9.6 KiB

  1. "use client";
  2. import { PurchaseQcResult, PurchaseQCInput } from "@/app/api/po/actions";
  3. import {
  4. Autocomplete,
  5. Box,
  6. Card,
  7. CardContent,
  8. FormControl,
  9. Grid,
  10. Stack,
  11. TextField,
  12. Tooltip,
  13. Typography,
  14. } from "@mui/material";
  15. import { Controller, useFormContext } from "react-hook-form";
  16. import { useTranslation } from "react-i18next";
  17. import StyledDataGrid from "../StyledDataGrid";
  18. import { useCallback, useEffect, useMemo, useState } from "react";
  19. import {
  20. GridColDef,
  21. GridRowIdGetter,
  22. GridRowModel,
  23. useGridApiContext,
  24. GridRenderCellParams,
  25. GridRenderEditCellParams,
  26. useGridApiRef,
  27. } from "@mui/x-data-grid";
  28. import InputDataGrid from "../InputDataGrid";
  29. import { TableRow } from "../InputDataGrid/InputDataGrid";
  30. import { GridEditInputCell } from "@mui/x-data-grid";
  31. import { StockInLine } from "@/app/api/po";
  32. import { INPUT_DATE_FORMAT, 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. import { SavePickOrderLineRequest, SavePickOrderRequest } from "@/app/api/pickOrder/actions";
  39. import TwoLineCell from "../PoDetail/TwoLineCell";
  40. import ItemSelect from "./ItemSelect";
  41. import { ItemCombo } from "@/app/api/settings/item/actions";
  42. import { DatePicker, LocalizationProvider } from "@mui/x-date-pickers";
  43. import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
  44. import dayjs from "dayjs";
  45. interface Props {
  46. items: ItemCombo[];
  47. // disabled: boolean;
  48. }
  49. type EntryError =
  50. | {
  51. [field in keyof SavePickOrderLineRequest]?: string;
  52. }
  53. | undefined;
  54. type PolRow = TableRow<Partial<SavePickOrderLineRequest>, EntryError>;
  55. // fetchQcItemCheck
  56. const CreateForm: React.FC<Props> = ({ items }) => {
  57. const {
  58. t,
  59. i18n: { language },
  60. } = useTranslation("pickOrder");
  61. const apiRef = useGridApiRef();
  62. const {
  63. formState: { errors, defaultValues, touchedFields },
  64. watch,
  65. control,
  66. setValue,
  67. } = useFormContext<SavePickOrderRequest>();
  68. console.log(defaultValues);
  69. const targetDate = watch("targetDate");
  70. //// validate form
  71. // const accQty = watch("acceptedQty");
  72. // const validateForm = useCallback(() => {
  73. // console.log(accQty);
  74. // if (accQty > itemDetail.acceptedQty) {
  75. // setError("acceptedQty", {
  76. // message: `${t("acceptedQty must not greater than")} ${
  77. // itemDetail.acceptedQty
  78. // }`,
  79. // type: "required",
  80. // });
  81. // }
  82. // if (accQty < 1) {
  83. // setError("acceptedQty", {
  84. // message: t("minimal value is 1"),
  85. // type: "required",
  86. // });
  87. // }
  88. // if (isNaN(accQty)) {
  89. // setError("acceptedQty", {
  90. // message: t("value must be a number"),
  91. // type: "required",
  92. // });
  93. // }
  94. // }, [accQty]);
  95. // useEffect(() => {
  96. // clearErrors();
  97. // validateForm();
  98. // }, [clearErrors, validateForm]);
  99. const columns = useMemo<GridColDef[]>(
  100. () => [
  101. {
  102. field: "itemId",
  103. headerName: t("Item"),
  104. // width: 100,
  105. flex: 1,
  106. editable: true,
  107. valueFormatter(params) {
  108. const row = params.id ? params.api.getRow<PolRow>(params.id) : null;
  109. if (!row) {
  110. return null;
  111. }
  112. const Item = items.find((q) => q.id === row.itemId);
  113. return Item ? Item.label : t("Please select item");
  114. },
  115. renderCell(params: GridRenderCellParams<PolRow, number>) {
  116. console.log(params.value);
  117. return <TwoLineCell>{params.formattedValue}</TwoLineCell>;
  118. },
  119. renderEditCell(params: GridRenderEditCellParams<PolRow, number>) {
  120. const errorMessage =
  121. params.row._error?.[params.field as keyof SavePickOrderLineRequest];
  122. console.log(errorMessage);
  123. const content = (
  124. // <></>
  125. <ItemSelect
  126. allItems={items}
  127. value={params.row.itemId}
  128. onItemSelect={async (itemId, uom, uomId) => {
  129. console.log(uom)
  130. await params.api.setEditCellValue({
  131. id: params.id,
  132. field: "itemId",
  133. value: itemId,
  134. });
  135. await params.api.setEditCellValue({
  136. id: params.id,
  137. field: "uom",
  138. value: uom
  139. })
  140. await params.api.setEditCellValue({
  141. id: params.id,
  142. field: "uomId",
  143. value: uomId
  144. })
  145. }}
  146. />
  147. );
  148. return errorMessage ? (
  149. <Tooltip title={errorMessage}>
  150. <Box width="100%">{content}</Box>
  151. </Tooltip>
  152. ) : (
  153. content
  154. );
  155. },
  156. },
  157. {
  158. field: "qty",
  159. headerName: t("qty"),
  160. // width: 100,
  161. flex: 1,
  162. type: "number",
  163. editable: true,
  164. renderEditCell(params: GridRenderEditCellParams<PolRow>) {
  165. const errorMessage =
  166. params.row._error?.[params.field as keyof SavePickOrderLineRequest];
  167. const content = <GridEditInputCell {...params} />;
  168. return errorMessage ? (
  169. <Tooltip title={t(errorMessage)}>
  170. <Box width="100%">{content}</Box>
  171. </Tooltip>
  172. ) : (
  173. content
  174. );
  175. },
  176. },
  177. {
  178. field: "uom",
  179. headerName: t("uom"),
  180. // width: 100,
  181. flex: 1,
  182. editable: true,
  183. // renderEditCell(params: GridRenderEditCellParams<PolRow>) {
  184. // console.log(params.row)
  185. // const errorMessage =
  186. // params.row._error?.[params.field as keyof SavePickOrderLineRequest];
  187. // const content = <GridEditInputCell {...params} />;
  188. // return errorMessage ? (
  189. // <Tooltip title={t(errorMessage)}>
  190. // <Box width="100%">{content}</Box>
  191. // </Tooltip>
  192. // ) : (
  193. // content
  194. // );
  195. // }
  196. }
  197. ],
  198. [items, t],
  199. );
  200. /// validate datagrid
  201. const validation = useCallback(
  202. (newRow: GridRowModel<PolRow>): EntryError => {
  203. const error: EntryError = {};
  204. const { itemId, qty } = newRow;
  205. if (!itemId || itemId <= 0) {
  206. error["itemId"] = t("select qc");
  207. }
  208. if (!qty || qty <= 0) {
  209. error["qty"] = t("enter a qty");
  210. }
  211. return Object.keys(error).length > 0 ? error : undefined;
  212. },
  213. [],
  214. );
  215. const typeList = [
  216. {
  217. type: "Consumable"
  218. }
  219. ]
  220. const onChange = useCallback(
  221. (event: React.SyntheticEvent, newValue: {type: string}) => {
  222. console.log(newValue);
  223. setValue("type", newValue.type);
  224. },
  225. [setValue],
  226. );
  227. return (
  228. <Grid container justifyContent="flex-start" alignItems="flex-start">
  229. <Grid item xs={12}>
  230. <Typography variant="h6" display="block" marginBlockEnd={1}>
  231. {t("Pick Order Detail")}
  232. </Typography>
  233. </Grid>
  234. <Grid
  235. container
  236. justifyContent="flex-start"
  237. alignItems="flex-start"
  238. spacing={2}
  239. sx={{ mt: 0.5 }}
  240. >
  241. <Grid item xs={6} lg={6}>
  242. <FormControl fullWidth>
  243. <Autocomplete
  244. disableClearable
  245. fullWidth
  246. getOptionLabel={(option) => option.type}
  247. options={typeList}
  248. onChange={onChange}
  249. renderInput={(params) => <TextField {...params} label={t("type")}/>}
  250. />
  251. </FormControl>
  252. </Grid>
  253. <Grid item xs={6}>
  254. <Controller
  255. control={control}
  256. name="targetDate"
  257. // rules={{ required: !Boolean(productionDate) }}
  258. render={({ field }) => {
  259. return (
  260. <LocalizationProvider
  261. dateAdapter={AdapterDayjs}
  262. adapterLocale={`${language}-hk`}
  263. >
  264. <DatePicker
  265. {...field}
  266. sx={{ width: "100%" }}
  267. label={t("targetDate")}
  268. value={targetDate ? dayjs(targetDate) : undefined}
  269. onChange={(date) => {
  270. console.log(date);
  271. if (!date) return;
  272. console.log(date.format(INPUT_DATE_FORMAT));
  273. setValue("targetDate", date.format(INPUT_DATE_FORMAT));
  274. // field.onChange(date);
  275. }}
  276. inputRef={field.ref}
  277. slotProps={{
  278. textField: {
  279. // required: true,
  280. error: Boolean(errors.targetDate?.message),
  281. helperText: errors.targetDate?.message,
  282. },
  283. }}
  284. />
  285. </LocalizationProvider>
  286. );
  287. }}
  288. />
  289. </Grid>
  290. </Grid>
  291. <Grid
  292. container
  293. justifyContent="flex-start"
  294. alignItems="flex-start"
  295. spacing={2}
  296. sx={{ mt: 0.5 }}
  297. >
  298. <Grid item xs={12}>
  299. <InputDataGrid<SavePickOrderRequest, SavePickOrderLineRequest, EntryError>
  300. apiRef={apiRef}
  301. checkboxSelection={false}
  302. _formKey={"pickOrderLine"}
  303. columns={columns}
  304. validateRow={validation}
  305. needAdd={true}
  306. />
  307. </Grid>
  308. </Grid>
  309. </Grid>
  310. );
  311. };
  312. export default CreateForm;