| @@ -26,9 +26,9 @@ export interface StockInLineEntry { | |||||
| expiryDate?: string | expiryDate?: string | ||||
| } | } | ||||
| export interface PurchaseQcCheck { | |||||
| qcCheckId: number; | |||||
| qty: number; | |||||
| export interface PurchaseQcResult { | |||||
| qcItemId: number; | |||||
| failQty: number; | |||||
| } | } | ||||
| export interface StockInInput { | export interface StockInInput { | ||||
| status: string | status: string | ||||
| @@ -41,15 +41,17 @@ export interface StockInInput { | |||||
| } | } | ||||
| export interface PurchaseQCInput { | export interface PurchaseQCInput { | ||||
| status: string | status: string | ||||
| acceptedQty: number | |||||
| sampleRate: number; | sampleRate: number; | ||||
| sampleWeight: number; | sampleWeight: number; | ||||
| totalWeight: number; | totalWeight: number; | ||||
| qcCheck: PurchaseQcCheck[]; | |||||
| qcResult: PurchaseQcResult[]; | |||||
| } | } | ||||
| export interface EscalationInput { | export interface EscalationInput { | ||||
| status: string | status: string | ||||
| handler: string | handler: string | ||||
| stockInLine: StockInLineEntry[] | |||||
| acceptedQty: number | |||||
| rejectedQty: number | |||||
| } | } | ||||
| export interface PutawayInput { | export interface PutawayInput { | ||||
| status: string | status: string | ||||
| @@ -16,14 +16,15 @@ export const integerFormatter = new Intl.NumberFormat("en-HK", { | |||||
| }) | }) | ||||
| export const stockInLineStatusMap: { [status: string]: {key: string, value: number} } = { | |||||
| draft: { key: "draft", value: 0 }, | |||||
| pending: { key: "pending", value: 1 }, | |||||
| qc: { key: "qc", value: 2 }, | |||||
| determine1: { key: "determine1", value: 3 }, | |||||
| determine2: { key: "determine2", value: 4 }, | |||||
| determine3: { key: "determine3", value: 5 }, | |||||
| receiving: { key: "receiving", value: 6 }, | |||||
| received: { key: "received", value: 7 }, | |||||
| completed: { key: "completed", value: 8 }, | |||||
| export const stockInLineStatusMap: { [status: string]: number } = { | |||||
| "draft": 0, | |||||
| "pending": 1, | |||||
| "qc": 2, | |||||
| "determine1": 3, | |||||
| "determine2": 4, | |||||
| "determine3": 5, | |||||
| "receiving": 6, | |||||
| "received": 7, | |||||
| "completed": 8, | |||||
| "rejected": 9, | |||||
| }; | }; | ||||
| @@ -43,8 +43,6 @@ type EntryError = | |||||
| } | } | ||||
| | undefined; | | undefined; | ||||
| type PoEscalationRow = TableRow<Partial<StockInLineEntry>, EntryError>; | |||||
| const EscalationForm: React.FC<Props> = ({ | const EscalationForm: React.FC<Props> = ({ | ||||
| // qc, | // qc, | ||||
| itemDetail, | itemDetail, | ||||
| @@ -64,98 +62,38 @@ const EscalationForm: React.FC<Props> = ({ | |||||
| clearErrors, | clearErrors, | ||||
| } = useFormContext<EscalationInput>(); | } = useFormContext<EscalationInput>(); | ||||
| console.log(itemDetail) | console.log(itemDetail) | ||||
| const columns = useMemo<GridColDef[]>( | |||||
| () => [ | |||||
| // { | |||||
| // field: "qcCheckId", | |||||
| // headerName: "qc Check", | |||||
| // flex: 1, | |||||
| // editable: true, | |||||
| // valueFormatter(params) { | |||||
| // const row = params.id ? params.api.getRow<PoEscalationRow>(params.id) : null; | |||||
| // if (!row) { | |||||
| // return null; | |||||
| // } | |||||
| // const Qc = qc.find((q) => q.id === row.qcCheckId); | |||||
| // return Qc ? `${Qc.code} - ${Qc.name}` : t("Please select QC"); | |||||
| // }, | |||||
| // renderCell(params: GridRenderCellParams<PoEscalationRow, number>) { | |||||
| // console.log(params.value); | |||||
| // return <TwoLineCell>{params.formattedValue}</TwoLineCell>; | |||||
| // }, | |||||
| // renderEditCell(params: GridRenderEditCellParams<PoEscalationRow, number>) { | |||||
| // const errorMessage = | |||||
| // params.row._error?.[params.field as keyof StockInLineEntry]; | |||||
| // console.log(errorMessage); | |||||
| // const content = ( | |||||
| // <QcSelect | |||||
| // allQcs={qc} | |||||
| // value={params.row.qcCheckId} | |||||
| // onQcSelect={async (qcCheckId) => { | |||||
| // await params.api.setEditCellValue({ | |||||
| // id: params.id, | |||||
| // field: "qcCheckId", | |||||
| // value: qcCheckId, | |||||
| // }); | |||||
| // }} | |||||
| // /> | |||||
| // ); | |||||
| // return errorMessage ? ( | |||||
| // <Tooltip title={t(errorMessage)}> | |||||
| // <Box width="100%">{content}</Box> | |||||
| // </Tooltip> | |||||
| // ) : ( | |||||
| // content | |||||
| // ); | |||||
| // }, | |||||
| // }, | |||||
| { | |||||
| field: "qty", | |||||
| headerName: "qty", | |||||
| flex: 1, | |||||
| editable: true, | |||||
| type: "number", | |||||
| renderEditCell(params: GridRenderEditCellParams<PoEscalationRow>) { | |||||
| const errorMessage = | |||||
| params.row._error?.[params.field as keyof StockInLineEntry]; | |||||
| const content = <GridEditInputCell {...params} />; | |||||
| return errorMessage ? ( | |||||
| <Tooltip title={t(errorMessage)}> | |||||
| <Box width="100%">{content}</Box> | |||||
| </Tooltip> | |||||
| ) : ( | |||||
| content | |||||
| ); | |||||
| }, | |||||
| }, | |||||
| ], | |||||
| [] | |||||
| ); | |||||
| const validationTest = useCallback( | |||||
| (newRow: GridRowModel<PoEscalationRow>): EntryError => { | |||||
| const error: EntryError = {}; | |||||
| // const { qcCheckId, qty } = newRow; | |||||
| // if (!qcCheckId || qcCheckId <= 0) { | |||||
| // error["qcCheckId"] = "select qc"; | |||||
| // } | |||||
| // if (!qty || qty <= 0) { | |||||
| // error["qty"] = "enter a qty"; | |||||
| // } | |||||
| return Object.keys(error).length > 0 ? error : undefined; | |||||
| }, | |||||
| [] | |||||
| ); | |||||
| const [status, determineCount] = useMemo(() => { | |||||
| switch (itemDetail.status) { | |||||
| case "pending": | |||||
| return ["determine1", 1]; | |||||
| case "determine1": | |||||
| return ["determine2", 2]; | |||||
| case "determine2": | |||||
| return ["determine3", 3]; | |||||
| default: | |||||
| return ["receiving", "receive or reject" ]; | |||||
| } | |||||
| }, [itemDetail]) | |||||
| const acceptedQty = watch("acceptedQty") | |||||
| const rejectedQty = watch("rejectedQty") | |||||
| useEffect(() => { | useEffect(() => { | ||||
| console.log("triggered") | console.log("triggered") | ||||
| // setValue("status", stockInLineStatusMap.determine1.key) | |||||
| setValue("status", status) | |||||
| }, []) | }, []) | ||||
| return ( | return ( | ||||
| <Grid container justifyContent="flex-start" alignItems="flex-start"> | <Grid container justifyContent="flex-start" alignItems="flex-start"> | ||||
| <Grid item xs={12}> | <Grid item xs={12}> | ||||
| <Typography variant="h6" display="block" marginBlockEnd={1}> | <Typography variant="h6" display="block" marginBlockEnd={1}> | ||||
| {t("Qc Detail")} | |||||
| {t(`Escalation`)}: {determineCount} | |||||
| </Typography> | |||||
| </Grid> | |||||
| <Grid item xs={12}> | |||||
| <Typography variant="h6" display="block" marginBlockEnd={1}> | |||||
| {t(`to be processed`)}: {itemDetail.acceptedQty - acceptedQty - rejectedQty} | |||||
| </Typography> | </Typography> | ||||
| </Grid> | </Grid> | ||||
| <Grid | <Grid | ||||
| @@ -165,7 +103,7 @@ const EscalationForm: React.FC<Props> = ({ | |||||
| spacing={2} | spacing={2} | ||||
| sx={{ mt: 0.5 }} | sx={{ mt: 0.5 }} | ||||
| > | > | ||||
| <Grid item xs={4}> | |||||
| {/* <Grid item xs={4}> | |||||
| <TextField | <TextField | ||||
| label={t("handler")} | label={t("handler")} | ||||
| fullWidth | fullWidth | ||||
| @@ -175,16 +113,31 @@ const EscalationForm: React.FC<Props> = ({ | |||||
| error={Boolean(errors.handler)} | error={Boolean(errors.handler)} | ||||
| helperText={errors.handler?.message} | helperText={errors.handler?.message} | ||||
| /> | /> | ||||
| </Grid> */} | |||||
| <Grid item xs={6}> | |||||
| <TextField | |||||
| label={t("acceptedQty")} | |||||
| fullWidth | |||||
| {...register("acceptedQty", { | |||||
| required: "acceptedQty required!", | |||||
| min: 0, | |||||
| valueAsNumber: true, | |||||
| })} | |||||
| // defaultValue={itemDetail.acceptedQty} | |||||
| // error={Boolean(errors.handler)} | |||||
| // helperText={errors.handler?.message} | |||||
| /> | |||||
| </Grid> | </Grid> | ||||
| <Grid item xs={4}> | |||||
| <Grid item xs={6}> | |||||
| <TextField | <TextField | ||||
| label={t("total")} | |||||
| label={t("rejectedQty")} | |||||
| fullWidth | fullWidth | ||||
| // {...register("handler", { | |||||
| // required: "handler required!", | |||||
| // })} | |||||
| value={itemDetail.acceptedQty} | |||||
| disabled | |||||
| {...register("rejectedQty", { | |||||
| required: "rejectedQty required!", | |||||
| min: 0, | |||||
| valueAsNumber: true, | |||||
| })} | |||||
| defaultValue={0} | |||||
| // error={Boolean(errors.handler)} | // error={Boolean(errors.handler)} | ||||
| // helperText={errors.handler?.message} | // helperText={errors.handler?.message} | ||||
| /> | /> | ||||
| @@ -197,15 +150,6 @@ const EscalationForm: React.FC<Props> = ({ | |||||
| spacing={2} | spacing={2} | ||||
| sx={{ mt: 0.5 }} | sx={{ mt: 0.5 }} | ||||
| > | > | ||||
| <Grid item xs={12}> | |||||
| <InputDataGrid<EscalationInput, StockInLineEntry, EntryError> | |||||
| apiRef={apiRef} | |||||
| checkboxSelection={false} | |||||
| _formKey={"stockInLine"} | |||||
| columns={columns} | |||||
| validateRow={validationTest} | |||||
| /> | |||||
| </Grid> | |||||
| </Grid> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| ); | ); | ||||
| @@ -110,12 +110,9 @@ function PoInputGrid({ | |||||
| return total; | return total; | ||||
| }); | }); | ||||
| useEffect(() => { | |||||
| }, []) | |||||
| useEffect(() => { | useEffect(() => { | ||||
| const completedList = entries.filter( | const completedList = entries.filter( | ||||
| (e) => e.status === stockInLineStatusMap.completed.key | |||||
| (e) => e.status === "completed" | |||||
| ); | ); | ||||
| const processedQty = completedList.reduce( | const processedQty = completedList.reduce( | ||||
| (acc, curr) => acc + (curr.acceptedQty || 0), | (acc, curr) => acc + (curr.acceptedQty || 0), | ||||
| @@ -176,21 +173,21 @@ function PoInputGrid({ | |||||
| }, | }, | ||||
| [] | [] | ||||
| ); | ); | ||||
| // const handleEscalation = useCallback( | |||||
| // (id: GridRowId, params: any) => () => { | |||||
| // setRowModesModel((prev) => ({ | |||||
| // ...prev, | |||||
| // [id]: { mode: GridRowModes.View }, | |||||
| // })); | |||||
| // setModalInfo(params.row); | |||||
| // setTimeout(() => { | |||||
| // // open qc modal | |||||
| // console.log("delayed"); | |||||
| // openEscalationModal(); | |||||
| // }, 200); | |||||
| // }, | |||||
| // [] | |||||
| // ); | |||||
| const handleEscalation = useCallback( | |||||
| (id: GridRowId, params: any) => () => { | |||||
| setRowModesModel((prev) => ({ | |||||
| ...prev, | |||||
| [id]: { mode: GridRowModes.View }, | |||||
| })); | |||||
| setModalInfo(params.row); | |||||
| setTimeout(() => { | |||||
| // open qc modal | |||||
| console.log("delayed"); | |||||
| openEscalationModal(); | |||||
| }, 200); | |||||
| }, | |||||
| [] | |||||
| ); | |||||
| const handleStockIn = useCallback( | const handleStockIn = useCallback( | ||||
| (id: GridRowId, params: any) => () => { | (id: GridRowId, params: any) => () => { | ||||
| setRowModesModel((prev) => ({ | setRowModesModel((prev) => ({ | ||||
| @@ -281,7 +278,7 @@ function PoInputGrid({ | |||||
| { | { | ||||
| field: "actions", | field: "actions", | ||||
| type: "actions", | type: "actions", | ||||
| headerName: "start | qc | stock in | putaway | delete", | |||||
| headerName: "start | qc | escalation | stock in | putaway | delete", | |||||
| flex: 1.5, | flex: 1.5, | ||||
| cellClassName: "actions", | cellClassName: "actions", | ||||
| getActions: (params) => { | getActions: (params) => { | ||||
| @@ -295,7 +292,7 @@ function PoInputGrid({ | |||||
| color: "primary.main", | color: "primary.main", | ||||
| marginRight: 2, | marginRight: 2, | ||||
| }} | }} | ||||
| disabled={!(stockInLineStatusMap[status].value === 0)} | |||||
| disabled={!(stockInLineStatusMap[status] === 0)} | |||||
| // set _isNew to false after posting | // set _isNew to false after posting | ||||
| // or check status | // or check status | ||||
| onClick={handleStart(params.row.id, params)} | onClick={handleStart(params.row.id, params)} | ||||
| @@ -310,8 +307,9 @@ function PoInputGrid({ | |||||
| marginRight: 2, | marginRight: 2, | ||||
| }} | }} | ||||
| disabled={ | disabled={ | ||||
| stockInLineStatusMap[status].value <= 0 || | |||||
| stockInLineStatusMap[status].value >= 5 | |||||
| // stockInLineStatusMap[status] <= 0 || | |||||
| // stockInLineStatusMap[status] >= 5 | |||||
| stockInLineStatusMap[status] != 1 | |||||
| } | } | ||||
| // set _isNew to false after posting | // set _isNew to false after posting | ||||
| // or check status | // or check status | ||||
| @@ -319,23 +317,23 @@ function PoInputGrid({ | |||||
| color="inherit" | color="inherit" | ||||
| key="edit" | key="edit" | ||||
| />, | />, | ||||
| // <GridActionsCellItem | |||||
| // icon={<NotificationImportantIcon />} | |||||
| // label="escalation" | |||||
| // sx={{ | |||||
| // color: "primary.main", | |||||
| // marginRight: 2, | |||||
| // }} | |||||
| // disabled={ | |||||
| // stockInLineStatusMap[status].value <= 0 || | |||||
| // stockInLineStatusMap[status].value >= 5 | |||||
| // } | |||||
| // // set _isNew to false after posting | |||||
| // // or check status | |||||
| // onClick={handleEscalation(params.row.id, params)} | |||||
| // color="inherit" | |||||
| // key="edit" | |||||
| // />, | |||||
| <GridActionsCellItem | |||||
| icon={<NotificationImportantIcon />} | |||||
| label="escalation" | |||||
| sx={{ | |||||
| color: "primary.main", | |||||
| marginRight: 2, | |||||
| }} | |||||
| disabled={ | |||||
| stockInLineStatusMap[status] <= 0 || | |||||
| stockInLineStatusMap[status] >= 5 | |||||
| } | |||||
| // set _isNew to false after posting | |||||
| // or check status | |||||
| onClick={handleEscalation(params.row.id, params)} | |||||
| color="inherit" | |||||
| key="edit" | |||||
| />, | |||||
| <GridActionsCellItem | <GridActionsCellItem | ||||
| icon={<ShoppingCartIcon />} | icon={<ShoppingCartIcon />} | ||||
| label="stockin" | label="stockin" | ||||
| @@ -343,7 +341,7 @@ function PoInputGrid({ | |||||
| color: "primary.main", | color: "primary.main", | ||||
| marginRight: 2, | marginRight: 2, | ||||
| }} | }} | ||||
| disabled={stockInLineStatusMap[status].value !== 6} | |||||
| disabled={stockInLineStatusMap[status] !== 6} | |||||
| // set _isNew to false after posting | // set _isNew to false after posting | ||||
| // or check status | // or check status | ||||
| onClick={handleStockIn(params.row.id, params)} | onClick={handleStockIn(params.row.id, params)} | ||||
| @@ -357,7 +355,7 @@ function PoInputGrid({ | |||||
| color: "primary.main", | color: "primary.main", | ||||
| marginRight: 2, | marginRight: 2, | ||||
| }} | }} | ||||
| disabled={stockInLineStatusMap[status].value !== 7} | |||||
| disabled={stockInLineStatusMap[status] !== 7} | |||||
| // set _isNew to false after posting | // set _isNew to false after posting | ||||
| // or check status | // or check status | ||||
| onClick={handlePutAway(params.row.id, params)} | onClick={handlePutAway(params.row.id, params)} | ||||
| @@ -370,7 +368,7 @@ function PoInputGrid({ | |||||
| sx={{ | sx={{ | ||||
| color: "error.main", | color: "error.main", | ||||
| }} | }} | ||||
| disabled={stockInLineStatusMap[status].value !== 0} | |||||
| disabled={stockInLineStatusMap[status] !== 0} | |||||
| // disabled={Boolean(params.row.status)} | // disabled={Boolean(params.row.status)} | ||||
| onClick={handleDelete(params.row.id)} | onClick={handleDelete(params.row.id)} | ||||
| color="inherit" | color="inherit" | ||||
| @@ -510,8 +508,8 @@ function PoInputGrid({ | |||||
| isCellEditable={(params) => { | isCellEditable={(params) => { | ||||
| const status = params.row.status.toLowerCase(); | const status = params.row.status.toLowerCase(); | ||||
| return ( | return ( | ||||
| stockInLineStatusMap[status].value >= 0 || | |||||
| stockInLineStatusMap[status].value <= 1 | |||||
| stockInLineStatusMap[status] >= 0 || | |||||
| stockInLineStatusMap[status] <= 1 | |||||
| ); | ); | ||||
| }} | }} | ||||
| getCellClassName={(params: GridCellParams<StockInLineRow>) => { | getCellClassName={(params: GridCellParams<StockInLineRow>) => { | ||||
| @@ -7,10 +7,9 @@ import { FormProvider, SubmitHandler, useForm } from "react-hook-form"; | |||||
| import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
| import QcForm from "./QcForm"; | import QcForm from "./QcForm"; | ||||
| import { QcItemWithChecks } from "@/app/api/qc"; | import { QcItemWithChecks } from "@/app/api/qc"; | ||||
| import { Check } from "@mui/icons-material"; | |||||
| import { Check, CurrencyYuanRounded } from "@mui/icons-material"; | |||||
| import { StockInLine } from "@/app/api/po"; | import { StockInLine } from "@/app/api/po"; | ||||
| import { useSearchParams } from "next/navigation"; | import { useSearchParams } from "next/navigation"; | ||||
| import { stockInLineStatusMap } from "@/app/utils/formatUtil"; | |||||
| import { StockInLineRow } from "./PoInputGrid"; | import { StockInLineRow } from "./PoInputGrid"; | ||||
| import EscalationForm from "./EscalationForm"; | import EscalationForm from "./EscalationForm"; | ||||
| import StockInForm from "./StockInForm"; | import StockInForm from "./StockInForm"; | ||||
| @@ -86,25 +85,10 @@ const PoQcStockInModal: React.FC<Props> = ({ | |||||
| setDefaultValues({}); | setDefaultValues({}); | ||||
| }, []); | }, []); | ||||
| // status to be posted | |||||
| // const getPostingStatus = useCallback( | |||||
| // (type: string) => { | |||||
| // switch (type) { | |||||
| // case "qc": | |||||
| // return stockInLineStatusMap.receiving.key; | |||||
| // case "stockIn": | |||||
| // return stockInLineStatusMap.received.key; | |||||
| // case "putaway": | |||||
| // return stockInLineStatusMap.completed.key; | |||||
| // default: | |||||
| // return stockInLineStatusMap.pending.key; | |||||
| // } | |||||
| // }, [] | |||||
| // ) | |||||
| const onSubmit = useCallback<SubmitHandler<ModalFormInput & {}>>( | const onSubmit = useCallback<SubmitHandler<ModalFormInput & {}>>( | ||||
| async (data, event) => { | async (data, event) => { | ||||
| let hasErrors = false; | let hasErrors = false; | ||||
| console.log("errors"); | |||||
| console.log(errors); | console.log(errors); | ||||
| console.log(data); | console.log(data); | ||||
| console.log(itemDetail); | console.log(itemDetail); | ||||
| @@ -118,23 +102,28 @@ const PoQcStockInModal: React.FC<Props> = ({ | |||||
| if (data.productionDate && data.productionDate.length > 0) { | if (data.productionDate && data.productionDate.length > 0) { | ||||
| productionDate = data.productionDate | productionDate = data.productionDate | ||||
| } | } | ||||
| if (data.acceptedQty) { | |||||
| acceptedQty = parseInt(data.acceptedQty.toString()) | |||||
| } else { | |||||
| acceptedQty = data.sampleRate | |||||
| if (data.qcResult) { | |||||
| acceptedQty = itemDetail.acceptedQty - data.qcResult.reduce((acc, curr) => acc + curr.failQty, 0) | |||||
| } | } | ||||
| console.log(acceptedQty) | |||||
| // if (data.acceptedQty) { | |||||
| // console.log("1") | |||||
| // acceptedQty = parseInt(data.acceptedQty.toString()) | |||||
| // } else { | |||||
| // console.log("2") | |||||
| // acceptedQty = data.sampleRate | |||||
| // } | |||||
| const args = { | const args = { | ||||
| id: itemDetail.id, | id: itemDetail.id, | ||||
| purchaseOrderId: parseInt(params.get("id")!!), | purchaseOrderId: parseInt(params.get("id")!!), | ||||
| purchaseOrderLineId: itemDetail.purchaseOrderLineId, | purchaseOrderLineId: itemDetail.purchaseOrderLineId, | ||||
| itemId: itemDetail.itemId, | itemId: itemDetail.itemId, | ||||
| ...data, | ...data, | ||||
| acceptedQty: acceptedQty, | |||||
| productionDate: productionDate, | productionDate: productionDate, | ||||
| } as StockInLineEntry & ModalFormInput; | } as StockInLineEntry & ModalFormInput; | ||||
| ////////////////////////////////////////////////////////////////////// | ////////////////////////////////////////////////////////////////////// | ||||
| console.log(args) | console.log(args) | ||||
| return | |||||
| // return | |||||
| if (hasErrors) { | if (hasErrors) { | ||||
| setServerError(t("An error has occurred. Please try again later.")); | setServerError(t("An error has occurred. Please try again later.")); | ||||
| return false; | return false; | ||||
| @@ -1,6 +1,6 @@ | |||||
| "use client"; | "use client"; | ||||
| import { PurchaseQcCheck, PutawayInput } from "@/app/api/po/actions"; | |||||
| import { PurchaseQcResult, PutawayInput } from "@/app/api/po/actions"; | |||||
| import { | import { | ||||
| Autocomplete, | Autocomplete, | ||||
| Box, | Box, | ||||
| @@ -43,11 +43,11 @@ interface Props { | |||||
| } | } | ||||
| type EntryError = | type EntryError = | ||||
| | { | | { | ||||
| [field in keyof PurchaseQcCheck]?: string; | |||||
| [field in keyof PurchaseQcResult]?: string; | |||||
| } | } | ||||
| | undefined; | | undefined; | ||||
| // type PoQcRow = TableRow<Partial<PurchaseQcCheck>, EntryError>; | |||||
| // type PoQcRow = TableRow<Partial<PurchaseQcResult>, EntryError>; | |||||
| const PutawayForm: React.FC<Props> = ({ itemDetail, warehouse }) => { | const PutawayForm: React.FC<Props> = ({ itemDetail, warehouse }) => { | ||||
| const { t } = useTranslation(); | const { t } = useTranslation(); | ||||
| @@ -107,7 +107,7 @@ const PutawayForm: React.FC<Props> = ({ itemDetail, warehouse }) => { | |||||
| ); | ); | ||||
| useEffect(() => { | useEffect(() => { | ||||
| setValue("status", stockInLineStatusMap.completed.key) | |||||
| setValue("status", "completed") | |||||
| }, []) | }, []) | ||||
| return ( | return ( | ||||
| <Grid container justifyContent="flex-start" alignItems="flex-start"> | <Grid container justifyContent="flex-start" alignItems="flex-start"> | ||||
| @@ -173,7 +173,7 @@ const PutawayForm: React.FC<Props> = ({ itemDetail, warehouse }) => { | |||||
| sx={{ mt: 0.5 }} | sx={{ mt: 0.5 }} | ||||
| > | > | ||||
| {/* <Grid item xs={12}> | {/* <Grid item xs={12}> | ||||
| <InputDataGrid<PutawayInput, PurchaseQcCheck, EntryError> | |||||
| <InputDataGrid<PutawayInput, PurchaseQcResult, EntryError> | |||||
| apiRef={apiRef} | apiRef={apiRef} | ||||
| checkboxSelection={false} | checkboxSelection={false} | ||||
| _formKey={"qcCheck"} | _formKey={"qcCheck"} | ||||
| @@ -1,6 +1,6 @@ | |||||
| "use client"; | "use client"; | ||||
| import { PurchaseQcCheck, PurchaseQCInput } from "@/app/api/po/actions"; | |||||
| import { PurchaseQcResult, PurchaseQCInput } from "@/app/api/po/actions"; | |||||
| import { | import { | ||||
| Box, | Box, | ||||
| Card, | Card, | ||||
| @@ -35,6 +35,7 @@ import { fetchQcItemCheck } from "@/app/api/qc/actions"; | |||||
| import { QcItemWithChecks } from "@/app/api/qc"; | import { QcItemWithChecks } from "@/app/api/qc"; | ||||
| import axios from "@/app/(main)/axios/axiosInstance"; | import axios from "@/app/(main)/axios/axiosInstance"; | ||||
| import { NEXT_PUBLIC_API_URL } from "@/config/api"; | import { NEXT_PUBLIC_API_URL } from "@/config/api"; | ||||
| import axiosInstance from "@/app/(main)/axios/axiosInstance"; | |||||
| interface Props { | interface Props { | ||||
| itemDetail: StockInLine; | itemDetail: StockInLine; | ||||
| @@ -42,11 +43,11 @@ interface Props { | |||||
| } | } | ||||
| type EntryError = | type EntryError = | ||||
| | { | | { | ||||
| [field in keyof PurchaseQcCheck]?: string; | |||||
| [field in keyof PurchaseQcResult]?: string; | |||||
| } | } | ||||
| | undefined; | | undefined; | ||||
| type PoQcRow = TableRow<Partial<PurchaseQcCheck>, EntryError>; | |||||
| type PoQcRow = TableRow<Partial<PurchaseQcResult>, EntryError>; | |||||
| // fetchQcItemCheck | // fetchQcItemCheck | ||||
| const QcForm: React.FC<Props> = ({ qc, itemDetail }) => { | const QcForm: React.FC<Props> = ({ qc, itemDetail }) => { | ||||
| const { t } = useTranslation(); | const { t } = useTranslation(); | ||||
| @@ -67,6 +68,10 @@ const QcForm: React.FC<Props> = ({ qc, itemDetail }) => { | |||||
| // const [qc, setQc] = useState<QcItemWithChecks[]>([]) | // const [qc, setQc] = useState<QcItemWithChecks[]>([]) | ||||
| // const fetchQcCheck = useCallback(async () => { | // const fetchQcCheck = useCallback(async () => { | ||||
| // const authHeader = axiosInstance.defaults.headers['Authorization']; | |||||
| // if (!authHeader) { | |||||
| // return; // Exit the function if the token is not set | |||||
| // } | |||||
| // const params = { | // const params = { | ||||
| // itemId: itemDetail.itemId | // itemId: itemDetail.itemId | ||||
| // } | // } | ||||
| @@ -77,11 +82,12 @@ const QcForm: React.FC<Props> = ({ qc, itemDetail }) => { | |||||
| // useEffect(() => { | // useEffect(() => { | ||||
| // fetchQcCheck() | // fetchQcCheck() | ||||
| // }, [fetchQcCheck]) | // }, [fetchQcCheck]) | ||||
| const [recordQty, setRecordQty] = useState(0); | const [recordQty, setRecordQty] = useState(0); | ||||
| const columns = useMemo<GridColDef[]>( | const columns = useMemo<GridColDef[]>( | ||||
| () => [ | () => [ | ||||
| { | { | ||||
| field: "qcCheckId", | |||||
| field: "qcItemId", | |||||
| headerName: "qc Check", | headerName: "qc Check", | ||||
| flex: 1, | flex: 1, | ||||
| editable: true, | editable: true, | ||||
| @@ -90,7 +96,7 @@ const QcForm: React.FC<Props> = ({ qc, itemDetail }) => { | |||||
| if (!row) { | if (!row) { | ||||
| return null; | return null; | ||||
| } | } | ||||
| const Qc = qc.find((q) => q.id === row.qcCheckId); | |||||
| const Qc = qc.find((q) => q.id === row.qcItemId); | |||||
| return Qc ? `${Qc.code} - ${Qc.name}` : t("Please select QC"); | return Qc ? `${Qc.code} - ${Qc.name}` : t("Please select QC"); | ||||
| }, | }, | ||||
| renderCell(params: GridRenderCellParams<PoQcRow, number>) { | renderCell(params: GridRenderCellParams<PoQcRow, number>) { | ||||
| @@ -99,18 +105,23 @@ const QcForm: React.FC<Props> = ({ qc, itemDetail }) => { | |||||
| }, | }, | ||||
| renderEditCell(params: GridRenderEditCellParams<PoQcRow, number>) { | renderEditCell(params: GridRenderEditCellParams<PoQcRow, number>) { | ||||
| const errorMessage = | const errorMessage = | ||||
| params.row._error?.[params.field as keyof PurchaseQcCheck]; | |||||
| params.row._error?.[params.field as keyof PurchaseQcResult]; | |||||
| console.log(errorMessage); | console.log(errorMessage); | ||||
| const content = ( | const content = ( | ||||
| <QcSelect | <QcSelect | ||||
| allQcs={qc} | allQcs={qc} | ||||
| value={params.row.qcCheckId} | |||||
| onQcSelect={async (qcCheckId) => { | |||||
| value={params.row.qcItemId} | |||||
| onQcSelect={async (qcItemId) => { | |||||
| await params.api.setEditCellValue({ | await params.api.setEditCellValue({ | ||||
| id: params.id, | id: params.id, | ||||
| field: "qcCheckId", | |||||
| value: qcCheckId, | |||||
| field: "qcItemId", | |||||
| value: qcItemId, | |||||
| }); | }); | ||||
| // await params.api.setEditCellValue({ | |||||
| // id: params.id, | |||||
| // field: "type", | |||||
| // value: "determine1", | |||||
| // }); | |||||
| }} | }} | ||||
| /> | /> | ||||
| ); | ); | ||||
| @@ -124,8 +135,8 @@ const QcForm: React.FC<Props> = ({ qc, itemDetail }) => { | |||||
| }, | }, | ||||
| }, | }, | ||||
| { | { | ||||
| field: "qty", | |||||
| headerName: "qty", | |||||
| field: "failQty", | |||||
| headerName: "failQty", | |||||
| flex: 1, | flex: 1, | ||||
| editable: true, | editable: true, | ||||
| type: "number", | type: "number", | ||||
| @@ -135,7 +146,7 @@ const QcForm: React.FC<Props> = ({ qc, itemDetail }) => { | |||||
| // setUnrecordQty((prev) => prev - recordQty) | // setUnrecordQty((prev) => prev - recordQty) | ||||
| // } | // } | ||||
| const errorMessage = | const errorMessage = | ||||
| params.row._error?.[params.field as keyof PurchaseQcCheck]; | |||||
| params.row._error?.[params.field as keyof PurchaseQcResult]; | |||||
| const content = <GridEditInputCell {...params} />; | const content = <GridEditInputCell {...params} />; | ||||
| return errorMessage ? ( | return errorMessage ? ( | ||||
| <Tooltip title={t(errorMessage)}> | <Tooltip title={t(errorMessage)}> | ||||
| @@ -152,15 +163,15 @@ const QcForm: React.FC<Props> = ({ qc, itemDetail }) => { | |||||
| const validation = useCallback( | const validation = useCallback( | ||||
| (newRow: GridRowModel<PoQcRow>): EntryError => { | (newRow: GridRowModel<PoQcRow>): EntryError => { | ||||
| const error: EntryError = {}; | const error: EntryError = {}; | ||||
| const { qcCheckId, qty } = newRow; | |||||
| if (!qcCheckId || qcCheckId <= 0) { | |||||
| error["qcCheckId"] = "select qc"; | |||||
| const { qcItemId, failQty } = newRow; | |||||
| if (!qcItemId || qcItemId <= 0) { | |||||
| error["qcItemId"] = "select qc"; | |||||
| } | } | ||||
| if (!qty || qty <= 0) { | |||||
| error["qty"] = "enter a qty"; | |||||
| if (!failQty || failQty <= 0) { | |||||
| error["failQty"] = "enter a failQty"; | |||||
| } | } | ||||
| if (qty && qty > itemDetail.acceptedQty) { | |||||
| error["qty"] = "qty too big"; | |||||
| if (failQty && failQty > itemDetail.acceptedQty) { | |||||
| error["failQty"] = "qty too big"; | |||||
| } | } | ||||
| return Object.keys(error).length > 0 ? error : undefined; | return Object.keys(error).length > 0 ? error : undefined; | ||||
| }, | }, | ||||
| @@ -169,7 +180,7 @@ const QcForm: React.FC<Props> = ({ qc, itemDetail }) => { | |||||
| useEffect(() => { | useEffect(() => { | ||||
| console.log(itemDetail) | console.log(itemDetail) | ||||
| var status = stockInLineStatusMap.receiving.key | |||||
| var status = "receiving" | |||||
| // switch (itemDetail.status) { | // switch (itemDetail.status) { | ||||
| // case 'pending': | // case 'pending': | ||||
| // status = "receiving" | // status = "receiving" | ||||
| @@ -194,15 +205,16 @@ const QcForm: React.FC<Props> = ({ qc, itemDetail }) => { | |||||
| > | > | ||||
| <Grid item xs={6}> | <Grid item xs={6}> | ||||
| <TextField | <TextField | ||||
| label={t("Total qty")} | |||||
| label={t("accepted Qty")} | |||||
| fullWidth | fullWidth | ||||
| value={itemDetail.acceptedQty} | |||||
| disabled | |||||
| // {...register("sampleRate", { | |||||
| // required: "sampleRate required!", | |||||
| // })} | |||||
| // error={Boolean(errors.sampleRate)} | |||||
| // helperText={errors.sampleRate?.message} | |||||
| // value={itemDetail.acceptedQty} | |||||
| {...register("acceptedQty", { | |||||
| required: "acceptedQty required!", | |||||
| valueAsNumber: true | |||||
| })} | |||||
| // disabled | |||||
| error={Boolean(errors.acceptedQty)} | |||||
| helperText={errors.acceptedQty?.message} | |||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| <Grid item xs={6}> | <Grid item xs={6}> | ||||
| @@ -224,6 +236,7 @@ const QcForm: React.FC<Props> = ({ qc, itemDetail }) => { | |||||
| fullWidth | fullWidth | ||||
| {...register("sampleRate", { | {...register("sampleRate", { | ||||
| required: "sampleRate required!", | required: "sampleRate required!", | ||||
| valueAsNumber: true | |||||
| })} | })} | ||||
| error={Boolean(errors.sampleRate)} | error={Boolean(errors.sampleRate)} | ||||
| helperText={errors.sampleRate?.message} | helperText={errors.sampleRate?.message} | ||||
| @@ -260,10 +273,10 @@ const QcForm: React.FC<Props> = ({ qc, itemDetail }) => { | |||||
| sx={{ mt: 0.5 }} | sx={{ mt: 0.5 }} | ||||
| > | > | ||||
| <Grid item xs={12}> | <Grid item xs={12}> | ||||
| <InputDataGrid<PurchaseQCInput, PurchaseQcCheck, EntryError> | |||||
| <InputDataGrid<PurchaseQCInput, PurchaseQcResult, EntryError> | |||||
| apiRef={apiRef} | apiRef={apiRef} | ||||
| checkboxSelection={false} | checkboxSelection={false} | ||||
| _formKey={"qcCheck"} | |||||
| _formKey={"qcResult"} | |||||
| columns={columns} | columns={columns} | ||||
| validateRow={validation} | validateRow={validation} | ||||
| /> | /> | ||||
| @@ -19,7 +19,7 @@ interface CommonProps { | |||||
| interface SingleAutocompleteProps extends CommonProps { | interface SingleAutocompleteProps extends CommonProps { | ||||
| value: number | string | undefined; | value: number | string | undefined; | ||||
| onQcSelect: (qcCheckId: number) => void | Promise<void>; | |||||
| onQcSelect: (qcItemId: number) => void | Promise<void>; | |||||
| // multiple: false; | // multiple: false; | ||||
| } | } | ||||
| @@ -1,6 +1,6 @@ | |||||
| "use client"; | "use client"; | ||||
| import { PurchaseQcCheck, PurchaseQCInput, StockInInput } from "@/app/api/po/actions"; | |||||
| import { PurchaseQcResult, PurchaseQCInput, StockInInput } from "@/app/api/po/actions"; | |||||
| import { | import { | ||||
| Box, | Box, | ||||
| Card, | Card, | ||||
| @@ -31,8 +31,7 @@ import QcSelect from "./QcSelect"; | |||||
| import { QcItemWithChecks } from "@/app/api/qc"; | import { QcItemWithChecks } from "@/app/api/qc"; | ||||
| import { GridEditInputCell } from "@mui/x-data-grid"; | import { GridEditInputCell } from "@mui/x-data-grid"; | ||||
| import { StockInLine } from "@/app/api/po"; | import { StockInLine } from "@/app/api/po"; | ||||
| import { stockInLineStatusMap } from "@/app/utils/formatUtil"; | |||||
| // change PurchaseQcCheck to stock in entry props | |||||
| // change PurchaseQcResult to stock in entry props | |||||
| interface Props { | interface Props { | ||||
| itemDetail: StockInLine; | itemDetail: StockInLine; | ||||
| // qc: QcItemWithChecks[]; | // qc: QcItemWithChecks[]; | ||||
| @@ -43,7 +42,7 @@ type EntryError = | |||||
| } | } | ||||
| | undefined; | | undefined; | ||||
| // type PoQcRow = TableRow<Partial<PurchaseQcCheck>, EntryError>; | |||||
| // type PoQcRow = TableRow<Partial<PurchaseQcResult>, EntryError>; | |||||
| const StockInForm: React.FC<Props> = ({ | const StockInForm: React.FC<Props> = ({ | ||||
| // qc, | // qc, | ||||
| @@ -67,7 +66,7 @@ const StockInForm: React.FC<Props> = ({ | |||||
| useEffect(() => { | useEffect(() => { | ||||
| console.log("triggered") | console.log("triggered") | ||||
| setValue("status", stockInLineStatusMap.received.key) | |||||
| setValue("status", "received") | |||||
| }, []) | }, []) | ||||
| return ( | return ( | ||||
| @@ -159,7 +158,7 @@ const StockInForm: React.FC<Props> = ({ | |||||
| sx={{ mt: 0.5 }} | sx={{ mt: 0.5 }} | ||||
| > | > | ||||
| {/* <Grid item xs={12}> | {/* <Grid item xs={12}> | ||||
| <InputDataGrid<PurchaseQCInput, PurchaseQcCheck, EntryError> | |||||
| <InputDataGrid<PurchaseQCInput, PurchaseQcResult, EntryError> | |||||
| apiRef={apiRef} | apiRef={apiRef} | ||||
| checkboxSelection={false} | checkboxSelection={false} | ||||
| _formKey={"qcCheck"} | _formKey={"qcCheck"} | ||||