|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537 |
- "use client";
-
- import { PutAwayInput, PutAwayLine } from "@/app/api/stockIn/actions";
- import {
- Autocomplete,
- Box,
- Button,
- Card,
- CardContent,
- FormControl,
- Grid,
- Modal,
- ModalProps,
- Stack,
- TextField,
- Tooltip,
- Typography,
- } from "@mui/material";
- import { Controller, useFormContext } from "react-hook-form";
- import { useTranslation } from "react-i18next";
- import StyledDataGrid from "../StyledDataGrid";
- import { Dispatch, SetStateAction, useCallback, useEffect, useMemo, useState } from "react";
- import {
- GridColDef,
- GridRowIdGetter,
- GridRowModel,
- useGridApiContext,
- GridRenderCellParams,
- GridRenderEditCellParams,
- useGridApiRef,
- GridRowSelectionModel,
- } from "@mui/x-data-grid";
- import InputDataGrid from "../InputDataGrid";
- import { TableRow } from "../InputDataGrid/InputDataGrid";
- import TwoLineCell from "./TwoLineCell";
- import QcSelect from "./QcSelect";
- import { QcItemWithChecks } from "@/app/api/qc";
- import { GridEditInputCell } from "@mui/x-data-grid";
- import { StockInLine } from "@/app/api/stockIn";
- import { WarehouseResult } from "@/app/api/warehouse";
- import {
- arrayToDateString,
- arrayToDateTimeString,
- OUTPUT_DATE_FORMAT,
- stockInLineStatusMap,
- } from "@/app/utils/formatUtil";
- import { QRCodeSVG } from "qrcode.react";
- import { QrCode } from "../QrCode";
- import ReactQrCodeScanner, {
- ScannerConfig,
- } from "../ReactQrCodeScanner/ReactQrCodeScanner";
- import { QrCodeInfo } from "@/app/api/qrcode";
- import { useQrCodeScannerContext } from "../QrCodeScannerProvider/QrCodeScannerProvider";
- import dayjs from "dayjs";
- import arraySupport from "dayjs/plugin/arraySupport";
- import { dummyPutAwayLine } from "./dummyQcTemplate";
- import { GridRowModesModel } from "@mui/x-data-grid";
- dayjs.extend(arraySupport);
-
- interface Props {
- itemDetail: StockInLine;
- warehouse?: WarehouseResult[];
- disabled: boolean;
- // qc: QcItemWithChecks[];
- setRowModesModel: Dispatch<SetStateAction<GridRowModesModel>>;
- setRowSelectionModel: Dispatch<SetStateAction<GridRowSelectionModel>>;
- }
- type EntryError =
- | {
- [field in keyof PutAwayLine]?: string;
- }
- | undefined;
-
- type PutAwayRow = TableRow<Partial<PutAwayLine>, EntryError>;
-
- const style = {
- position: "absolute",
- top: "50%",
- left: "50%",
- transform: "translate(-50%, -50%)",
- bgcolor: "background.paper",
- pt: 5,
- px: 5,
- pb: 10,
- width: "auto",
- };
-
- const PutAwayForm: React.FC<Props> = ({ itemDetail, warehouse=[], disabled, setRowModesModel, setRowSelectionModel }) => {
- const { t } = useTranslation("purchaseOrder");
- const apiRef = useGridApiRef();
- const {
- register,
- formState: { errors, defaultValues, touchedFields },
- watch,
- control,
- setValue,
- getValues,
- reset,
- resetField,
- setError,
- clearErrors,
- } = useFormContext<PutAwayInput>();
- // const [recordQty, setRecordQty] = useState(0);
- const [warehouseId, setWarehouseId] = useState(itemDetail.defaultWarehouseId ?? 1);
- const filteredWarehouse = useMemo(() => {
- // do filtering here if any
- return warehouse;
- }, []);
-
- const defaultOption = {
- value: 0, // think think sin
- label: t("Select warehouse"),
- group: "default",
- };
- const options = useMemo(() => {
- return [
- {
- value: 1,
- label: t("W001 - 憶兆 3樓A倉"),
- group: "default",
- },
- ...filteredWarehouse.map((w) => ({
- value: w.id,
- label: `${w.code} - ${w.name}`,
- group: "existing",
- })),
- ];
- }, [filteredWarehouse]);
- const currentValue =
- warehouseId > 0
- ? options.find((o) => o.value === warehouseId)
- : options.find((o) => o.value === getValues("warehouseId")) ||
- defaultOption;
-
- const onChange = useCallback(
- (
- event: React.SyntheticEvent,
- newValue: { value: number; group: string } | { value: number }[],
- ) => {
- const singleNewVal = newValue as {
- value: number;
- group: string;
- };
- // console.log(singleNewVal);
- // console.log("onChange");
- // setValue("warehouseId", singleNewVal.value);
- setWarehouseId(singleNewVal.value);
- },
- [],
- );
- // const accQty = watch("acceptedQty");
- // const validateForm = useCallback(() => {
- // console.log(accQty);
- // if (accQty > itemDetail.acceptedQty) {
- // setError("acceptedQty", {
- // message: `acceptedQty must not greater than ${itemDetail.acceptedQty}`,
- // type: "required",
- // });
- // }
- // if (accQty < 1) {
- // setError("acceptedQty", {
- // message: `minimal value is 1`,
- // type: "required",
- // });
- // }
- // if (isNaN(accQty)) {
- // setError("acceptedQty", {
- // message: `value must be a number`,
- // type: "required",
- // });
- // }
- // }, [accQty]);
-
- // useEffect(() => {
- // clearErrors();
- // validateForm();
- // }, [validateForm]);
-
- useEffect(() => {
- setValue("status", "received");
- // setValue("status", "completed");
- // setValue("warehouseId", options[0].value); //TODO: save all warehouse entry?
- }, []);
-
- useEffect(() => {
- if (warehouseId > 0) {
- setValue("warehouseId", warehouseId);
- clearErrors("warehouseId");
- }
- }, [warehouseId]);
-
- const getWarningTextHardcode = useCallback((): string | undefined => {
- console.log(options)
- if (options.length === 0) return undefined
- const defaultWarehouseId = options[0].value;
- const currWarehouseId = watch("warehouseId");
- if (defaultWarehouseId !== currWarehouseId) {
- return t("not default warehosue");
- }
- return undefined;
- }, [options]);
-
- const columns = useMemo<GridColDef[]>(
- () => [
- {
- field: "id",
- headerName: t(""),
- flex: 0.2,
- editable: false,
- renderCell(params) {
- return <span style={{fontSize:18}}>
- {`${params.api.getRowIndexRelativeToVisibleRows(params.id) + 1}.`}
- </span>
- },
- },
- {
- field: "putawayDate",
- headerName: t("putawayDatetime"),
- flex: 1,
- editable: false,
- renderCell(params) {
- return <span style={{fontSize:24}}>
- {`${(arrayToDateTimeString(params.value))}`}
- </span>
- },
- },
- {
- field: "putawayUser",
- headerName: t("putawayUser"),
- flex: 1,
- editable: false,
- renderCell(params) {
- return <span style={{fontSize:24}}>
- {params.value}
- </span>
- }
- },
- {
- field: "qty",
- headerName: t("putawayQty"),
- flex: 0.5,
- editable: false,
- headerAlign: "right",
- align: "right",
- renderCell(params) {
- return <span style={{fontSize:24}}>
- {params.value}
- </span>
- }
- },
- {
- field: "warehouse",
- headerName: t("warehouse"),
- flex: 2,
- editable: false,
- renderCell(params) {
- return <span style={{fontSize:24}}>
- {params.value}
- </span>
- }
- // renderEditCell: (params) => {
- // const index = params.api.getRowIndexRelativeToVisibleRows(params.row.id)
- // // console.log(index)
- // // console.log(watch(`putAwayLines.${index}.warehouse`))
- // return <Autocomplete
- // fullWidth
- // disableClearable
- // options={options}
- // // defaultValue={options.find((o) => o.value === itemDetail.defaultWarehouseId)}
- // // value={options.find((o) => o.value === watch(`putAwayLines.${index}.warehouseId`))}
- // defaultValue={options.find((o) => o.value === watch(`putAwayLines.${index}.warehouseId`))}
- // onChange={(event, value) => {
- // params.api.setEditCellValue({ id: params.id, field: params.field, value: options.find((o) => o.value === value.value)?.label ?? ""})
- // params.api.setEditCellValue({ id: params.id, field: "warehouseId", value: value.value})
- // // setValue(`putAwayLines.${index}.warehouseId`, value.value)
- // // setValue(`putAwayLines.${index}.warehouse`, options.find((o) => o.value === value.value)?.label ?? "")
- // }}
- // sx={{
- // // Style the dropdown options
- // "& .MuiAutocomplete-option": {
- // fontSize: 24,
- // },
- // }}
- // renderInput={(params) => (
- // <TextField
- // {...params}
- // variant="outlined"
- // InputProps={{style: {fontSize: 24}}}
- // // label={t("Warehouse")}
- // />
- // )}
- // />
- // }
- // renderCell(params) {
- // return <>{filteredWarehouse[0].name}</>
- // },
- },
-
- // {
- // field: "printQty",
- // headerName: t("printQty"),
- // flex: 1,
- // editable: false,
- // renderCell(params) {
- // return <>100</>
- // },
- // },
- ], [])
-
- const validation = useCallback(
- (newRow: GridRowModel<PutAwayRow>): EntryError => {
- const error: EntryError = {};
- const { qty, warehouseId, printQty } = newRow;
-
- return Object.keys(error).length > 0 ? error : undefined;
- },
- [],
- );
-
- const addRowDefaultValue = useMemo(() => {
- const defaultMaxQty = Number(itemDetail.demandQty?? itemDetail.acceptedQty)//watch("acceptedQty")
- - watch("putAwayLines").reduce((acc, cur) => acc + cur.qty, 0)
- const defaultWarehouseId = itemDetail.defaultWarehouseId ?? 1
- const defaultWarehouse = "W001 - 憶兆 3樓A倉"//options.find((o) => o.value === defaultWarehouseId)?.label
- return {qty: defaultMaxQty, warehouseId: defaultWarehouseId, warehouse: defaultWarehouse, printQty: 1, _isNew: true } as Partial<PutAwayLine>
- }, [])
-
- return (
- <Grid container justifyContent="flex-start" alignItems="flex-start">
- <Grid item xs={12}>
- <Typography variant="h6" display="block" marginBlockEnd={1}>
- {t("Putaway Detail")}
- </Typography>
- </Grid>
- <Grid
- container
- justifyContent="flex-start"
- alignItems="flex-start"
- spacing={2}
- sx={{ mt: 0.5 }}
- >
- {/* <Grid item xs={6}>
- <TextField
- label={t("Supplier")}
- fullWidth
- value={itemDetail.supplier}
- disabled
- />
- </Grid> */}
- {/* <Grid item xs={6}>
- <TextField
- label={t("Po Code")}
- fullWidth
- value={itemDetail.poCode}
- disabled
- />
- </Grid> */}
- <Grid item xs={6}>
- <TextField
- label={t("itemNo")}
- fullWidth
- value={itemDetail.itemNo}
- disabled
- />
- </Grid>
- <Grid item xs={6}>
- <TextField
- label={t("itemName")}
- fullWidth
- value={itemDetail.itemName}
- disabled
- />
- </Grid>
- <Grid item xs={6}>
- <TextField
- label={t("stockLotNo")}
- fullWidth
- value={itemDetail.lotNo}
- disabled
- />
- </Grid>
- <Grid item xs={6}>
- <TextField
- label={t("expiryDate")}
- fullWidth
- value={arrayToDateString(itemDetail.expiryDate, "output")}
- disabled
- />
- </Grid>
- <Grid item xs={3}>
- <TextField
- label={t("acceptedPutawayQty")} // TODO: fix it back to acceptedQty after db is fixed
- fullWidth
- value={itemDetail.demandQty ?? itemDetail.acceptedQty}
- disabled
- />
- </Grid>
- <Grid item xs={3}>
- <TextField
- label={t("uom")}
- fullWidth
- value={itemDetail.uom?.udfudesc}
- disabled
- />
- </Grid>
- {/* <Grid item xs={6}>
- <TextField
- label={t("productionDate")}
- fullWidth
- value={
- // dayjs(itemDetail.productionDate)
- dayjs()
- // .add(-1, "month")
- .format(OUTPUT_DATE_FORMAT)}
- disabled
- />
- </Grid> */}
- <Grid item xs={6}>
- <FormControl fullWidth>
- <Autocomplete
- noOptionsText={t("No Warehouse")}
- disableClearable
- disabled
- fullWidth
- defaultValue={options[0]} /// modify this later
- // onChange={onChange}
- getOptionLabel={(option) => option.label}
- options={options}
- renderInput={(params) => (
- <TextField {...params} label={t("Default Warehouse")} />
- )}
- />
- </FormControl>
- </Grid>
- {/* <Grid item xs={5.5}>
- <TextField
- label={t("acceptedQty")}
- fullWidth
- {...register("acceptedQty", {
- required: "acceptedQty required!",
- min: 1,
- max: itemDetail.acceptedQty,
- valueAsNumber: true,
- })}
- // defaultValue={itemDetail.acceptedQty}
- disabled={disabled}
- error={Boolean(errors.acceptedQty)}
- helperText={errors.acceptedQty?.message}
- />
- </Grid>
- <Grid item xs={1}>
- <Button disabled={disabled} onClick={onOpenScanner}>
- {t("bind")}
- </Button>
- </Grid> */}
- {/* <Grid item xs={5.5}>
- <Controller
- control={control}
- name="warehouseId"
- render={({ field }) => {
- console.log(field);
- return (
- <Autocomplete
- noOptionsText={t("No Warehouse")}
- disableClearable
- fullWidth
- value={options.find((o) => o.value == field.value)}
- onChange={onChange}
- getOptionLabel={(option) => option.label}
- options={options}
- renderInput={(params) => (
- <TextField
- {...params}
- label={"Select warehouse"}
- error={Boolean(errors.warehouseId?.message)}
- helperText={warehouseHelperText}
- // helperText={errors.warehouseId?.message}
- />
- )}
- />
- );
- }}
- />
- <FormControl fullWidth>
- <Autocomplete
- noOptionsText={t("No Warehouse")}
- disableClearable
- fullWidth
- // value={warehouseId > 0
- // ? options.find((o) => o.value === warehouseId)
- // : undefined}
- defaultValue={options[0]}
- // defaultValue={options.find((o) => o.value === 1)}
- value={currentValue}
- onChange={onChange}
- getOptionLabel={(option) => option.label}
- options={options}
- renderInput={(params) => (
- <TextField
- {...params}
- // label={"Select warehouse"}
- disabled={disabled}
- error={Boolean(errors.warehouseId?.message)}
- helperText={
- errors.warehouseId?.message ?? getWarningTextHardcode()
- }
- // helperText={warehouseHelperText}
- />
- )}
- />
- </FormControl>
- </Grid> */}
- <Grid
- item
- xs={12}
- style={{ display: "flex", justifyContent: "center", marginTop:5 }}
- >
- {/* <QrCode content={qrContent} sx={{ width: 200, height: 200 }} /> */}
- <InputDataGrid<PutAwayInput, PutAwayLine, EntryError>
- apiRef={apiRef}
- checkboxSelection={false}
- _formKey={"putAwayLines"}
- columns={columns}
- validateRow={validation}
- needAdd={false}
- needActions={false}
- showRemoveBtn={false}
- addRowDefaultValue={addRowDefaultValue}
- _setRowModesModel={setRowModesModel}
- _setRowSelectionModel={setRowSelectionModel}
- />
- </Grid>
- </Grid>
- </Grid>
- );
- };
- export default PutAwayForm;
|