@@ -21,6 +21,7 @@ import { | |||||
GridRowModel, | GridRowModel, | ||||
GridRowModes, | GridRowModes, | ||||
GridRowModesModel, | GridRowModesModel, | ||||
GridRowParams, | |||||
GridRowSelectionModel, | GridRowSelectionModel, | ||||
GridToolbarContainer, | GridToolbarContainer, | ||||
GridValidRowModel, | GridValidRowModel, | ||||
@@ -63,6 +64,7 @@ export type TableRow<V, E> = Partial< | |||||
isActive: boolean | undefined; | isActive: boolean | undefined; | ||||
_isNew: boolean; | _isNew: boolean; | ||||
_error: E; | _error: E; | ||||
_disableDelete: boolean; | |||||
} & ResultWithId | } & ResultWithId | ||||
>; | >; | ||||
@@ -76,6 +78,7 @@ export interface InputDataGridProps<T, V, E> { | |||||
showRemoveBtn?: boolean; | showRemoveBtn?: boolean; | ||||
addRowDefaultValue?: Partial<V>; | addRowDefaultValue?: Partial<V>; | ||||
_setRowModesModel?: Dispatch<SetStateAction<GridRowModesModel>>; | _setRowModesModel?: Dispatch<SetStateAction<GridRowModesModel>>; | ||||
_setRowSelectionModel?: Dispatch<SetStateAction<GridRowSelectionModel>>; | |||||
} | } | ||||
export interface SelectionInputDataGridProps<T, V, E> { | export interface SelectionInputDataGridProps<T, V, E> { | ||||
@@ -89,6 +92,7 @@ export interface SelectionInputDataGridProps<T, V, E> { | |||||
showRemoveBtn?: boolean; | showRemoveBtn?: boolean; | ||||
addRowDefaultValue?: Partial<V>; | addRowDefaultValue?: Partial<V>; | ||||
_setRowModesModel?: Dispatch<SetStateAction<GridRowModesModel>>; | _setRowModesModel?: Dispatch<SetStateAction<GridRowModesModel>>; | ||||
_setRowSelectionModel?: Dispatch<SetStateAction<GridRowSelectionModel>>; | |||||
} | } | ||||
export type Props<T, V, E> = | export type Props<T, V, E> = | ||||
@@ -118,6 +122,7 @@ function InputDataGrid<T, V, E>({ | |||||
showRemoveBtn = true, | showRemoveBtn = true, | ||||
addRowDefaultValue = {}, | addRowDefaultValue = {}, | ||||
_setRowModesModel = undefined, | _setRowModesModel = undefined, | ||||
_setRowSelectionModel = undefined, | |||||
}: Props<T, V, E>) { | }: Props<T, V, E>) { | ||||
const { | const { | ||||
t, | t, | ||||
@@ -157,9 +162,15 @@ function InputDataGrid<T, V, E>({ | |||||
`${formKey}_active`, | `${formKey}_active`, | ||||
) as GridRowSelectionModel; | ) as GridRowSelectionModel; | ||||
// console.log(rowModel); | // console.log(rowModel); | ||||
return rowModel; | |||||
return rowModel ?? []; | |||||
}); | }); | ||||
useEffect(() => { | |||||
if (_setRowSelectionModel) { | |||||
_setRowSelectionModel(rowSelectionModel) | |||||
} | |||||
}, [rowSelectionModel]) | |||||
const handleSave = useCallback( | const handleSave = useCallback( | ||||
(id: GridRowId) => () => { | (id: GridRowId) => () => { | ||||
setRowModesModel((prevRowModesModel) => ({ | setRowModesModel((prevRowModesModel) => ({ | ||||
@@ -259,7 +270,9 @@ function InputDataGrid<T, V, E>({ | |||||
headerName: "", | headerName: "", | ||||
flex: 0.5, | flex: 0.5, | ||||
cellClassName: "actions", | cellClassName: "actions", | ||||
getActions: ({ id }: { id: GridRowId }) => { | |||||
getActions: (params: GridRowParams<TableRow<V, E>>) => { | |||||
const id = params.id | |||||
const _disableDelete = Boolean(params.row._disableDelete) | |||||
const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit; | const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit; | ||||
if (isInEditMode) { | if (isInEditMode) { | ||||
return [ | return [ | ||||
@@ -284,6 +297,7 @@ function InputDataGrid<T, V, E>({ | |||||
<GridActionsCellItem | <GridActionsCellItem | ||||
icon={<DeleteIcon />} | icon={<DeleteIcon />} | ||||
label="Delete" | label="Delete" | ||||
disabled={_disableDelete} | |||||
sx={{ | sx={{ | ||||
color: "error.main", | color: "error.main", | ||||
}} | }} | ||||
@@ -349,7 +363,8 @@ function InputDataGrid<T, V, E>({ | |||||
rowSelectionModel={rowSelectionModel} | rowSelectionModel={rowSelectionModel} | ||||
apiRef={apiRef} | apiRef={apiRef} | ||||
rows={rows} | rows={rows} | ||||
columns={!checkboxSelection ? _columns : columns} | |||||
// columns={!checkboxSelection ? _columns : columns} | |||||
columns={_columns} | |||||
editMode="row" | editMode="row" | ||||
autoHeight | autoHeight | ||||
sx={{ | sx={{ | ||||
@@ -377,15 +392,17 @@ function InputDataGrid<T, V, E>({ | |||||
return classname; | return classname; | ||||
}} | }} | ||||
slots={ | slots={ | ||||
!checkboxSelection | |||||
? { | |||||
// !checkboxSelection | |||||
// ? | |||||
{ | |||||
footer: FooterToolbar, | footer: FooterToolbar, | ||||
noRowsOverlay: NoRowsOverlay, | noRowsOverlay: NoRowsOverlay, | ||||
} | } | ||||
: undefined | |||||
// : undefined | |||||
} | } | ||||
slotProps={ | slotProps={ | ||||
!checkboxSelection && Boolean(needAdd) | |||||
// !checkboxSelection && Boolean(needAdd) | |||||
Boolean(needAdd) | |||||
? { | ? { | ||||
footer: { child: footer }, | footer: { child: footer }, | ||||
} | } | ||||
@@ -28,6 +28,7 @@ import { | |||||
GridRenderCellParams, | GridRenderCellParams, | ||||
GridRenderEditCellParams, | GridRenderEditCellParams, | ||||
useGridApiRef, | useGridApiRef, | ||||
GridRowSelectionModel, | |||||
} from "@mui/x-data-grid"; | } from "@mui/x-data-grid"; | ||||
import InputDataGrid from "../InputDataGrid"; | import InputDataGrid from "../InputDataGrid"; | ||||
import { TableRow } from "../InputDataGrid/InputDataGrid"; | import { TableRow } from "../InputDataGrid/InputDataGrid"; | ||||
@@ -60,6 +61,7 @@ interface Props { | |||||
disabled: boolean; | disabled: boolean; | ||||
// qc: QcItemWithChecks[]; | // qc: QcItemWithChecks[]; | ||||
setRowModesModel: Dispatch<SetStateAction<GridRowModesModel>>; | setRowModesModel: Dispatch<SetStateAction<GridRowModesModel>>; | ||||
setRowSelectionModel: Dispatch<SetStateAction<GridRowSelectionModel>>; | |||||
} | } | ||||
type EntryError = | type EntryError = | ||||
| { | | { | ||||
@@ -81,7 +83,7 @@ const style = { | |||||
width: "auto", | width: "auto", | ||||
}; | }; | ||||
const PutAwayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled, setRowModesModel }) => { | |||||
const PutAwayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled, setRowModesModel, setRowSelectionModel }) => { | |||||
const { t } = useTranslation("purchaseOrder"); | const { t } = useTranslation("purchaseOrder"); | ||||
const apiRef = useGridApiRef(); | const apiRef = useGridApiRef(); | ||||
const { | const { | ||||
@@ -534,7 +536,7 @@ const PutAwayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled, setRowM | |||||
{/* <QrCode content={qrContent} sx={{ width: 200, height: 200 }} /> */} | {/* <QrCode content={qrContent} sx={{ width: 200, height: 200 }} /> */} | ||||
<InputDataGrid<PutAwayInput, PutAwayLine, EntryError> | <InputDataGrid<PutAwayInput, PutAwayLine, EntryError> | ||||
apiRef={apiRef} | apiRef={apiRef} | ||||
checkboxSelection={false} | |||||
checkboxSelection={true} | |||||
_formKey={"putAwayLines"} | _formKey={"putAwayLines"} | ||||
columns={columns} | columns={columns} | ||||
validateRow={validation} | validateRow={validation} | ||||
@@ -542,6 +544,7 @@ const PutAwayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled, setRowM | |||||
showRemoveBtn={false} | showRemoveBtn={false} | ||||
addRowDefaultValue={addRowDefaultValue} | addRowDefaultValue={addRowDefaultValue} | ||||
_setRowModesModel={setRowModesModel} | _setRowModesModel={setRowModesModel} | ||||
_setRowSelectionModel={setRowSelectionModel} | |||||
/> | /> | ||||
</Grid> | </Grid> | ||||
</Grid> | </Grid> | ||||
@@ -21,7 +21,7 @@ import StockInFormVer2 from "./StockInFormVer2"; | |||||
import QcComponent from "./QcComponent"; | import QcComponent from "./QcComponent"; | ||||
import { dummyPutAwayLine, dummyQCData } from "./dummyQcTemplate"; | import { dummyPutAwayLine, dummyQCData } from "./dummyQcTemplate"; | ||||
import PutAwayForm from "./PutAwayForm"; | import PutAwayForm from "./PutAwayForm"; | ||||
import { GridRowModes, useGridApiRef } from "@mui/x-data-grid"; | |||||
import { GridRowModes, GridRowSelectionModel, useGridApiRef } from "@mui/x-data-grid"; | |||||
import {submitDialogWithWarning} from "../Swal/CustomAlerts"; | import {submitDialogWithWarning} from "../Swal/CustomAlerts"; | ||||
import { INPUT_DATE_FORMAT, arrayToDateString, dayjsToInputDateString } from "@/app/utils/formatUtil"; | import { INPUT_DATE_FORMAT, arrayToDateString, dayjsToInputDateString } from "@/app/utils/formatUtil"; | ||||
import dayjs from "dayjs"; | import dayjs from "dayjs"; | ||||
@@ -33,6 +33,7 @@ import { SessionWithTokens } from "@/config/authConfig"; | |||||
import { GridRowModesModel } from "@mui/x-data-grid"; | import { GridRowModesModel } from "@mui/x-data-grid"; | ||||
import { isEmpty } from "lodash"; | import { isEmpty } from "lodash"; | ||||
import { EscalationCombo } from "@/app/api/user"; | import { EscalationCombo } from "@/app/api/user"; | ||||
import { truncateSync } from "fs"; | |||||
const style = { | const style = { | ||||
@@ -103,7 +104,7 @@ const defaultNewValue = useMemo(() => { | |||||
dnDate: arrayToDateString(itemDetail.dnDate, "input")?? dayjsToInputDateString(dayjs()), | dnDate: arrayToDateString(itemDetail.dnDate, "input")?? dayjsToInputDateString(dayjs()), | ||||
// putAwayLines: dummyPutAwayLine, | // putAwayLines: dummyPutAwayLine, | ||||
// putAwayLines: itemDetail.putAwayLines.map((line) => (return {...line, printQty: 1})) ?? [], | // putAwayLines: itemDetail.putAwayLines.map((line) => (return {...line, printQty: 1})) ?? [], | ||||
putAwayLines: itemDetail.putAwayLines?.map((line) => ({...line, printQty: 1, _isNew: false})) ?? [], | |||||
putAwayLines: itemDetail.putAwayLines?.map((line) => ({...line, printQty: 1, _isNew: false, _disableDelete: true})) ?? [], | |||||
// qcResult: (itemDetail.qcResult && itemDetail.qcResult?.length > 0) ? itemDetail.qcResult : [],//[...dummyQCData], | // qcResult: (itemDetail.qcResult && itemDetail.qcResult?.length > 0) ? itemDetail.qcResult : [],//[...dummyQCData], | ||||
escResult: (itemDetail.escResult && itemDetail.escResult?.length > 0) ? itemDetail.escResult : [], | escResult: (itemDetail.escResult && itemDetail.escResult?.length > 0) ? itemDetail.escResult : [], | ||||
productionDate: itemDetail.productionDate ? arrayToDateString(itemDetail.productionDate, "input") : undefined, | productionDate: itemDetail.productionDate ? arrayToDateString(itemDetail.productionDate, "input") : undefined, | ||||
@@ -366,6 +367,7 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
// Put away model | // Put away model | ||||
const [pafRowModesModel, setPafRowModesModel] = useState<GridRowModesModel>({}) | const [pafRowModesModel, setPafRowModesModel] = useState<GridRowModesModel>({}) | ||||
const [pafRowSelectionModel, setPafRowSelectionModel] = useState<GridRowSelectionModel>([]) | |||||
const pafSubmitDisable = useMemo(() => { | const pafSubmitDisable = useMemo(() => { | ||||
// console.log("%c mode: ", "background:#90EE90; color:red", Object.entries(pafRowModesModel)) | // console.log("%c mode: ", "background:#90EE90; color:red", Object.entries(pafRowModesModel)) | ||||
// console.log("%c mode: ", "background:pink; color:#87CEEB", Object.entries(pafRowModesModel)) | // console.log("%c mode: ", "background:pink; color:#87CEEB", Object.entries(pafRowModesModel)) | ||||
@@ -441,11 +443,14 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
alert("列印數量不正確!"); | alert("列印數量不正確!"); | ||||
return; | return; | ||||
} | } | ||||
// console.log(pafRowSelectionModel) | |||||
const printList = formProps.watch("putAwayLines")?.filter((line) => ((pafRowSelectionModel ?? []).some((model) => model === line.id))) ?? [] | |||||
const printQty = printList.reduce((acc, cur) => acc + cur.printQty, 0) | |||||
// console.log(printQty) | |||||
const data: PrintQrCodeForSilRequest = { | const data: PrintQrCodeForSilRequest = { | ||||
stockInLineId: itemDetail.id, | stockInLineId: itemDetail.id, | ||||
printerId: selectedPrinter.id, | printerId: selectedPrinter.id, | ||||
printQty: formProps.watch("putAwayLines")?.reduce((acc, cur) => acc + cur.printQty, 0) | |||||
printQty: printQty | |||||
} | } | ||||
const response = await printQrCodeForSil(data); | const response = await printQrCodeForSil(data); | ||||
if (response) { | if (response) { | ||||
@@ -454,7 +459,7 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
} finally { | } finally { | ||||
setIsPrinting(() => false) | setIsPrinting(() => false) | ||||
} | } | ||||
}, [itemDetail.id]); | |||||
}, [itemDetail.id, pafRowSelectionModel]); | |||||
const acceptQty = formProps.watch("acceptedQty") | const acceptQty = formProps.watch("acceptedQty") | ||||
@@ -499,6 +504,7 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
warehouse={warehouse!} | warehouse={warehouse!} | ||||
disabled={viewOnly} | disabled={viewOnly} | ||||
setRowModesModel={setPafRowModesModel} | setRowModesModel={setPafRowModesModel} | ||||
setRowSelectionModel={setPafRowSelectionModel} | |||||
/> | /> | ||||
<Stack direction="row" justifyContent="flex-end" gap={1}> | <Stack direction="row" justifyContent="flex-end" gap={1}> | ||||
<Autocomplete | <Autocomplete | ||||
@@ -524,7 +530,7 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
color="primary" | color="primary" | ||||
sx={{ mt: 1 }} | sx={{ mt: 1 }} | ||||
onClick={handlePrint} | onClick={handlePrint} | ||||
disabled={isPrinting || printerCombo.length <= 0} | |||||
disabled={isPrinting || printerCombo.length <= 0 || pafSubmitDisable} | |||||
> | > | ||||
{isPrinting ? t("Printing") : t("print")} | {isPrinting ? t("Printing") : t("print")} | ||||
</Button> | </Button> | ||||