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.
 
 
 

319 lines
9.8 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("purchaseOrder");
  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. flex: 1,
  105. editable: true,
  106. valueFormatter(params) {
  107. const row = params.id ? params.api.getRow<PolRow>(params.id) : null;
  108. if (!row) {
  109. return null;
  110. }
  111. const Item = items.find((q) => q.id === row.itemId);
  112. return Item ? Item.label : t("Please select item");
  113. },
  114. renderCell(params: GridRenderCellParams<PolRow, number>) {
  115. console.log(params.value);
  116. return <TwoLineCell>{params.formattedValue}</TwoLineCell>;
  117. },
  118. renderEditCell(params: GridRenderEditCellParams<PolRow, number>) {
  119. const errorMessage =
  120. params.row._error?.[params.field as keyof SavePickOrderLineRequest];
  121. console.log(errorMessage);
  122. const content = (
  123. // <></>
  124. <ItemSelect
  125. allItems={items}
  126. value={params.row.itemId}
  127. onItemSelect={async (itemId, uom, uomId) => {
  128. console.log(uom)
  129. await params.api.setEditCellValue({
  130. id: params.id,
  131. field: "itemId",
  132. value: itemId,
  133. });
  134. await params.api.setEditCellValue({
  135. id: params.id,
  136. field: "uom",
  137. value: uom
  138. })
  139. await params.api.setEditCellValue({
  140. id: params.id,
  141. field: "uomId",
  142. value: uomId
  143. })
  144. }}
  145. />
  146. );
  147. return errorMessage ? (
  148. <Tooltip title={errorMessage}>
  149. <Box width="100%">{content}</Box>
  150. </Tooltip>
  151. ) : (
  152. content
  153. );
  154. },
  155. },
  156. {
  157. field: "qty",
  158. headerName: t("qty"),
  159. flex: 1,
  160. type: "number",
  161. editable: true,
  162. renderEditCell(params: GridRenderEditCellParams<PolRow>) {
  163. const errorMessage =
  164. params.row._error?.[params.field as keyof SavePickOrderLineRequest];
  165. const content = <GridEditInputCell {...params} />;
  166. return errorMessage ? (
  167. <Tooltip title={t(errorMessage)}>
  168. <Box width="100%">{content}</Box>
  169. </Tooltip>
  170. ) : (
  171. content
  172. );
  173. },
  174. },
  175. {
  176. field: "uom",
  177. headerName: t("uom"),
  178. flex: 1,
  179. editable: true,
  180. // renderEditCell(params: GridRenderEditCellParams<PolRow>) {
  181. // console.log(params.row)
  182. // const errorMessage =
  183. // params.row._error?.[params.field as keyof SavePickOrderLineRequest];
  184. // const content = <GridEditInputCell {...params} />;
  185. // return errorMessage ? (
  186. // <Tooltip title={t(errorMessage)}>
  187. // <Box width="100%">{content}</Box>
  188. // </Tooltip>
  189. // ) : (
  190. // content
  191. // );
  192. // }
  193. }
  194. ],
  195. [items, t],
  196. );
  197. /// validate datagrid
  198. const validation = useCallback(
  199. (newRow: GridRowModel<PolRow>): EntryError => {
  200. const error: EntryError = {};
  201. const { itemId, qty } = newRow;
  202. if (!itemId || itemId <= 0) {
  203. error["itemId"] = t("select qc");
  204. }
  205. if (!qty || qty <= 0) {
  206. error["qty"] = t("enter a qty");
  207. }
  208. return Object.keys(error).length > 0 ? error : undefined;
  209. },
  210. [],
  211. );
  212. const typeList = [
  213. {
  214. type: "Consumable"
  215. }
  216. ]
  217. const onChange = useCallback(
  218. (event: React.SyntheticEvent, newValue: {type: string}) => {
  219. console.log(newValue);
  220. setValue("type", newValue.type);
  221. },
  222. [setValue],
  223. );
  224. return (
  225. <Grid container justifyContent="flex-start" alignItems="flex-start">
  226. <Grid item xs={12}>
  227. <Typography variant="h6" display="block" marginBlockEnd={1}>
  228. {t("Pick Order Detail")}
  229. </Typography>
  230. </Grid>
  231. <Grid
  232. container
  233. justifyContent="flex-start"
  234. alignItems="flex-start"
  235. spacing={2}
  236. sx={{ mt: 0.5 }}
  237. >
  238. <Grid item xs={6} lg={6}>
  239. <FormControl fullWidth>
  240. <Autocomplete
  241. disableClearable
  242. fullWidth
  243. getOptionLabel={(option) => option.type}
  244. options={typeList}
  245. onChange={onChange}
  246. renderInput={(params) => <TextField {...params} label={t("type")}/>}
  247. />
  248. </FormControl>
  249. </Grid>
  250. <Grid item xs={6}>
  251. <Controller
  252. control={control}
  253. name="targetDate"
  254. // rules={{ required: !Boolean(productionDate) }}
  255. render={({ field }) => {
  256. return (
  257. <LocalizationProvider
  258. dateAdapter={AdapterDayjs}
  259. adapterLocale={`${language}-hk`}
  260. >
  261. <DatePicker
  262. {...field}
  263. sx={{ width: "100%" }}
  264. label={t("targetDate")}
  265. value={targetDate ? dayjs(targetDate) : undefined}
  266. onChange={(date) => {
  267. console.log(date);
  268. if (!date) return;
  269. console.log(date.format(INPUT_DATE_FORMAT));
  270. setValue("targetDate", date.format(INPUT_DATE_FORMAT));
  271. // field.onChange(date);
  272. }}
  273. inputRef={field.ref}
  274. slotProps={{
  275. textField: {
  276. // required: true,
  277. error: Boolean(errors.targetDate?.message),
  278. helperText: errors.targetDate?.message,
  279. },
  280. }}
  281. />
  282. </LocalizationProvider>
  283. );
  284. }}
  285. />
  286. </Grid>
  287. </Grid>
  288. <Grid
  289. container
  290. justifyContent="flex-start"
  291. alignItems="flex-start"
  292. spacing={2}
  293. sx={{ mt: 0.5 }}
  294. >
  295. <Grid item xs={12}>
  296. <InputDataGrid<SavePickOrderRequest, SavePickOrderLineRequest, EntryError>
  297. apiRef={apiRef}
  298. checkboxSelection={false}
  299. _formKey={"pickOrderLine"}
  300. columns={columns}
  301. validateRow={validation}
  302. needAdd={true}
  303. />
  304. </Grid>
  305. </Grid>
  306. </Grid>
  307. );
  308. };
  309. export default CreateForm;