@@ -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"} | ||||