| @@ -4,9 +4,9 @@ import { serverFetchBlob } from "@/app/utils/fetchUtil"; | |||||
| import { BASE_API_URL } from "@/config/api"; | import { BASE_API_URL } from "@/config/api"; | ||||
| import { cache } from "react"; | import { cache } from "react"; | ||||
| export const getMailTemplateForStockInLine = cache(async (stockInLineId: number) => { | |||||
| export const getMailTemplatePdfForStockInLine = cache(async (stockInLineId: number) => { | |||||
| console.log("stockInLineId", stockInLineId) | console.log("stockInLineId", stockInLineId) | ||||
| return serverFetchBlob(`${BASE_API_URL}/mailTemplates/getMailTemplateForStockInLine/${stockInLineId}`, | |||||
| return serverFetchBlob(`${BASE_API_URL}/mailTemplates/getMailTemplatePdfForStockInLine/${stockInLineId}`, | |||||
| { | { | ||||
| method: "GET", | method: "GET", | ||||
| headers: { "Content-Type": "application/json" }, | headers: { "Content-Type": "application/json" }, | ||||
| @@ -15,6 +15,7 @@ import { | |||||
| GridCellParams, | GridCellParams, | ||||
| GridColDef, | GridColDef, | ||||
| GridEventListener, | GridEventListener, | ||||
| GridPaginationModel, | |||||
| GridRowEditStopReasons, | GridRowEditStopReasons, | ||||
| GridRowId, | GridRowId, | ||||
| GridRowIdGetter, | GridRowIdGetter, | ||||
| @@ -75,6 +76,7 @@ export interface InputDataGridProps<T, V, E> { | |||||
| columns: GridColDef[]; | columns: GridColDef[]; | ||||
| validateRow: (newRow: GridRowModel<TableRow<V, E>>) => E; | validateRow: (newRow: GridRowModel<TableRow<V, E>>) => E; | ||||
| needAdd?: boolean; | needAdd?: boolean; | ||||
| needActions?: boolean; | |||||
| showRemoveBtn?: boolean; | showRemoveBtn?: boolean; | ||||
| addRowDefaultValue?: Partial<V>; | addRowDefaultValue?: Partial<V>; | ||||
| _setRowModesModel?: Dispatch<SetStateAction<GridRowModesModel>>; | _setRowModesModel?: Dispatch<SetStateAction<GridRowModesModel>>; | ||||
| @@ -89,6 +91,7 @@ export interface SelectionInputDataGridProps<T, V, E> { | |||||
| columns: GridColDef[]; | columns: GridColDef[]; | ||||
| validateRow: (newRow: GridRowModel<TableRow<V, E>>) => E; | validateRow: (newRow: GridRowModel<TableRow<V, E>>) => E; | ||||
| needAdd?: boolean; | needAdd?: boolean; | ||||
| needActions?: boolean; | |||||
| showRemoveBtn?: boolean; | showRemoveBtn?: boolean; | ||||
| addRowDefaultValue?: Partial<V>; | addRowDefaultValue?: Partial<V>; | ||||
| _setRowModesModel?: Dispatch<SetStateAction<GridRowModesModel>>; | _setRowModesModel?: Dispatch<SetStateAction<GridRowModesModel>>; | ||||
| @@ -119,6 +122,7 @@ function InputDataGrid<T, V, E>({ | |||||
| columns, | columns, | ||||
| validateRow, | validateRow, | ||||
| needAdd, | needAdd, | ||||
| needActions = true, | |||||
| showRemoveBtn = true, | showRemoveBtn = true, | ||||
| addRowDefaultValue = {}, | addRowDefaultValue = {}, | ||||
| _setRowModesModel = undefined, | _setRowModesModel = undefined, | ||||
| @@ -364,10 +368,11 @@ function InputDataGrid<T, V, E>({ | |||||
| apiRef={apiRef} | apiRef={apiRef} | ||||
| rows={rows} | rows={rows} | ||||
| // columns={!checkboxSelection ? _columns : columns} | // columns={!checkboxSelection ? _columns : columns} | ||||
| columns={_columns} | |||||
| columns={needActions ? _columns : columns} | |||||
| editMode="row" | editMode="row" | ||||
| autoHeight | |||||
| // autoHeight | |||||
| sx={{ | sx={{ | ||||
| height: "30vh", | |||||
| "--DataGrid-overlayHeight": "100px", | "--DataGrid-overlayHeight": "100px", | ||||
| ".MuiDataGrid-row .MuiDataGrid-cell.hasError": { | ".MuiDataGrid-row .MuiDataGrid-cell.hasError": { | ||||
| border: "1px solid", | border: "1px solid", | ||||
| @@ -78,7 +78,7 @@ import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; | |||||
| import { DatePicker, LocalizationProvider, zhHK } from "@mui/x-date-pickers"; | import { DatePicker, LocalizationProvider, zhHK } from "@mui/x-date-pickers"; | ||||
| import { debounce } from "lodash"; | import { debounce } from "lodash"; | ||||
| import LoadingComponent from "../General/LoadingComponent"; | import LoadingComponent from "../General/LoadingComponent"; | ||||
| import { getMailTemplateForStockInLine } from "@/app/api/mailTemplate/actions"; | |||||
| import { getMailTemplatePdfForStockInLine } from "@/app/api/mailTemplate/actions"; | |||||
| import { PrinterCombo } from "@/app/api/settings/printer"; | import { PrinterCombo } from "@/app/api/settings/printer"; | ||||
| import { EscalationCombo } from "@/app/api/user"; | import { EscalationCombo } from "@/app/api/user"; | ||||
| //import { useRouter } from "next/navigation"; | //import { useRouter } from "next/navigation"; | ||||
| @@ -340,7 +340,7 @@ const PoDetail: React.FC<Props> = ({ po, qc, warehouse, printerCombo }) => { | |||||
| }, [purchaseOrder.id]); | }, [purchaseOrder.id]); | ||||
| const handleMailTemplateForStockInLine = useCallback(async (stockInLineId: number) => { | const handleMailTemplateForStockInLine = useCallback(async (stockInLineId: number) => { | ||||
| const response = await getMailTemplateForStockInLine(stockInLineId) | |||||
| const response = await getMailTemplatePdfForStockInLine(stockInLineId) | |||||
| if (response) { | if (response) { | ||||
| downloadFile(new Uint8Array(response.blobValue), response.filename); | downloadFile(new Uint8Array(response.blobValue), response.filename); | ||||
| } | } | ||||
| @@ -98,7 +98,6 @@ const PutAwayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled, setRowM | |||||
| setError, | setError, | ||||
| clearErrors, | clearErrors, | ||||
| } = useFormContext<PutAwayInput>(); | } = useFormContext<PutAwayInput>(); | ||||
| console.log(itemDetail); | |||||
| // const [recordQty, setRecordQty] = useState(0); | // const [recordQty, setRecordQty] = useState(0); | ||||
| const [warehouseId, setWarehouseId] = useState(itemDetail.defaultWarehouseId); | const [warehouseId, setWarehouseId] = useState(itemDetail.defaultWarehouseId); | ||||
| const filteredWarehouse = useMemo(() => { | const filteredWarehouse = useMemo(() => { | ||||
| @@ -140,14 +139,13 @@ const PutAwayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled, setRowM | |||||
| value: number; | value: number; | ||||
| group: string; | group: string; | ||||
| }; | }; | ||||
| console.log(singleNewVal); | |||||
| console.log("onChange"); | |||||
| // console.log(singleNewVal); | |||||
| // console.log("onChange"); | |||||
| // setValue("warehouseId", singleNewVal.value); | // setValue("warehouseId", singleNewVal.value); | ||||
| setWarehouseId(singleNewVal.value); | setWarehouseId(singleNewVal.value); | ||||
| }, | }, | ||||
| [], | [], | ||||
| ); | ); | ||||
| console.log(watch("putAwayLines")) | |||||
| // const accQty = watch("acceptedQty"); | // const accQty = watch("acceptedQty"); | ||||
| // const validateForm = useCallback(() => { | // const validateForm = useCallback(() => { | ||||
| // console.log(accQty); | // console.log(accQty); | ||||
| @@ -224,11 +222,20 @@ const PutAwayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled, setRowM | |||||
| const columns = useMemo<GridColDef[]>( | const columns = useMemo<GridColDef[]>( | ||||
| () => [ | () => [ | ||||
| { | |||||
| field: "id", | |||||
| headerName: t(""), | |||||
| flex: 0.2, | |||||
| editable: false, | |||||
| renderCell(params) { | |||||
| return `${params.api.getRowIndexRelativeToVisibleRows(params.id) + 1}.` | |||||
| }, | |||||
| }, | |||||
| { | { | ||||
| field: "qty", | field: "qty", | ||||
| headerName: t("qty"), | headerName: t("qty"), | ||||
| flex: 1, | |||||
| editable: true, | |||||
| flex: 0.5, | |||||
| editable: false, | |||||
| // renderCell(params) { | // renderCell(params) { | ||||
| // return <>100</> | // return <>100</> | ||||
| // }, | // }, | ||||
| @@ -237,7 +244,7 @@ const PutAwayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled, setRowM | |||||
| field: "warehouse", | field: "warehouse", | ||||
| headerName: t("warehouse"), | headerName: t("warehouse"), | ||||
| flex: 1, | flex: 1, | ||||
| editable: true, | |||||
| editable: false, | |||||
| renderEditCell: (params) => { | renderEditCell: (params) => { | ||||
| const index = params.api.getRowIndexRelativeToVisibleRows(params.row.id) | const index = params.api.getRowIndexRelativeToVisibleRows(params.row.id) | ||||
| // console.log(index) | // console.log(index) | ||||
| @@ -268,15 +275,15 @@ const PutAwayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled, setRowM | |||||
| // return <>{filteredWarehouse[0].name}</> | // return <>{filteredWarehouse[0].name}</> | ||||
| // }, | // }, | ||||
| }, | }, | ||||
| { | |||||
| field: "printQty", | |||||
| headerName: t("printQty"), | |||||
| flex: 1, | |||||
| editable: true, | |||||
| // { | |||||
| // field: "printQty", | |||||
| // headerName: t("printQty"), | |||||
| // flex: 1, | |||||
| // editable: false, | |||||
| // renderCell(params) { | // renderCell(params) { | ||||
| // return <>100</> | // return <>100</> | ||||
| // }, | // }, | ||||
| }, | |||||
| // }, | |||||
| ], []) | ], []) | ||||
| const validation = useCallback( | const validation = useCallback( | ||||
| @@ -491,6 +498,7 @@ const PutAwayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled, setRowM | |||||
| columns={columns} | columns={columns} | ||||
| validateRow={validation} | validateRow={validation} | ||||
| needAdd={false} | needAdd={false} | ||||
| needActions={false} | |||||
| showRemoveBtn={false} | showRemoveBtn={false} | ||||
| addRowDefaultValue={addRowDefaultValue} | addRowDefaultValue={addRowDefaultValue} | ||||
| _setRowModesModel={setRowModesModel} | _setRowModesModel={setRowModesModel} | ||||
| @@ -99,6 +99,7 @@ const PoQcStockInModalVer2: React.FC<Props> = ({ | |||||
| // Select Printer | // Select Printer | ||||
| const [selectedPrinter, setSelectedPrinter] = useState(printerCombo[0]); | const [selectedPrinter, setSelectedPrinter] = useState(printerCombo[0]); | ||||
| const [printQty, setPrintQty] = useState(1); | |||||
| const [tabIndex, setTabIndex] = useState(0); | const [tabIndex, setTabIndex] = useState(0); | ||||
| const handleTabChange = useCallback<NonNullable<TabsProps["onChange"]>>( | const handleTabChange = useCallback<NonNullable<TabsProps["onChange"]>>( | ||||
| @@ -460,7 +461,7 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
| } | } | ||||
| // console.log(pafRowSelectionModel) | // console.log(pafRowSelectionModel) | ||||
| const printList = formProps.watch("putAwayLines")?.filter((line) => ((pafRowSelectionModel ?? []).some((model) => model === line.id))) ?? [] | const printList = formProps.watch("putAwayLines")?.filter((line) => ((pafRowSelectionModel ?? []).some((model) => model === line.id))) ?? [] | ||||
| const printQty = printList.reduce((acc, cur) => acc + cur.printQty, 0) | |||||
| // const printQty = printList.reduce((acc, cur) => acc + cur.printQty, 0) | |||||
| // console.log(printQty) | // console.log(printQty) | ||||
| const data: PrintQrCodeForSilRequest = { | const data: PrintQrCodeForSilRequest = { | ||||
| stockInLineId: itemDetail.id, | stockInLineId: itemDetail.id, | ||||
| @@ -474,7 +475,7 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
| } finally { | } finally { | ||||
| setIsPrinting(() => false) | setIsPrinting(() => false) | ||||
| } | } | ||||
| }, [itemDetail.id, pafRowSelectionModel]); | |||||
| }, [itemDetail.id, pafRowSelectionModel, printQty]); | |||||
| const acceptQty = formProps.watch("acceptedQty") | const acceptQty = formProps.watch("acceptedQty") | ||||
| @@ -578,59 +579,75 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
| container | container | ||||
| justifyContent="flex-start" | justifyContent="flex-start" | ||||
| alignItems="flex-start" | alignItems="flex-start" | ||||
| spacing={2} | |||||
| > | > | ||||
| <PutAwayForm | |||||
| itemDetail={itemDetail} | |||||
| warehouse={warehouse!} | |||||
| disabled={viewOnly} | |||||
| setRowModesModel={setPafRowModesModel} | |||||
| setRowSelectionModel={setPafRowSelectionModel} | |||||
| /> | |||||
| <Grid item xs={12}> | |||||
| <PutAwayForm | |||||
| itemDetail={itemDetail} | |||||
| warehouse={warehouse!} | |||||
| disabled={viewOnly} | |||||
| setRowModesModel={setPafRowModesModel} | |||||
| setRowSelectionModel={setPafRowSelectionModel} | |||||
| /> | |||||
| </Grid> | |||||
| {/* <PutAwayGrid | {/* <PutAwayGrid | ||||
| itemDetail={itemDetail} | itemDetail={itemDetail} | ||||
| warehouse={warehouse!} | warehouse={warehouse!} | ||||
| disabled={viewOnly} | disabled={viewOnly} | ||||
| /> */} | /> */} | ||||
| <Stack direction="row" justifyContent="flex-end" gap={1}> | |||||
| <Autocomplete | |||||
| disableClearable | |||||
| options={printerCombo} | |||||
| defaultValue={selectedPrinter} | |||||
| onChange={(event, value) => { | |||||
| setSelectedPrinter(value) | |||||
| }} | |||||
| renderInput={(params) => ( | |||||
| <TextField | |||||
| {...params} | |||||
| variant="outlined" | |||||
| label={t("Printer")} | |||||
| sx={{ width: 300}} | |||||
| /> | |||||
| )} | |||||
| /> | |||||
| <Button | |||||
| id="printButton" | |||||
| type="button" | |||||
| variant="contained" | |||||
| color="primary" | |||||
| sx={{ mt: 1 }} | |||||
| onClick={handlePrint} | |||||
| disabled={isPrinting || printerCombo.length <= 0 || pafSubmitDisable} | |||||
| > | |||||
| {isPrinting ? t("Printing") : t("print")} | |||||
| </Button> | |||||
| {/* <Button | |||||
| id="putawaySubmit" | |||||
| type="submit" | |||||
| variant="contained" | |||||
| color="primary" | |||||
| sx={{ mt: 1 }} | |||||
| onClick={formProps.handleSubmit(onSubmitPutaway)} | |||||
| disabled={pafSubmitDisable} | |||||
| > | |||||
| {t("confirm putaway")} | |||||
| </Button> */} | |||||
| </Stack> | |||||
| <Grid item xs={12}> | |||||
| <Stack direction="row" justifyContent="flex-end" gap={1}> | |||||
| <Autocomplete | |||||
| disableClearable | |||||
| options={printerCombo} | |||||
| defaultValue={selectedPrinter} | |||||
| onChange={(event, value) => { | |||||
| setSelectedPrinter(value) | |||||
| }} | |||||
| renderInput={(params) => ( | |||||
| <TextField | |||||
| {...params} | |||||
| variant="outlined" | |||||
| label={t("Printer")} | |||||
| sx={{ width: 300}} | |||||
| /> | |||||
| )} | |||||
| /> | |||||
| <TextField | |||||
| variant="outlined" | |||||
| label={t("Print Qty")} | |||||
| defaultValue={printQty} | |||||
| onChange={(event) => { | |||||
| event.target.value = event.target.value.replace(/[^0-9]/g, '') | |||||
| setPrintQty(Number(event.target.value)) | |||||
| }} | |||||
| sx={{ width: 300}} | |||||
| /> | |||||
| <Button | |||||
| id="printButton" | |||||
| type="button" | |||||
| variant="contained" | |||||
| color="primary" | |||||
| sx={{ mt: 1 }} | |||||
| onClick={handlePrint} | |||||
| disabled={isPrinting || printerCombo.length <= 0 || pafSubmitDisable} | |||||
| > | |||||
| {isPrinting ? t("Printing") : t("print")} | |||||
| </Button> | |||||
| {/* <Button | |||||
| id="putawaySubmit" | |||||
| type="submit" | |||||
| variant="contained" | |||||
| color="primary" | |||||
| sx={{ mt: 1 }} | |||||
| onClick={formProps.handleSubmit(onSubmitPutaway)} | |||||
| disabled={pafSubmitDisable} | |||||
| > | |||||
| {t("confirm putaway")} | |||||
| </Button> */} | |||||
| </Stack> | |||||
| </Grid> | |||||
| </Grid> | </Grid> | ||||
| </Box> | </Box> | ||||
| } | } | ||||
| @@ -148,5 +148,6 @@ | |||||
| "QC Record": "品檢記錄", | "QC Record": "品檢記錄", | ||||
| "value must be integer": "請輸入整數", | "value must be integer": "請輸入整數", | ||||
| "dn and qc info": "來貨及品檢詳情", | "dn and qc info": "來貨及品檢詳情", | ||||
| "Qc Decision": "品檢詳情" | |||||
| "Qc Decision": "品檢詳情", | |||||
| "Print Qty": "列印數量" | |||||
| } | } | ||||