|
|
@@ -20,7 +20,7 @@ import { |
|
|
|
Tooltip, |
|
|
|
Typography, |
|
|
|
} from "@mui/material"; |
|
|
|
import { useFormContext, Controller, FieldPath, useFieldArray } from "react-hook-form"; |
|
|
|
import { useFormContext, Controller, FieldPath } from "react-hook-form"; |
|
|
|
import { useTranslation } from "react-i18next"; |
|
|
|
import StyledDataGrid from "../StyledDataGrid"; |
|
|
|
import { Dispatch, SetStateAction, useCallback, useEffect, useMemo, useState } from "react"; |
|
|
@@ -51,11 +51,12 @@ import QcDataGrid from "./QCDatagrid"; |
|
|
|
import StockInFormVer2 from "./StockInFormVer2"; |
|
|
|
import { dummyEscalationHistory, dummyQCData } from "./dummyQcTemplate"; |
|
|
|
import { ModalFormInput } from "@/app/api/po/actions"; |
|
|
|
import { escape } from "lodash"; |
|
|
|
import { escape, min } from "lodash"; |
|
|
|
import { PanoramaSharp } from "@mui/icons-material"; |
|
|
|
import EscalationLogTable from "../DashboardPage/escalation/EscalationLogTable"; |
|
|
|
import { EscalationResult } from "@/app/api/escalation"; |
|
|
|
import { EscalationCombo } from "@/app/api/user"; |
|
|
|
import CollapsibleCard from "../CollapsibleCard/CollapsibleCard"; |
|
|
|
|
|
|
|
interface Props { |
|
|
|
itemDetail: StockInLine & { qcResult?: PurchaseQcResult[] } & { escResult?: EscalationResult[] }; |
|
|
@@ -135,16 +136,20 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala |
|
|
|
const accQty = watch("acceptQty"); |
|
|
|
const validateForm = useCallback(() => { |
|
|
|
if (qcDecision == 1) { |
|
|
|
if (accQty > itemDetail.acceptedQty){ |
|
|
|
if (isNaN(accQty) || accQty === undefined || accQty === null || typeof(accQty) != "number") { |
|
|
|
setError("acceptQty", { message: t("value must be a number") }); |
|
|
|
} else |
|
|
|
if (!Number.isInteger(accQty)) { |
|
|
|
setError("acceptQty", { message: t("value must be integer") }); |
|
|
|
} |
|
|
|
if (accQty > itemDetail.acceptedQty) { |
|
|
|
setError("acceptQty", { message: `${t("acceptQty must not greater than")} ${ |
|
|
|
itemDetail.acceptedQty}` }); |
|
|
|
} |
|
|
|
if (accQty < 1){ |
|
|
|
} else |
|
|
|
if (accQty < 1) { |
|
|
|
setError("acceptQty", { message: t("minimal value is 1") }); |
|
|
|
} |
|
|
|
if (isNaN(accQty)){ |
|
|
|
setError("acceptQty", { message: t("value must be a number") }); |
|
|
|
} |
|
|
|
} else |
|
|
|
console.log("%c Validated accQty:", "color:yellow", accQty); |
|
|
|
} |
|
|
|
},[setError, qcDecision, accQty, itemDetail]) |
|
|
|
|
|
|
@@ -343,7 +348,6 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala |
|
|
|
onClick={(e) => e.stopPropagation()} |
|
|
|
onMouseDown={(e) => e.stopPropagation()} |
|
|
|
onKeyDown={(e) => e.stopPropagation()} |
|
|
|
inputProps={{ min: 0 }} |
|
|
|
sx={{ width: '100%' }} |
|
|
|
/> |
|
|
|
); |
|
|
@@ -490,7 +494,7 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala |
|
|
|
</Grid> */} |
|
|
|
<Grid item xs={12}> |
|
|
|
<EscalationLogTable type="qc" items={itemDetail.escResult || []}/> |
|
|
|
{/* <Collapse in={true}> */} |
|
|
|
<CollapsibleCard title={t("QC Record")}> |
|
|
|
<StyledDataGrid |
|
|
|
columns={qcColumns} |
|
|
|
rows={qcResult} |
|
|
@@ -499,7 +503,7 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala |
|
|
|
autoHeight |
|
|
|
sortModel={[]} |
|
|
|
/> |
|
|
|
{/* </Collapse> */} |
|
|
|
</CollapsibleCard> |
|
|
|
{/* <StyledDataGrid |
|
|
|
rows={escalationHistory} |
|
|
|
columns={columns} |
|
|
@@ -531,37 +535,84 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala |
|
|
|
// value={field.value?.toString() || "true"} |
|
|
|
onChange={(e) => { |
|
|
|
const value = e.target.value.toString();// === 'true'; |
|
|
|
if (value != "1" && Boolean(errors.acceptQty)) { |
|
|
|
// if (!value && Boolean(errors.acceptQty)) { |
|
|
|
setValue("acceptQty", itemDetail.acceptedQty ?? 0); |
|
|
|
|
|
|
|
const input = document.getElementById('accQty') as HTMLInputElement; |
|
|
|
console.log("%c Error", "color:pink", errors.acceptQty); |
|
|
|
if (input) { // Selected Reject in new flow with Error |
|
|
|
if (value == "1") { // Selected Accept |
|
|
|
input.value = Number(accQty).toString(); |
|
|
|
} else { |
|
|
|
if (Boolean(errors.acceptQty)) { |
|
|
|
setValue("acceptQty", 0); |
|
|
|
} |
|
|
|
input.value = '0'; |
|
|
|
} |
|
|
|
} |
|
|
|
// setValue("acceptQty", itemDetail.acceptedQty ?? 0); |
|
|
|
// clearErrors("acceptQty"); |
|
|
|
// } |
|
|
|
field.onChange(value); |
|
|
|
}} |
|
|
|
> |
|
|
|
<FormControlLabel disabled={disabled} |
|
|
|
value="1" control={<Radio />} label="接受來貨" /> |
|
|
|
|
|
|
|
{(itemDetail.status == "escalated" || (disabled && accQty != itemDetail.acceptedQty && qcDecision == 1)) && ( //TODO Improve |
|
|
|
{(itemDetail.status == "escalated"|| (disabled && accQty != itemDetail.acceptedQty && qcDecision == 1)) && ( //TODO Improve |
|
|
|
<Box sx={{mr:2}}> |
|
|
|
<TextField |
|
|
|
type="number" |
|
|
|
// type="number" |
|
|
|
id="accQty" |
|
|
|
label={t("acceptQty")} |
|
|
|
sx={{ width: '150px' }} |
|
|
|
value={(qcDecision == 1)? Number(accQty) : 0 } |
|
|
|
// value={Number(accQty)} |
|
|
|
defaultValue={Number(accQty)} |
|
|
|
// defaultValue={(qcDecision == 1)? Number(accQty) : 0} |
|
|
|
// value={(qcDecision == 1)? Number(accQty) : undefined } |
|
|
|
// value={qcAccept? accQty : 0 } |
|
|
|
disabled={qcDecision != 1 || disabled} |
|
|
|
// disabled={!qcAccept || disabled} |
|
|
|
{...register("acceptQty", { |
|
|
|
required: "acceptQty required!", |
|
|
|
})} |
|
|
|
onBlur={(e) => { |
|
|
|
const value = e.target.value; |
|
|
|
const input = document.getElementById('accQty') as HTMLInputElement; |
|
|
|
input.value = Number(value).toString() |
|
|
|
setValue(`acceptQty`, Number(value)); |
|
|
|
}} |
|
|
|
onInput={(e: React.ChangeEvent<HTMLInputElement>) => { |
|
|
|
const input = e.target.value; |
|
|
|
|
|
|
|
const numReg = /^[0-9]+$/ |
|
|
|
let r = ''; |
|
|
|
if (!numReg.test(input)) { |
|
|
|
const result = input.replace(/\D/g, ""); |
|
|
|
r = (result === '' ? result : Number(result)).toString(); |
|
|
|
} else { |
|
|
|
r = Number(input).toString() |
|
|
|
} |
|
|
|
e.target.value = r; |
|
|
|
}} |
|
|
|
inputProps={{ min: 1, max:itemDetail.acceptedQty }} |
|
|
|
// onChange={(e) => { |
|
|
|
// const inputValue = e.target.value; |
|
|
|
// if (inputValue === '' || /^[0-9]*$/.test(inputValue)) { |
|
|
|
// setValue("acceptQty", Number(inputValue === '' ? null : parseInt(inputValue, 10))); |
|
|
|
// } |
|
|
|
// }} |
|
|
|
// {...register("acceptQty", { |
|
|
|
// required: "acceptQty required!", |
|
|
|
// })} |
|
|
|
error={Boolean(errors.acceptQty)} |
|
|
|
helperText={errors.acceptQty?.message} |
|
|
|
/> |
|
|
|
/> |
|
|
|
<TextField |
|
|
|
type="number" |
|
|
|
label={t("rejectQty")} |
|
|
|
sx={{ width: '150px' }} |
|
|
|
value={itemDetail.acceptedQty - accQty} |
|
|
|
value={ |
|
|
|
(!Boolean(errors.acceptQty)) ? |
|
|
|
(qcDecision == 1 ? itemDetail.acceptedQty - accQty : itemDetail.acceptedQty) |
|
|
|
: "" |
|
|
|
} |
|
|
|
error={Boolean(errors.acceptQty)} |
|
|
|
disabled={true} |
|
|
|
/> |
|
|
|
</Box>)} |
|
|
|