瀏覽代碼

update

create_edit_user
MSI\derek 2 月之前
父節點
當前提交
677de6152a
共有 4 個檔案被更改,包括 251 行新增29 行删除
  1. +73
    -11
      src/components/PoDetail/PoInputGrid.tsx
  2. +50
    -15
      src/components/PoDetail/PoQcStockInModal.tsx
  3. +3
    -3
      src/components/PoDetail/QcForm.tsx
  4. +125
    -0
      src/components/PoDetail/RejectForm.tsx

+ 73
- 11
src/components/PoDetail/PoInputGrid.tsx 查看文件

@@ -55,6 +55,8 @@ import { downloadFile } from "@/app/utils/commonUtil";
import { fetchPoQrcode } from "@/app/api/pdf/actions"; import { fetchPoQrcode } from "@/app/api/pdf/actions";
import { fetchQcResult } from "@/app/api/qc/actions"; import { fetchQcResult } from "@/app/api/qc/actions";
import PoQcStockInModal from "./PoQcStockInModal"; import PoQcStockInModal from "./PoQcStockInModal";
import { notifyActionSuccess } from "../Toast/Toast";
import DoDisturbIcon from "@mui/icons-material/DoDisturb";


interface ResultWithId { interface ResultWithId {
id: number; id: number;
@@ -124,6 +126,7 @@ function PoInputGrid({
const [escalOpen, setEscalOpen] = useState(false); const [escalOpen, setEscalOpen] = useState(false);
const [stockInOpen, setStockInOpen] = useState(false); const [stockInOpen, setStockInOpen] = useState(false);
const [putAwayOpen, setPutAwayOpen] = useState(false); const [putAwayOpen, setPutAwayOpen] = useState(false);
const [rejectOpen, setRejectOpen] = useState(false);
const [btnIsLoading, setBtnIsLoading] = useState(false); const [btnIsLoading, setBtnIsLoading] = useState(false);
const [currQty, setCurrQty] = useState(() => { const [currQty, setCurrQty] = useState(() => {
const total = entries.reduce( const total = entries.reduce(
@@ -178,6 +181,7 @@ function PoInputGrid({
) as StockInLine[] ) as StockInLine[]
); );
setBtnIsLoading(false); setBtnIsLoading(false);
notifyActionSuccess();
// do post directly to test // do post directly to test
// openStartModal(); // openStartModal();
}, 200); }, 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( const handleStockIn = useCallback(
(id: GridRowId, params: any) => () => { (id: GridRowId, params: any) => () => {
// setBtnIsLoading(true); // setBtnIsLoading(true);
@@ -332,6 +357,13 @@ function PoInputGrid({
setEscalOpen(true); setEscalOpen(true);
}, []); }, []);


const closeRejectModal = useCallback(() => {
setRejectOpen(false);
}, []);
const openRejectModal = useCallback(() => {
setRejectOpen(true);
}, []);

const columns = useMemo<GridColDef[]>( const columns = useMemo<GridColDef[]>(
() => [ () => [
{ {
@@ -393,7 +425,7 @@ function PoInputGrid({
color: "primary.main", color: "primary.main",
// marginRight: 1, // marginRight: 1,
}} }}
disabled={btnIsLoading || !(stockInLineStatusMap[status] === 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)}
@@ -407,7 +439,10 @@ function PoInputGrid({
color: "primary.main", color: "primary.main",
// marginRight: 1, // marginRight: 1,
}} }}
disabled={btnIsLoading || stockInLineStatusMap[status] < 1}
disabled={
// stockInLineStatusMap[status] === 9 ||
stockInLineStatusMap[status] < 1
}
// set _isNew to false after posting // set _isNew to false after posting
// or check status // or check status
onClick={handleQC(params.row.id, params)} onClick={handleQC(params.row.id, params)}
@@ -422,7 +457,7 @@ function PoInputGrid({
// marginRight: 1, // marginRight: 1,
}} }}
disabled={ disabled={
btnIsLoading ||
stockInLineStatusMap[status] === 9 ||
stockInLineStatusMap[status] <= 0 || stockInLineStatusMap[status] <= 0 ||
stockInLineStatusMap[status] >= 5 stockInLineStatusMap[status] >= 5
} }
@@ -440,7 +475,7 @@ function PoInputGrid({
// marginRight: 1, // marginRight: 1,
}} }}
disabled={ disabled={
btnIsLoading ||
stockInLineStatusMap[status] === 9 ||
stockInLineStatusMap[status] <= 2 || stockInLineStatusMap[status] <= 2 ||
stockInLineStatusMap[status] >= 7 stockInLineStatusMap[status] >= 7
} }
@@ -457,7 +492,7 @@ function PoInputGrid({
color: "primary.main", color: "primary.main",
// marginRight: 1, // marginRight: 1,
}} }}
disabled={btnIsLoading || stockInLineStatusMap[status] < 7}
disabled={stockInLineStatusMap[status] === 9 || 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)}
@@ -471,7 +506,7 @@ function PoInputGrid({
color: "primary.main", color: "primary.main",
// marginRight: 1, // marginRight: 1,
}} }}
disabled={btnIsLoading || stockInLineStatusMap[status] !== 8}
disabled={stockInLineStatusMap[status] === 9 || stockInLineStatusMap[status] !== 8}
// set _isNew to false after posting // set _isNew to false after posting
// or check status // or check status
onClick={handleQrCode(params.row.id, params)} onClick={handleQrCode(params.row.id, params)}
@@ -479,14 +514,26 @@ function PoInputGrid({
key="edit" key="edit"
/>, />,
<GridActionsCellItem <GridActionsCellItem
icon={<DeleteIcon />}
icon={
stockInLineStatusMap[status] >= 1 ? (
<DoDisturbIcon />
) : (
<DeleteIcon />
)
}
label="Delete" label="Delete"
sx={{ sx={{
color: "error.main", 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" color="inherit"
key="edit" key="edit"
/>, />,
@@ -494,7 +541,7 @@ function PoInputGrid({
}, },
}, },
], ],
[btnIsLoading]
[stockInLineStatusMap, btnIsLoading, handleQrCode, handleReject]
); );


const addRow = useCallback(() => { 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 && ( {modalInfo !== undefined && (
<> <>
<PoQcStockInModal <PoQcStockInModal


+ 50
- 15
src/components/PoDetail/PoQcStockInModal.tsx 查看文件

@@ -39,6 +39,7 @@ import { downloadFile } from "@/app/utils/commonUtil";
import { fetchPoQrcode } from "@/app/api/pdf/actions"; import { fetchPoQrcode } from "@/app/api/pdf/actions";
import UploadContext from "../UploadProvider/UploadProvider"; import UploadContext from "../UploadProvider/UploadProvider";
import useUploadContext from "../UploadProvider/useUploadContext"; import useUploadContext from "../UploadProvider/useUploadContext";
import RejectForm from "./RejectForm";


dayjs.extend(arraySupport); dayjs.extend(arraySupport);
interface CommonProps extends Omit<ModalProps, "children"> { interface CommonProps extends Omit<ModalProps, "children"> {
@@ -56,7 +57,7 @@ interface CommonProps extends Omit<ModalProps, "children"> {
>; >;
qc?: QcItemWithChecks[]; qc?: QcItemWithChecks[];
warehouse?: any[]; warehouse?: any[];
type: "qc" | "stockIn" | "escalation" | "putaway";
type: "qc" | "stockIn" | "escalation" | "putaway" | "reject";
} }
interface QcProps extends CommonProps { interface QcProps extends CommonProps {
qc: QcItemWithChecks[]; qc: QcItemWithChecks[];
@@ -74,8 +75,17 @@ interface EscalationProps extends CommonProps {
// naming // naming
type: "escalation"; type: "escalation";
} }
interface RejectProps extends CommonProps {
// naming
type: "reject";
}


type Props = QcProps | StockInProps | PutawayProps | EscalationProps;
type Props =
| QcProps
| StockInProps
| PutawayProps
| EscalationProps
| RejectProps;
const style = { const style = {
position: "absolute", position: "absolute",
top: "50%", top: "50%",
@@ -194,7 +204,7 @@ const PoQcStockInModal: React.FC<Props> = ({
const onSubmit = useCallback<SubmitHandler<ModalFormInput & {}>>( const onSubmit = useCallback<SubmitHandler<ModalFormInput & {}>>(
async (data, event) => { async (data, event) => {
setBtnIsLoading(true); setBtnIsLoading(true);
setIsUploading(true)
setIsUploading(true);
formProps.clearErrors(); formProps.clearErrors();
let hasErrors = false; let hasErrors = false;
console.log(errors); console.log(errors);
@@ -204,12 +214,12 @@ const PoQcStockInModal: React.FC<Props> = ({
try { try {
// add checking // add checking
if (type === "stockIn") { if (type === "stockIn") {
hasErrors = checkStockIn(data)
console.log(hasErrors)
hasErrors = checkStockIn(data);
console.log(hasErrors);
} }
if (type === "putaway") { if (type === "putaway") {
hasErrors = checkPutaway(data); hasErrors = checkPutaway(data);
console.log(hasErrors)
console.log(hasErrors);
} }
//////////////////////// modify this mess later ////////////////////// //////////////////////// modify this mess later //////////////////////
var productionDate = null; var productionDate = null;
@@ -246,7 +256,7 @@ const PoQcStockInModal: React.FC<Props> = ({
console.log(args); console.log(args);
setServerError(t("An error has occurred. Please try again later.")); setServerError(t("An error has occurred. Please try again later."));
setBtnIsLoading(false); setBtnIsLoading(false);
setIsUploading(false)
setIsUploading(false);
return; return;
} }
console.log(args); console.log(args);
@@ -294,7 +304,7 @@ const PoQcStockInModal: React.FC<Props> = ({
} }
// add loading // add loading
setBtnIsLoading(false); setBtnIsLoading(false);
setIsUploading(false)
setIsUploading(false);
setItemDetail(undefined); setItemDetail(undefined);
closeHandler({}, "backdropClick"); closeHandler({}, "backdropClick");
} }
@@ -303,7 +313,7 @@ const PoQcStockInModal: React.FC<Props> = ({
} catch (e) { } catch (e) {
// server error // server error
setBtnIsLoading(false); setBtnIsLoading(false);
setIsUploading(false)
setIsUploading(false);
setServerError(t("An error has occurred. Please try again later.")); setServerError(t("An error has occurred. Please try again later."));
console.log(e); console.log(e);
} }
@@ -313,7 +323,7 @@ const PoQcStockInModal: React.FC<Props> = ({


const printQrcode = useCallback(async () => { const printQrcode = useCallback(async () => {
setBtnIsLoading(true); setBtnIsLoading(true);
setIsUploading(true)
setIsUploading(true);
const postData = { stockInLineIds: [itemDetail.id] }; const postData = { stockInLineIds: [itemDetail.id] };
// const postData = { stockInLineIds: [42,43,44] }; // const postData = { stockInLineIds: [42,43,44] };
const response = await fetchPoQrcode(postData); const response = await fetchPoQrcode(postData);
@@ -322,7 +332,7 @@ const PoQcStockInModal: React.FC<Props> = ({
downloadFile(new Uint8Array(response.blobValue), response.filename!!); downloadFile(new Uint8Array(response.blobValue), response.filename!!);
} }
setBtnIsLoading(false); setBtnIsLoading(false);
setIsUploading(false)
setIsUploading(false);
}, [itemDetail, fetchPoQrcode, downloadFile]); }, [itemDetail, fetchPoQrcode, downloadFile]);


const renderSubmitButton = useMemo((): boolean => { const renderSubmitButton = useMemo((): boolean => {
@@ -348,6 +358,11 @@ const PoQcStockInModal: React.FC<Props> = ({
); );
case "putaway": case "putaway":
return stockInLineStatusMap[status] === 7; return stockInLineStatusMap[status] === 7;
case "reject":
return (
stockInLineStatusMap[status] >= 1 &&
stockInLineStatusMap[status] <= 6
);
default: default:
return false; // Handle unexpected type return false; // Handle unexpected type
} }
@@ -366,16 +381,36 @@ const PoQcStockInModal: React.FC<Props> = ({
onSubmit={formProps.handleSubmit(onSubmit)} onSubmit={formProps.handleSubmit(onSubmit)}
> >
{itemDetail !== undefined && type === "qc" && ( {itemDetail !== undefined && type === "qc" && (
<QcForm qc={qc!!} itemDetail={itemDetail} disabled={renderSubmitButton}/>
<QcForm
qc={qc!!}
itemDetail={itemDetail}
disabled={!renderSubmitButton}
/>
)} )}
{itemDetail !== undefined && type === "stockIn" && ( {itemDetail !== undefined && type === "stockIn" && (
<StockInForm itemDetail={itemDetail} disabled={renderSubmitButton}/>
<StockInForm
itemDetail={itemDetail}
disabled={!renderSubmitButton}
/>
)} )}
{itemDetail !== undefined && type === "escalation" && ( {itemDetail !== undefined && type === "escalation" && (
<EscalationForm itemDetail={itemDetail} disabled={renderSubmitButton}/>
<EscalationForm
itemDetail={itemDetail}
disabled={!renderSubmitButton}
/>
)} )}
{itemDetail !== undefined && type === "putaway" && ( {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}> <Stack direction="row" justifyContent="flex-end" gap={1}>
{renderSubmitButton ? ( {renderSubmitButton ? (


+ 3
- 3
src/components/PoDetail/QcForm.tsx 查看文件

@@ -249,7 +249,7 @@ const QcForm: React.FC<Props> = ({ qc, itemDetail, disabled }) => {
<TextField <TextField
label={t("sampleRate")} label={t("sampleRate")}
fullWidth fullWidth
defaultValue={1}
// defaultValue={1}
{...register("sampleRate", { {...register("sampleRate", {
required: "sampleRate required!", required: "sampleRate required!",
valueAsNumber: true, valueAsNumber: true,
@@ -263,7 +263,7 @@ const QcForm: React.FC<Props> = ({ qc, itemDetail, disabled }) => {
<TextField <TextField
label={t("sampleWeight")} label={t("sampleWeight")}
fullWidth fullWidth
defaultValue={1}
// defaultValue={1}
{...register("sampleWeight", { {...register("sampleWeight", {
required: "sampleWeight required!", required: "sampleWeight required!",
valueAsNumber: true, valueAsNumber: true,
@@ -277,7 +277,7 @@ const QcForm: React.FC<Props> = ({ qc, itemDetail, disabled }) => {
<TextField <TextField
label={t("totalWeight")} label={t("totalWeight")}
fullWidth fullWidth
defaultValue={1}
// defaultValue={1}
{...register("totalWeight", { {...register("totalWeight", {
required: "totalWeight required!", required: "totalWeight required!",
valueAsNumber: true, valueAsNumber: true,


+ 125
- 0
src/components/PoDetail/RejectForm.tsx 查看文件

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

Loading…
取消
儲存