|
- "use client";
- import {
- FooterPropsOverrides,
- GridActionsCellItem,
- GridCellParams,
- GridRowId,
- GridRowIdGetter,
- GridRowModel,
- GridRowModes,
- GridRowModesModel,
- GridToolbarContainer,
- useGridApiRef,
- } from "@mui/x-data-grid";
- import {
- Dispatch,
- MutableRefObject,
- SetStateAction,
- useCallback,
- useEffect,
- useMemo,
- useState,
- } from "react";
- import StyledDataGrid from "../StyledDataGrid";
- import { GridColDef } from "@mui/x-data-grid";
- import { Box, Button, Grid, Icon, Typography } from "@mui/material";
- import { useTranslation } from "react-i18next";
- import { Add } from "@mui/icons-material";
- import SaveIcon from "@mui/icons-material/Save";
- import DeleteIcon from "@mui/icons-material/Delete";
- import CancelIcon from "@mui/icons-material/Cancel";
- import FactCheckIcon from "@mui/icons-material/FactCheck";
- import ShoppingCartIcon from "@mui/icons-material/ShoppingCart";
- // import PoQcModal from "./PoQcModal";
- import { QcItemWithChecks } from "src/app/api/qc";
- import PlayArrowIcon from "@mui/icons-material/PlayArrow";
- import { createStockInLine, testFetch } from "@/app/api/po/actions";
- import { useSearchParams } from "next/navigation";
- import { decimalFormatter, stockInLineStatusMap } from "@/app/utils/formatUtil";
- import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';
-
- interface ResultWithId {
- id: number;
- }
-
- interface Props {
- // qc: QcItemWithChecks[];
- // setRows: Dispatch<SetStateAction<PurchaseOrderLine[]>>;
- // itemDetail: PurchaseOrderLine;
- stockInLine: any[];
- }
-
- export type StockInLineEntryError = {
- [field in keyof any]?: string;
- };
-
- export type StockInLineRow = Partial<
- any & {
- isActive: boolean | undefined;
- _isNew: boolean;
- _error: StockInLineEntryError;
- } & ResultWithId
- >;
-
- class ProcessRowUpdateError extends Error {
- public readonly row: StockInLineRow;
- public readonly errors: StockInLineEntryError | undefined;
- constructor(row: StockInLineRow, message?: string, errors?: StockInLineEntryError) {
- super(message);
- this.row = row;
- this.errors = errors;
-
- Object.setPrototypeOf(this, ProcessRowUpdateError.prototype);
- }
- }
-
- function TempInputGridForMockUp({ stockInLine }: Props) {
- const { t } = useTranslation("schedule");
- const apiRef = useGridApiRef();
- const [rowModesModel, setRowModesModel] = useState<GridRowModesModel>({});
- const getRowId = useCallback<GridRowIdGetter<StockInLineRow>>(
- (row) => row.id as number,
- []
- );
- console.log(stockInLine);
- const [entries, setEntries] = useState<StockInLineRow[]>(stockInLine || []);
- const [modalInfo, setModalInfo] = useState<any>()
- const [qcOpen, setQcOpen] = useState(false);
- // const [defaultQty, setDefaultQty] = useState(() => {
- // const total = entries.reduce((acc, curr) => acc + (curr.acceptedQty || 0), 0);
- // return itemDetail.qty - total;
- // });
-
- const params = useSearchParams()
-
- const handleDelete = useCallback(
- (id: GridRowId) => () => {
- setEntries((es) => es.filter((e) => getRowId(e) !== id));
- },
- [getRowId]
- );
- const handleStart = useCallback(
- (id: GridRowId, params: any) => () => {
- setRowModesModel((prev) => ({
- ...prev,
- [id]: { mode: GridRowModes.View },
- }));
- setTimeout(async () => {
- // post stock in line
- console.log("delayed");
- console.log(params);
- const oldId = params.row.id
- console.log(oldId)
- const postData = {
- itemId: params.row.itemId,
- itemNo: params.row.itemNo,
- itemName: params.row.itemName,
- purchaseOrderId: params.row.purchaseOrderId,
- purchaseOrderLineId: params.row.purchaseOrderLineId,
- acceptedQty: params.row.acceptedQty,
- }
- const res = await createStockInLine(postData)
- console.log(res)
- // setEntries((prev) => prev.map((p) => p.id === oldId ? res.entity : p))
- // do post directly to test
- // openStartModal();
- }, 200);
- },
- []
- );
- const handleQC = useCallback(
- (id: GridRowId, params: any) => () => {
- setRowModesModel((prev) => ({
- ...prev,
- [id]: { mode: GridRowModes.View },
- }));
- setModalInfo(params.row)
- setTimeout(() => {
- // open qc modal
- console.log("delayed");
- openQcModal();
- }, 200);
- },
- []
- );
- const handleStockIn = useCallback(
- (id: GridRowId) => () => {
- setRowModesModel((prev) => ({
- ...prev,
- [id]: { mode: GridRowModes.View },
- }));
- setTimeout(() => {
- // open stock in modal
- // return the record with its status as pending
- // update layout
- console.log("delayed");
- }, 200);
- },
- []
- );
-
- const closeQcModal = useCallback(() => {
- setQcOpen(false);
- }, []);
- const openQcModal = useCallback(() => {
- setQcOpen(true);
- }, []);
-
- const columns = useMemo<GridColDef[]>(
- () => [
- {
- field: "code",
- headerName: t("Code"),
- flex: 1,
- },
- {
- field: "name",
- headerName: t("Name"),
- flex: 1,
- },
- {
- field: "type",
- headerName: t("type"),
- flex: 1,
- },
- {
- field: "inStockQty",
- headerName: t("Available Qty"),
- flex: 0.5,
- type: "number",
- editable: true,
- align: "right",
- headerAlign: "right",
- renderCell: (row) => {
- return decimalFormatter.format(row.value)
- }
- // replace with tooltip + content
- },
- {
- field: "purchaseQty",
- headerName: t("Demand Qty"),
- flex: 0.5,
- editable: true,
- align: "right",
- headerAlign: "right",
- renderCell: (row) => {
- return decimalFormatter.format(row.value)
- }
- },
- {
- field: "status",
- headerName: t("status"),
- flex: 0.5,
- editable: true,
- align: "center",
- headerAlign: "center",
- renderCell: () => {
- return <CheckCircleOutlineIcon
- color="success"
- fontSize="small"
- />
- }
- },
- // {
- // field: "actions",
- // type: "actions",
- // headerName: "start | qc | stock in | delete",
- // flex: 1,
- // cellClassName: "actions",
- // getActions: (params) => {
- // // const stockInLineStatusMap: { [status: string]: number } = {
- // // draft: 0,
- // // pending: 1,
- // // qc: 2,
- // // determine1: 3,
- // // determine2: 4,
- // // determine3: 5,
- // // receiving: 6,
- // // completed: 7,
- // // };
- // console.log(params.row.status);
- // const status = params.row.status.toLowerCase()
- // return [
- // <GridActionsCellItem
- // icon={<PlayArrowIcon />}
- // label="start"
- // sx={{
- // color: "primary.main",
- // }}
- // disabled={!(stockInLineStatusMap[status] === 0)}
- // // set _isNew to false after posting
- // // or check status
- // onClick={handleStart(params.row.id, params)}
- // color="inherit"
- // key="edit"
- // />,
- // <GridActionsCellItem
- // icon={<FactCheckIcon />}
- // label="qc"
- // sx={{
- // color: "primary.main",
- // }}
- // disabled={stockInLineStatusMap[status] <= 0 || stockInLineStatusMap[status] >= 6}
- // // set _isNew to false after posting
- // // or check status
- // onClick={handleQC(params.row.id, params)}
- // color="inherit"
- // key="edit"
- // />,
- // <GridActionsCellItem
- // icon={<ShoppingCartIcon />}
- // label="stockin"
- // sx={{
- // color: "primary.main",
- // }}
- // disabled={stockInLineStatusMap[status] !== 6}
- // // set _isNew to false after posting
- // // or check status
- // onClick={handleStockIn(params.row.id)}
- // color="inherit"
- // key="edit"
- // />,
- // <GridActionsCellItem
- // icon={<DeleteIcon />}
- // label="Delete"
- // sx={{
- // color: "error.main",
- // }}
- // disabled={stockInLineStatusMap[status] !== 0}
- // // disabled={Boolean(params.row.status)}
- // onClick={handleDelete(params.row.id)}
- // color="inherit"
- // key="edit"
- // />,
- // ];
- // },
- // },
- ],
- []
- );
-
- // const addRow = useCallback(() => {
- // const newEntry = {
- // id: Date.now(),
- // _isNew: true,
- // itemId: itemDetail.itemId,
- // purchaseOrderId: itemDetail.purchaseOrderId,
- // purchaseOrderLineId: itemDetail.id,
- // itemNo: itemDetail.itemNo,
- // itemName: itemDetail.itemName,
- // acceptedQty: defaultQty,
- // status: "draft",
- // };
- // setEntries((e) => [...e, newEntry]);
- // setRowModesModel((model) => ({
- // ...model,
- // [getRowId(newEntry)]: {
- // mode: GridRowModes.Edit,
- // // fieldToFocus: "projectId",
- // },
- // }));
- // }, [getRowId]);
- const validation = useCallback(
- (
- newRow: GridRowModel<StockInLineRow>
- // rowModel: GridRowSelectionModel
- ): StockInLineEntryError | undefined => {
- const error: StockInLineEntryError = {};
- console.log(newRow);
- // if (newRow.acceptedQty && newRow.acceptedQty > defaultQty) {
- // error["acceptedQty"] = "qty cannot be greater than remaining qty";
- // }
- return Object.keys(error).length > 0 ? error : undefined;
- },
- []
- );
- const processRowUpdate = useCallback(
- (newRow: GridRowModel<StockInLineRow>, originalRow: GridRowModel<StockInLineRow>) => {
- const errors = validation(newRow); // change to validation
- if (errors) {
- throw new ProcessRowUpdateError(
- originalRow,
- "validation error",
- errors
- );
- }
- const { _isNew, _error, ...updatedRow } = newRow;
- const rowToSave = {
- ...updatedRow,
- } satisfies StockInLineRow;
- const newEntries = entries.map((e) =>
- getRowId(e) === getRowId(originalRow) ? rowToSave : e
- );
- setEntries(newEntries);
- //update remaining qty
- const total = newEntries.reduce((acc, curr) => acc + (curr.acceptedQty || 0), 0);
- // setDefaultQty(itemDetail.qty - total);
- return rowToSave;
- },
- [getRowId, entries]
- );
-
- const onProcessRowUpdateError = useCallback(
- (updateError: ProcessRowUpdateError) => {
- const errors = updateError.errors;
- const oldRow = updateError.row;
-
- apiRef.current.updateRows([{ ...oldRow, _error: errors }]);
- },
- [apiRef]
- );
-
- // useEffect(() => {
- // const total = entries.reduce((acc, curr) => acc + (curr.acceptedQty || 0), 0);
- // setDefaultQty(itemDetail.qty - total);
- // }, [entries]);
-
- // const footer = (
- // <Box display="flex" gap={2} alignItems="center">
- // <Button
- // disableRipple
- // variant="outlined"
- // startIcon={<Add />}
- // disabled={defaultQty <= 0}
- // onClick={addRow}
- // size="small"
- // >
- // {t("Record pol")}
- // </Button>
- // </Box>
- // );
- return (
- <>
- <StyledDataGrid
- getRowId={getRowId}
- apiRef={apiRef}
- autoHeight
- sx={{
- "--DataGrid-overlayHeight": "100px",
- ".MuiDataGrid-row .MuiDataGrid-cell.hasError": {
- border: "1px solid",
- borderColor: "error.main",
- },
- ".MuiDataGrid-row .MuiDataGrid-cell.hasWarning": {
- border: "1px solid",
- borderColor: "warning.main",
- },
- }}
- disableColumnMenu
- editMode="row"
- rows={entries}
- rowModesModel={rowModesModel}
- onRowModesModelChange={setRowModesModel}
- processRowUpdate={processRowUpdate}
- onProcessRowUpdateError={onProcessRowUpdateError}
- columns={columns}
- getCellClassName={(params: GridCellParams<StockInLineRow>) => {
- let classname = "";
- if (params.row._error) {
- classname = "hasError";
- }
- return classname;
- }}
- // slots={{
- // footer: FooterToolbar,
- // noRowsOverlay: NoRowsOverlay,
- // }}
- // slotProps={{
- // footer: { child: footer },
- // }}
- />
- </>
- );
- }
- const NoRowsOverlay: React.FC = () => {
- const { t } = useTranslation("home");
- return (
- <Box
- display="flex"
- justifyContent="center"
- alignItems="center"
- height="100%"
- >
- <Typography variant="caption">{t("Add some entries!")}</Typography>
- </Box>
- );
- };
-
- const FooterToolbar: React.FC<FooterPropsOverrides> = ({ child }) => {
- return <GridToolbarContainer sx={{ p: 2 }}>{child}</GridToolbarContainer>;
- };
- export default TempInputGridForMockUp;
|