Browse Source

update stock in with qc

create_edit_user
MSI\derek 3 months ago
parent
commit
f4856b78a6
9 changed files with 176 additions and 230 deletions
  1. +7
    -5
      src/app/api/po/actions.ts
  2. +11
    -10
      src/app/utils/formatUtil.ts
  3. +47
    -103
      src/components/PoDetail/EscalationForm.tsx
  4. +43
    -45
      src/components/PoDetail/PoInputGrid.tsx
  5. +13
    -24
      src/components/PoDetail/PoQcStockInModal.tsx
  6. +5
    -5
      src/components/PoDetail/PutawayForm.tsx
  7. +44
    -31
      src/components/PoDetail/QcForm.tsx
  8. +1
    -1
      src/components/PoDetail/QcSelect.tsx
  9. +5
    -6
      src/components/PoDetail/StockInForm.tsx

+ 7
- 5
src/app/api/po/actions.ts View File

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


+ 11
- 10
src/app/utils/formatUtil.ts View File

@@ -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,
}; };

+ 47
- 103
src/components/PoDetail/EscalationForm.tsx View File

@@ -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>
); );


+ 43
- 45
src/components/PoDetail/PoInputGrid.tsx View File

@@ -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>) => {


+ 13
- 24
src/components/PoDetail/PoQcStockInModal.tsx View File

@@ -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;


+ 5
- 5
src/components/PoDetail/PutawayForm.tsx View File

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


+ 44
- 31
src/components/PoDetail/QcForm.tsx View File

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


+ 1
- 1
src/components/PoDetail/QcSelect.tsx View File

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




+ 5
- 6
src/components/PoDetail/StockInForm.tsx View File

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


Loading…
Cancel
Save