@@ -55,6 +55,8 @@ import { downloadFile } from "@/app/utils/commonUtil"; | |||
import { fetchPoQrcode } from "@/app/api/pdf/actions"; | |||
import { fetchQcResult } from "@/app/api/qc/actions"; | |||
import PoQcStockInModal from "./PoQcStockInModal"; | |||
import { notifyActionSuccess } from "../Toast/Toast"; | |||
import DoDisturbIcon from "@mui/icons-material/DoDisturb"; | |||
interface ResultWithId { | |||
id: number; | |||
@@ -124,6 +126,7 @@ function PoInputGrid({ | |||
const [escalOpen, setEscalOpen] = useState(false); | |||
const [stockInOpen, setStockInOpen] = useState(false); | |||
const [putAwayOpen, setPutAwayOpen] = useState(false); | |||
const [rejectOpen, setRejectOpen] = useState(false); | |||
const [btnIsLoading, setBtnIsLoading] = useState(false); | |||
const [currQty, setCurrQty] = useState(() => { | |||
const total = entries.reduce( | |||
@@ -178,6 +181,7 @@ function PoInputGrid({ | |||
) as StockInLine[] | |||
); | |||
setBtnIsLoading(false); | |||
notifyActionSuccess(); | |||
// do post directly to test | |||
// openStartModal(); | |||
}, 200); | |||
@@ -229,6 +233,27 @@ function PoInputGrid({ | |||
}, | |||
[] | |||
); | |||
const handleReject = useCallback( | |||
(id: GridRowId, params: any) => () => { | |||
setRowModesModel((prev) => ({ | |||
...prev, | |||
[id]: { mode: GridRowModes.View }, | |||
})); | |||
setModalInfo(params.row); | |||
setTimeout(() => { | |||
// open stock in modal | |||
// openPutAwayModal(); | |||
// return the record with its status as pending | |||
// update layout | |||
console.log("delayed"); | |||
openRejectModal(); | |||
// printQrcode(params.row); | |||
}, 200); | |||
}, | |||
[] | |||
); | |||
const handleStockIn = useCallback( | |||
(id: GridRowId, params: any) => () => { | |||
// setBtnIsLoading(true); | |||
@@ -332,6 +357,13 @@ function PoInputGrid({ | |||
setEscalOpen(true); | |||
}, []); | |||
const closeRejectModal = useCallback(() => { | |||
setRejectOpen(false); | |||
}, []); | |||
const openRejectModal = useCallback(() => { | |||
setRejectOpen(true); | |||
}, []); | |||
const columns = useMemo<GridColDef[]>( | |||
() => [ | |||
{ | |||
@@ -393,7 +425,7 @@ function PoInputGrid({ | |||
color: "primary.main", | |||
// marginRight: 1, | |||
}} | |||
disabled={btnIsLoading || !(stockInLineStatusMap[status] === 0)} | |||
disabled={!(stockInLineStatusMap[status] === 0)} | |||
// set _isNew to false after posting | |||
// or check status | |||
onClick={handleStart(params.row.id, params)} | |||
@@ -407,7 +439,10 @@ function PoInputGrid({ | |||
color: "primary.main", | |||
// marginRight: 1, | |||
}} | |||
disabled={btnIsLoading || stockInLineStatusMap[status] < 1} | |||
disabled={ | |||
// stockInLineStatusMap[status] === 9 || | |||
stockInLineStatusMap[status] < 1 | |||
} | |||
// set _isNew to false after posting | |||
// or check status | |||
onClick={handleQC(params.row.id, params)} | |||
@@ -422,7 +457,7 @@ function PoInputGrid({ | |||
// marginRight: 1, | |||
}} | |||
disabled={ | |||
btnIsLoading || | |||
stockInLineStatusMap[status] === 9 || | |||
stockInLineStatusMap[status] <= 0 || | |||
stockInLineStatusMap[status] >= 5 | |||
} | |||
@@ -440,7 +475,7 @@ function PoInputGrid({ | |||
// marginRight: 1, | |||
}} | |||
disabled={ | |||
btnIsLoading || | |||
stockInLineStatusMap[status] === 9 || | |||
stockInLineStatusMap[status] <= 2 || | |||
stockInLineStatusMap[status] >= 7 | |||
} | |||
@@ -457,7 +492,7 @@ function PoInputGrid({ | |||
color: "primary.main", | |||
// marginRight: 1, | |||
}} | |||
disabled={btnIsLoading || stockInLineStatusMap[status] < 7} | |||
disabled={stockInLineStatusMap[status] === 9 || stockInLineStatusMap[status] < 7} | |||
// set _isNew to false after posting | |||
// or check status | |||
onClick={handlePutAway(params.row.id, params)} | |||
@@ -471,7 +506,7 @@ function PoInputGrid({ | |||
color: "primary.main", | |||
// marginRight: 1, | |||
}} | |||
disabled={btnIsLoading || stockInLineStatusMap[status] !== 8} | |||
disabled={stockInLineStatusMap[status] === 9 || stockInLineStatusMap[status] !== 8} | |||
// set _isNew to false after posting | |||
// or check status | |||
onClick={handleQrCode(params.row.id, params)} | |||
@@ -479,14 +514,26 @@ function PoInputGrid({ | |||
key="edit" | |||
/>, | |||
<GridActionsCellItem | |||
icon={<DeleteIcon />} | |||
icon={ | |||
stockInLineStatusMap[status] >= 1 ? ( | |||
<DoDisturbIcon /> | |||
) : ( | |||
<DeleteIcon /> | |||
) | |||
} | |||
label="Delete" | |||
sx={{ | |||
color: "error.main", | |||
}} | |||
disabled={btnIsLoading || stockInLineStatusMap[status] !== 0} | |||
// disabled={Boolean(params.row.status)} | |||
onClick={handleDelete(params.row.id)} | |||
disabled={ | |||
stockInLineStatusMap[status] >= 7 && | |||
stockInLineStatusMap[status] <= 9 | |||
} | |||
onClick={ | |||
stockInLineStatusMap[status] === 0 | |||
? handleDelete(params.row.id) | |||
: handleReject(params.row.id, params) | |||
} | |||
color="inherit" | |||
key="edit" | |||
/>, | |||
@@ -494,7 +541,7 @@ function PoInputGrid({ | |||
}, | |||
}, | |||
], | |||
[btnIsLoading] | |||
[stockInLineStatusMap, btnIsLoading, handleQrCode, handleReject] | |||
); | |||
const addRow = useCallback(() => { | |||
@@ -671,6 +718,21 @@ function PoInputGrid({ | |||
/> | |||
</> | |||
)} | |||
{modalInfo !== undefined && ( | |||
<> | |||
<PoQcStockInModal | |||
type={"reject"} | |||
// setRows={setRows} | |||
setEntries={setEntries} | |||
setStockInLine={setStockInLine} | |||
setItemDetail={setModalInfo} | |||
// qc={qc} | |||
open={rejectOpen} | |||
onClose={closeRejectModal} | |||
itemDetail={modalInfo} | |||
/> | |||
</> | |||
)} | |||
{modalInfo !== undefined && ( | |||
<> | |||
<PoQcStockInModal | |||
@@ -39,6 +39,7 @@ import { downloadFile } from "@/app/utils/commonUtil"; | |||
import { fetchPoQrcode } from "@/app/api/pdf/actions"; | |||
import UploadContext from "../UploadProvider/UploadProvider"; | |||
import useUploadContext from "../UploadProvider/useUploadContext"; | |||
import RejectForm from "./RejectForm"; | |||
dayjs.extend(arraySupport); | |||
interface CommonProps extends Omit<ModalProps, "children"> { | |||
@@ -56,7 +57,7 @@ interface CommonProps extends Omit<ModalProps, "children"> { | |||
>; | |||
qc?: QcItemWithChecks[]; | |||
warehouse?: any[]; | |||
type: "qc" | "stockIn" | "escalation" | "putaway"; | |||
type: "qc" | "stockIn" | "escalation" | "putaway" | "reject"; | |||
} | |||
interface QcProps extends CommonProps { | |||
qc: QcItemWithChecks[]; | |||
@@ -74,8 +75,17 @@ interface EscalationProps extends CommonProps { | |||
// naming | |||
type: "escalation"; | |||
} | |||
interface RejectProps extends CommonProps { | |||
// naming | |||
type: "reject"; | |||
} | |||
type Props = QcProps | StockInProps | PutawayProps | EscalationProps; | |||
type Props = | |||
| QcProps | |||
| StockInProps | |||
| PutawayProps | |||
| EscalationProps | |||
| RejectProps; | |||
const style = { | |||
position: "absolute", | |||
top: "50%", | |||
@@ -194,7 +204,7 @@ const PoQcStockInModal: React.FC<Props> = ({ | |||
const onSubmit = useCallback<SubmitHandler<ModalFormInput & {}>>( | |||
async (data, event) => { | |||
setBtnIsLoading(true); | |||
setIsUploading(true) | |||
setIsUploading(true); | |||
formProps.clearErrors(); | |||
let hasErrors = false; | |||
console.log(errors); | |||
@@ -204,12 +214,12 @@ const PoQcStockInModal: React.FC<Props> = ({ | |||
try { | |||
// add checking | |||
if (type === "stockIn") { | |||
hasErrors = checkStockIn(data) | |||
console.log(hasErrors) | |||
hasErrors = checkStockIn(data); | |||
console.log(hasErrors); | |||
} | |||
if (type === "putaway") { | |||
hasErrors = checkPutaway(data); | |||
console.log(hasErrors) | |||
console.log(hasErrors); | |||
} | |||
//////////////////////// modify this mess later ////////////////////// | |||
var productionDate = null; | |||
@@ -246,7 +256,7 @@ const PoQcStockInModal: React.FC<Props> = ({ | |||
console.log(args); | |||
setServerError(t("An error has occurred. Please try again later.")); | |||
setBtnIsLoading(false); | |||
setIsUploading(false) | |||
setIsUploading(false); | |||
return; | |||
} | |||
console.log(args); | |||
@@ -294,7 +304,7 @@ const PoQcStockInModal: React.FC<Props> = ({ | |||
} | |||
// add loading | |||
setBtnIsLoading(false); | |||
setIsUploading(false) | |||
setIsUploading(false); | |||
setItemDetail(undefined); | |||
closeHandler({}, "backdropClick"); | |||
} | |||
@@ -303,7 +313,7 @@ const PoQcStockInModal: React.FC<Props> = ({ | |||
} catch (e) { | |||
// server error | |||
setBtnIsLoading(false); | |||
setIsUploading(false) | |||
setIsUploading(false); | |||
setServerError(t("An error has occurred. Please try again later.")); | |||
console.log(e); | |||
} | |||
@@ -313,7 +323,7 @@ const PoQcStockInModal: React.FC<Props> = ({ | |||
const printQrcode = useCallback(async () => { | |||
setBtnIsLoading(true); | |||
setIsUploading(true) | |||
setIsUploading(true); | |||
const postData = { stockInLineIds: [itemDetail.id] }; | |||
// const postData = { stockInLineIds: [42,43,44] }; | |||
const response = await fetchPoQrcode(postData); | |||
@@ -322,7 +332,7 @@ const PoQcStockInModal: React.FC<Props> = ({ | |||
downloadFile(new Uint8Array(response.blobValue), response.filename!!); | |||
} | |||
setBtnIsLoading(false); | |||
setIsUploading(false) | |||
setIsUploading(false); | |||
}, [itemDetail, fetchPoQrcode, downloadFile]); | |||
const renderSubmitButton = useMemo((): boolean => { | |||
@@ -348,6 +358,11 @@ const PoQcStockInModal: React.FC<Props> = ({ | |||
); | |||
case "putaway": | |||
return stockInLineStatusMap[status] === 7; | |||
case "reject": | |||
return ( | |||
stockInLineStatusMap[status] >= 1 && | |||
stockInLineStatusMap[status] <= 6 | |||
); | |||
default: | |||
return false; // Handle unexpected type | |||
} | |||
@@ -366,16 +381,36 @@ const PoQcStockInModal: React.FC<Props> = ({ | |||
onSubmit={formProps.handleSubmit(onSubmit)} | |||
> | |||
{itemDetail !== undefined && type === "qc" && ( | |||
<QcForm qc={qc!!} itemDetail={itemDetail} disabled={renderSubmitButton}/> | |||
<QcForm | |||
qc={qc!!} | |||
itemDetail={itemDetail} | |||
disabled={!renderSubmitButton} | |||
/> | |||
)} | |||
{itemDetail !== undefined && type === "stockIn" && ( | |||
<StockInForm itemDetail={itemDetail} disabled={renderSubmitButton}/> | |||
<StockInForm | |||
itemDetail={itemDetail} | |||
disabled={!renderSubmitButton} | |||
/> | |||
)} | |||
{itemDetail !== undefined && type === "escalation" && ( | |||
<EscalationForm itemDetail={itemDetail} disabled={renderSubmitButton}/> | |||
<EscalationForm | |||
itemDetail={itemDetail} | |||
disabled={!renderSubmitButton} | |||
/> | |||
)} | |||
{itemDetail !== undefined && type === "putaway" && ( | |||
<PutawayForm itemDetail={itemDetail} warehouse={warehouse!!} disabled={renderSubmitButton}/> | |||
<PutawayForm | |||
itemDetail={itemDetail} | |||
warehouse={warehouse!!} | |||
disabled={!renderSubmitButton} | |||
/> | |||
)} | |||
{itemDetail !== undefined && type === "reject" && ( | |||
<RejectForm | |||
itemDetail={itemDetail} | |||
disabled={!renderSubmitButton} | |||
/> | |||
)} | |||
<Stack direction="row" justifyContent="flex-end" gap={1}> | |||
{renderSubmitButton ? ( | |||
@@ -249,7 +249,7 @@ const QcForm: React.FC<Props> = ({ qc, itemDetail, disabled }) => { | |||
<TextField | |||
label={t("sampleRate")} | |||
fullWidth | |||
defaultValue={1} | |||
// defaultValue={1} | |||
{...register("sampleRate", { | |||
required: "sampleRate required!", | |||
valueAsNumber: true, | |||
@@ -263,7 +263,7 @@ const QcForm: React.FC<Props> = ({ qc, itemDetail, disabled }) => { | |||
<TextField | |||
label={t("sampleWeight")} | |||
fullWidth | |||
defaultValue={1} | |||
// defaultValue={1} | |||
{...register("sampleWeight", { | |||
required: "sampleWeight required!", | |||
valueAsNumber: true, | |||
@@ -277,7 +277,7 @@ const QcForm: React.FC<Props> = ({ qc, itemDetail, disabled }) => { | |||
<TextField | |||
label={t("totalWeight")} | |||
fullWidth | |||
defaultValue={1} | |||
// defaultValue={1} | |||
{...register("totalWeight", { | |||
required: "totalWeight required!", | |||
valueAsNumber: true, | |||
@@ -0,0 +1,125 @@ | |||
"use client"; | |||
import { StockInLineEntry, EscalationInput } from "@/app/api/po/actions"; | |||
import { | |||
Box, | |||
Card, | |||
CardContent, | |||
Grid, | |||
Stack, | |||
TextField, | |||
Tooltip, | |||
Typography, | |||
} from "@mui/material"; | |||
import { useFormContext } from "react-hook-form"; | |||
import { useTranslation } from "react-i18next"; | |||
import StyledDataGrid from "../StyledDataGrid"; | |||
import { useCallback, useEffect, useMemo } from "react"; | |||
import { | |||
GridColDef, | |||
GridRowIdGetter, | |||
GridRowModel, | |||
useGridApiContext, | |||
GridRenderCellParams, | |||
GridRenderEditCellParams, | |||
useGridApiRef, | |||
} from "@mui/x-data-grid"; | |||
import InputDataGrid from "../InputDataGrid"; | |||
import { TableRow } from "../InputDataGrid/InputDataGrid"; | |||
import TwoLineCell from "./TwoLineCell"; | |||
import QcSelect from "./QcSelect"; | |||
import { QcItemWithChecks } from "@/app/api/qc"; | |||
import { GridEditInputCell } from "@mui/x-data-grid"; | |||
import { StockInLine } from "@/app/api/po"; | |||
import { stockInLineStatusMap } from "@/app/utils/formatUtil"; | |||
interface Props { | |||
itemDetail: StockInLine; | |||
// qc: QcItemWithChecks[]; | |||
disabled: boolean | |||
} | |||
type EntryError = | |||
| { | |||
[field in keyof StockInLineEntry]?: string; | |||
} | |||
| undefined; | |||
const RejectForm: React.FC<Props> = ({ | |||
// qc, | |||
itemDetail, | |||
disabled | |||
}) => { | |||
const { t } = useTranslation(); | |||
const apiRef = useGridApiRef(); | |||
const { | |||
register, | |||
formState: { errors, defaultValues, touchedFields }, | |||
watch, | |||
control, | |||
setValue, | |||
getValues, | |||
reset, | |||
resetField, | |||
setError, | |||
clearErrors, | |||
} = useFormContext<EscalationInput>(); | |||
console.log(itemDetail) | |||
// const status = "rejected" | |||
const acceptedQty = watch("acceptedQty") || 0 | |||
console.log(disabled) | |||
useEffect(() => { | |||
console.log("triggered") | |||
setValue("status", "rejected") | |||
}, []) | |||
return ( | |||
<Grid container justifyContent="flex-start" alignItems="flex-start"> | |||
<Grid item xs={12}> | |||
<Typography variant="h6" display="block" marginBlockEnd={1}> | |||
{t(`Reject`)} | |||
</Typography> | |||
</Grid> | |||
<Grid item xs={12}> | |||
<Typography variant="h6" display="block" marginBlockEnd={1}> | |||
{t(`to be processed`)}: {itemDetail.acceptedQty - acceptedQty} | |||
</Typography> | |||
</Grid> | |||
<Grid | |||
container | |||
justifyContent="flex-start" | |||
alignItems="flex-start" | |||
spacing={2} | |||
sx={{ mt: 0.5 }} | |||
> | |||
<Grid item xs={6}> | |||
<TextField | |||
label={t("acceptedQty")} | |||
fullWidth | |||
{...register("acceptedQty", { | |||
required: "acceptedQty required!", | |||
min: 0, | |||
valueAsNumber: true, | |||
max: itemDetail.acceptedQty | |||
})} | |||
disabled={disabled} | |||
defaultValue={itemDetail.acceptedQty} | |||
error={Boolean(errors.acceptedQty)} | |||
helperText={errors.acceptedQty?.message} | |||
/> | |||
</Grid> | |||
</Grid> | |||
<Grid | |||
container | |||
justifyContent="flex-start" | |||
alignItems="flex-start" | |||
spacing={2} | |||
sx={{ mt: 0.5 }} | |||
> | |||
</Grid> | |||
</Grid> | |||
); | |||
}; | |||
export default RejectForm; |