@@ -7,6 +7,7 @@ import { cache } from "react"; | |||
export interface EscalationResult { | |||
id: number; | |||
submitter?: string; | |||
handler?: string; | |||
handlerDepartment?: string; | |||
handlerName?: string; | |||
@@ -38,7 +38,8 @@ export interface StockInLineEntry { | |||
} | |||
export interface PurchaseQcResult{ | |||
id: number; | |||
id?: number; | |||
qcItemId: number; | |||
qcPassed?: boolean; | |||
failQty?: number; | |||
remarks?: string; | |||
@@ -16,7 +16,8 @@ export interface QcItemWithChecks { | |||
} | |||
export interface QcData { | |||
id: number, | |||
id?: number, | |||
qcItemId: number, | |||
code: string, | |||
name: string, | |||
qcDescription: string, | |||
@@ -104,7 +104,7 @@ export const adminChangePassword = async (data: any) => { | |||
}; | |||
export const fetchEscalationCombo = async () => { | |||
return serverFetchJson<EscalationCombo>(`${BASE_API_URL}/user/escalation-combo`, { | |||
return serverFetchJson<EscalationCombo[]>(`${BASE_API_URL}/user/escalation-combo`, { | |||
next: { tags: ["escalationCombo"]} | |||
}) | |||
}; |
@@ -89,6 +89,13 @@ const EscalationLogTable: React.FC<Props> = ({ | |||
const columns_dashboard = useMemo<Column<EscalationResult>[]>( | |||
() => [ | |||
{ | |||
name: "submitter", | |||
label: t("escalateFrom"), | |||
align: "left", | |||
headerAlign: "left", | |||
sx: { width: "15%", minWidth: 100 }, | |||
}, | |||
{ | |||
name: "poCode", | |||
label: t("Po Code"), | |||
@@ -138,6 +145,13 @@ const EscalationLogTable: React.FC<Props> = ({ | |||
const columns_qc = useMemo<Column<EscalationResult>[]>( | |||
() => [ | |||
{ | |||
name: "submitter", | |||
label: t("escalateFrom"), | |||
align: "left", | |||
headerAlign: "left", | |||
sx: { width: "15%", minWidth: 100 }, | |||
}, | |||
{ | |||
name: "handler", | |||
label: t("Responsible for handling colleagues"), | |||
@@ -153,12 +167,12 @@ const EscalationLogTable: React.FC<Props> = ({ | |||
}, | |||
{ | |||
name: "recordDate", | |||
label: t("escalated date"), | |||
label: t("escalated datetime"), | |||
align: "right", | |||
headerAlign: "right", | |||
sx: { width: "10%", minWidth: 100 }, | |||
renderCell: (params) => { | |||
return arrayToDateString(params.recordDate); | |||
return arrayToDateTimeString(params.recordDate); | |||
} | |||
}, | |||
{ | |||
@@ -24,6 +24,7 @@ import { useTranslation } from 'react-i18next'; | |||
import { Controller, useFormContext } from 'react-hook-form'; | |||
import { EscalationInput, ModalFormInput } from '@/app/api/po/actions'; | |||
import { EscalationCombo } from "@/app/api/user"; | |||
import { fetchEscalationCombo } from "@/app/api/user/actions"; | |||
import { FireExtinguisher } from '@mui/icons-material'; | |||
interface NameOption { | |||
@@ -41,14 +42,14 @@ interface Props { | |||
forSupervisor: boolean | |||
isCollapsed: boolean | |||
setIsCollapsed: Dispatch<React.SetStateAction<boolean>> | |||
escalationCombo: EscalationCombo[] | |||
// escalationCombo: EscalationCombo[] | |||
} | |||
const EscalationComponent: React.FC<Props> = ({ | |||
forSupervisor, | |||
isCollapsed, | |||
setIsCollapsed, | |||
escalationCombo | |||
// escalationCombo | |||
}) => { | |||
const { t } = useTranslation("purchaseOrder"); | |||
@@ -58,6 +59,18 @@ const EscalationComponent: React.FC<Props> = ({ | |||
message: '', | |||
}); | |||
const [escalationCombo, setEscalationCombo] = useState<EscalationCombo[]>([]); | |||
useEffect(() => { | |||
async function fetchData() { | |||
if (escalationCombo.length < 1) { | |||
const escCombo = await fetchEscalationCombo(); | |||
setEscalationCombo(escCombo); | |||
} | |||
} | |||
fetchData(); | |||
}, []) | |||
const nameOptions: NameOption[] = [ | |||
{ value: '', label: '請選擇姓名...' }, | |||
{ value: 'john', label: '張大明' }, | |||
@@ -89,7 +89,6 @@ type Props = { | |||
qc: QcItemWithChecks[]; | |||
warehouse: WarehouseResult[]; | |||
printerCombo: PrinterCombo[]; | |||
escalationCombo: EscalationCombo[]; | |||
}; | |||
type EntryError = | |||
@@ -192,7 +191,7 @@ interface PolInputResult { | |||
dnQty: number, | |||
} | |||
const PoDetail: React.FC<Props> = ({ po, qc, warehouse, printerCombo, escalationCombo }) => { | |||
const PoDetail: React.FC<Props> = ({ po, qc, warehouse, printerCombo }) => { | |||
const cameras = useContext(CameraContext); | |||
// console.log(cameras); | |||
const { t } = useTranslation("purchaseOrder"); | |||
@@ -865,7 +864,6 @@ const PoDetail: React.FC<Props> = ({ po, qc, warehouse, printerCombo, escalation | |||
fetchPoDetail={fetchPoDetail} | |||
handleMailTemplateForStockInLine={handleMailTemplateForStockInLine} | |||
printerCombo={printerCombo} | |||
escalationCombo={escalationCombo} | |||
/> | |||
</Box> | |||
</TableCell> | |||
@@ -27,17 +27,15 @@ const PoDetailWrapper: React.FC<Props> & SubComponents = async ({ id }) => { | |||
warehouse, | |||
qc, | |||
printerCombo, | |||
escalationCombo, | |||
] = await Promise.all([ | |||
fetchPoWithStockInLines(id), | |||
fetchWarehouseList(), | |||
fetchQcItemCheck(), | |||
fetchPrinterCombo(), | |||
fetchEscalationCombo() | |||
]); | |||
// const poWithStockInLine = await fetchPoWithStockInLines(id) | |||
console.log("%c pol:", "color:green", poWithStockInLine); | |||
return <PoDetail po={poWithStockInLine} qc={qc} warehouse={warehouse} printerCombo={printerCombo} escalationCombo={escalationCombo}/>; | |||
return <PoDetail po={poWithStockInLine} qc={qc} warehouse={warehouse} printerCombo={printerCombo} />; | |||
}; | |||
PoDetailWrapper.Loading = PoDetailLoading; | |||
@@ -83,7 +83,6 @@ interface Props { | |||
fetchPoDetail: (poId: string) => void; | |||
handleMailTemplateForStockInLine: (stockInLineId: number) => void; | |||
printerCombo: PrinterCombo[]; | |||
escalationCombo: EscalationCombo[]; | |||
} | |||
export type StockInLineEntryError = { | |||
@@ -125,7 +124,6 @@ function PoInputGrid({ | |||
fetchPoDetail, | |||
handleMailTemplateForStockInLine, | |||
printerCombo, | |||
escalationCombo | |||
}: Props) { | |||
const { t } = useTranslation("purchaseOrder"); | |||
@@ -307,7 +305,6 @@ const closeNewModal = useCallback(() => { | |||
const handleNewQC = useCallback( | |||
(id: GridRowId, params: any) => async() => { | |||
// console.log(id) | |||
console.log("params", params.row) | |||
// setBtnIsLoading(true); | |||
setRowModesModel((prev) => ({ | |||
...prev, | |||
@@ -955,7 +952,6 @@ const closeNewModal = useCallback(() => { | |||
itemDetail={modalInfo} | |||
handleMailTemplateForStockInLine={handleMailTemplateForStockInLine} | |||
printerCombo={printerCombo} | |||
escalationCombo={escalationCombo} | |||
/> | |||
</> | |||
) | |||
@@ -60,9 +60,8 @@ import CollapsibleCard from "../CollapsibleCard/CollapsibleCard"; | |||
interface Props { | |||
itemDetail: StockInLine & { qcResult?: PurchaseQcResult[] } & { escResult?: EscalationResult[] }; | |||
qc: QcItemWithChecks[]; | |||
// qc: QcItemWithChecks[]; | |||
disabled: boolean; | |||
escalationCombo: EscalationCombo[]; | |||
// qcItems: QcData[] | |||
// setQcItems: Dispatch<SetStateAction<QcData[]>> | |||
} | |||
@@ -75,7 +74,7 @@ type EntryError = | |||
type QcRow = TableRow<Partial<QcData>, EntryError>; | |||
// fetchQcItemCheck | |||
const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escalationCombo }) => { | |||
const QcComponent: React.FC<Props> = ({ itemDetail, disabled = false }) => { | |||
const { t } = useTranslation("purchaseOrder"); | |||
const apiRef = useGridApiRef(); | |||
const { | |||
@@ -94,12 +93,16 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala | |||
const [tabIndex, setTabIndex] = useState(0); | |||
const [rowSelectionModel, setRowSelectionModel] = useState<GridRowSelectionModel>(); | |||
const [escalationHistory, setEscalationHistory] = useState(dummyEscalationHistory); | |||
// const [qcResult, setQcResult] = useState(); | |||
const qcAccept = watch("qcAccept"); | |||
const qcDecision = watch("qcDecision"); //WIP | |||
// const qcResult = useMemo(() => [...watch("qcResult")], [watch("qcResult")]); | |||
const qcResult = [...watch("qcResult")]; | |||
const qcRecord = useMemo(() => { // Need testing | |||
const value = watch('qcResult'); console.log("%c QC update!", "color:green", value); | |||
return Array.isArray(value) ? [...value] : []; | |||
}, [watch('qcResult')]); | |||
const [qcHistory, setQcHistory] = useState<PurchaseQcResult[]>([]); | |||
const [qcResult, setQcResult] = useState<PurchaseQcResult[]>([]); | |||
// const [qcAccept, setQcAccept] = useState(true); | |||
// const [qcItems, setQcItems] = useState(dummyQCData) | |||
@@ -118,12 +121,16 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala | |||
}, | |||
], [] | |||
) | |||
const handleTabChange = useCallback<NonNullable<TabsProps["onChange"]>>( | |||
(_e, newValue) => { | |||
setTabIndex(newValue); | |||
}, | |||
[], | |||
); | |||
const handleTabChange = useCallback<NonNullable<TabsProps["onChange"]>>( | |||
(_e, newValue) => { | |||
setTabIndex(newValue); | |||
}, | |||
[], | |||
); | |||
const isExist = (data : string | number | undefined) => { | |||
return (data !== null && data !== undefined); | |||
} | |||
// W I P // | |||
const validateFieldFail = (field : FieldPath<PurchaseQCInput>, condition: boolean, message: string) : boolean => { | |||
@@ -225,6 +232,10 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala | |||
return <Checkbox checked={!!value} onChange={handleChange} sx={{ p: 0 }} />; | |||
} | |||
const qcDisabled = (row : PurchaseQcResult) => { | |||
return disabled || isExist(row.escalationLogId); | |||
}; | |||
const qcColumns: GridColDef[] = useMemo(() => [ | |||
{ | |||
field: "code", | |||
@@ -245,7 +256,7 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala | |||
flex: 1.5, | |||
renderCell: (params) => { | |||
const rowValue = params.row; | |||
const index = params.api.getRowIndexRelativeToVisibleRows(params.id); | |||
const index = Number(params.id);//params.api.getRowIndexRelativeToVisibleRows(params.id); | |||
// console.log(rowValue.row); | |||
return ( | |||
<FormControl> | |||
@@ -267,7 +278,7 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala | |||
value="true" | |||
control={<Radio />} | |||
label="合格" | |||
disabled={disabled || itemDetail.status == "escalated"} | |||
disabled={qcDisabled(rowValue)} | |||
sx={{ | |||
color: rowValue.qcPassed === true ? "green" : "inherit", | |||
"& .Mui-checked": {color: "green"} | |||
@@ -277,7 +288,7 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala | |||
value="false" | |||
control={<Radio />} | |||
label="不合格" | |||
disabled={disabled || itemDetail.status == "escalated"} | |||
disabled={qcDisabled(rowValue)} | |||
sx={{ | |||
color: rowValue.qcPassed === false ? "red" : "inherit", | |||
"& .Mui-checked": {color: "red"} | |||
@@ -294,22 +305,27 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala | |||
flex: 1, | |||
// editable: true, | |||
renderCell: (params) => { | |||
const index = params.api.getRowIndexRelativeToVisibleRows(params.id); | |||
const index = Number(params.id);//params.api.getRowIndexRelativeToVisibleRows(params.id); | |||
return ( | |||
<TextField | |||
type="number" | |||
size="small" | |||
value={!params.row.qcPassed? params.value : '0'} | |||
disabled={params.row.qcPassed || disabled || itemDetail.status == "escalated"} | |||
onBlur={(e) => { | |||
disabled={params.row.qcPassed || qcDisabled(params.row)} | |||
/* TODO improve */ | |||
/* Reference: https://grok.com/share/c2hhcmQtNA%3D%3D_10787069-3eec-40af-a7cc-bacbdb86bf05 */ | |||
onChange={(e) => { | |||
const v = e.target.value; | |||
const next = v === '' ? undefined : Number(v); | |||
if (Number.isNaN(next)) return; | |||
// setQcItems((prev) => | |||
// prev.map((r) => (r.id === params.id ? { ...r, failQty: next } : r)) | |||
// ); | |||
setValue(`qcResult.${index}.failQty`, next); | |||
}} | |||
// onBlur={(e) => { | |||
// const v = e.target.value; | |||
// const next = v === '' ? undefined : Number(v); | |||
// if (Number.isNaN(next)) return; | |||
// setValue(`qcResult.${index}.failQty`, next); | |||
// }} | |||
onClick={(e) => e.stopPropagation()} | |||
onMouseDown={(e) => e.stopPropagation()} | |||
onKeyDown={(e) => e.stopPropagation()} | |||
@@ -324,12 +340,12 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala | |||
headerName: t("remarks"), | |||
flex: 2, | |||
renderCell: (params) => { | |||
const index = params.api.getRowIndexRelativeToVisibleRows(params.id); | |||
const index = Number(params.id);//params.api.getRowIndexRelativeToVisibleRows(params.id); | |||
return ( | |||
<TextField | |||
size="small" | |||
defaultValue={params.value} | |||
disabled={disabled || itemDetail.status == "escalated"} | |||
disabled={qcDisabled(params.row)} | |||
onBlur={(e) => { | |||
const value = e.target.value; | |||
setValue(`qcResult.${index}.remarks`, value); | |||
@@ -365,15 +381,31 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala | |||
}, [itemDetail?.demandQty, itemDetail?.acceptedQty, setValue]); | |||
useEffect(() => { | |||
// console.log("Qc Result updated:", qcResult); | |||
if (qcResult.length < 1) { // New QC | |||
const mutableQcData = dummyQCData; | |||
// const mutableQcData = JSON.parse(JSON.stringify(dummyQCData)); | |||
// replace([mutableQcData]); | |||
setValue("qcResult", mutableQcData); | |||
// setValue("qcResult.0.qcPassed", false); | |||
console.log("%c Qc Record updated:", "color:red", qcRecord); | |||
if (qcRecord.length < 1) { // New QC | |||
const fetchedQcData = dummyQCData; //TODO fetch from DB | |||
setValue("qcResult", fetchedQcData); | |||
} else { | |||
if (itemDetail.status == "escalated") { // Copy the previous QC data for editing | |||
if (qcRecord.find((qc) => !isExist(qc.escalationLogId)) === undefined) { | |||
const copiedQcData = qcRecord.map(qc => ({ ...qc, escalationLogId: undefined })); | |||
const mutableQcData = [...qcRecord, ...copiedQcData]; | |||
setValue("qcResult", mutableQcData); | |||
} | |||
} | |||
if (qcRecord.length > 0) { | |||
if (qcResult.length < 1) { // Set QC Result | |||
const filteredQcResult = qcRecord.filter((qc) => !isExist(qc.escalationLogId)); | |||
setQcResult(filteredQcResult); | |||
} | |||
if (qcHistory.length < 1) { // Set QC History | |||
const filteredQcHistory = qcRecord.filter((qc) => isExist(qc.escalationLogId)); | |||
setQcHistory(filteredQcHistory); | |||
} | |||
} | |||
} | |||
}, [qcResult, setValue]) | |||
}, [qcRecord, setValue]) | |||
// const [openCollapse, setOpenCollapse] = useState(false) | |||
const [isCollapsed, setIsCollapsed] = useState<boolean>(true); | |||
@@ -415,16 +447,16 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala | |||
} | |||
} | |||
useEffect(() => { | |||
if (qcHistory.length < 1) { | |||
setQcHistory(qcResult.filter((qc) => {qc.escalationLogId != null})); | |||
console.log("QC History updated:", qcHistory); | |||
} | |||
}, [watch("qcResult")]); | |||
// }, [watch("qcResult")]); | |||
// useEffect(() => { | |||
// // onFailedOpenCollapse(qcItems) | |||
// }, [qcItems]); | |||
const getRowId = (row :any) => { | |||
return qcRecord.findIndex(qc => qc == row); | |||
// return row.id || `${row.name}-${Math.random().toString(36).substr(2, 9)}`; | |||
}; | |||
return ( | |||
<> | |||
<Grid container justifyContent="flex-start" alignItems="flex-start"> | |||
@@ -475,6 +507,7 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala | |||
// rows={disabled? qcResult:qcItems} | |||
autoHeight | |||
sortModel={[]} | |||
getRowId={getRowId} | |||
/> | |||
</Grid> | |||
</> | |||
@@ -497,7 +530,7 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala | |||
<CollapsibleCard title={t("QC Record")}> | |||
<StyledDataGrid | |||
columns={qcColumns} | |||
rows={qcResult} | |||
rows={qcHistory} | |||
// rows={qcResult && qcResult.length > 0 ? qcResult : qcItems} | |||
// rows={disabled? qcResult:qcItems} | |||
autoHeight | |||
@@ -536,8 +569,8 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala | |||
onChange={(e) => { | |||
const value = e.target.value.toString();// === 'true'; | |||
const input = document.getElementById('accQty') as HTMLInputElement; | |||
console.log("%c Error", "color:pink", errors.acceptQty); | |||
const input = document.getElementById('accQty') as HTMLInputElement; //TODO improve | |||
console.log("%c AccQty Error", "color:pink", errors.acceptQty); | |||
if (input) { // Selected Reject in new flow with Error | |||
if (value == "1") { // Selected Accept | |||
input.value = Number(accQty).toString(); | |||
@@ -641,7 +674,6 @@ const QcComponent: React.FC<Props> = ({ qc, itemDetail, disabled = false, escala | |||
forSupervisor={false} | |||
isCollapsed={isCollapsed} | |||
setIsCollapsed={setIsCollapsed} | |||
escalationCombo={escalationCombo} | |||
/> | |||
</Grid>)} | |||
{/* {qcAccept && <Grid item xs={12}> | |||
@@ -67,7 +67,6 @@ interface CommonProps extends Omit<ModalProps, "children"> { | |||
// type: "qc" | "stockIn" | "escalation" | "putaway" | "reject"; | |||
handleMailTemplateForStockInLine: (stockInLineId: number) => void; | |||
printerCombo: PrinterCombo[]; | |||
escalationCombo: EscalationCombo[]; | |||
onClose: () => void; | |||
} | |||
interface Props extends CommonProps { | |||
@@ -87,7 +86,6 @@ const PoQcStockInModalVer2: React.FC<Props> = ({ | |||
warehouse, | |||
handleMailTemplateForStockInLine, | |||
printerCombo, | |||
escalationCombo | |||
}) => { | |||
const { | |||
t, | |||
@@ -110,9 +108,10 @@ const defaultNewValue = useMemo(() => { | |||
escResult: (itemDetail.escResult && itemDetail.escResult?.length > 0) ? itemDetail.escResult : [], | |||
productionDate: itemDetail.productionDate ? arrayToDateString(itemDetail.productionDate, "input") : undefined, | |||
expiryDate: itemDetail.expiryDate ? arrayToDateString(itemDetail.expiryDate, "input") : undefined, | |||
receiptDate: itemDetail.receiptDate ?? dayjs().add(0, "month").format(INPUT_DATE_FORMAT), | |||
receiptDate: itemDetail.receiptDate ? arrayToDateString(itemDetail.receiptDate, "input") | |||
: dayjs().add(0, "month").format(INPUT_DATE_FORMAT), | |||
acceptQty: itemDetail.demandQty?? itemDetail.acceptedQty, | |||
warehouseId: itemDetail.defaultWarehouseId ?? 1 | |||
warehouseId: itemDetail.defaultWarehouseId ?? 1, | |||
} | |||
) | |||
},[itemDetail]) | |||
@@ -153,10 +152,6 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||
}, [itemDetail]); | |||
useEffect(() => { | |||
const qcRes = itemDetail?.qcResult; | |||
// if (!qcRes || qcRes?.length <= 0) { | |||
// itemDetail.qcResult = dummyQCData; | |||
// } | |||
formProps.reset({ | |||
...defaultNewValue | |||
}) | |||
@@ -220,7 +215,7 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||
const qcAccept = data.qcDecision == 1; | |||
// const qcAccept = data.qcAccept; | |||
let acceptQty = Number(data.acceptQty); | |||
const qcResults = data.qcResult || dummyQCData; // qcItems; | |||
const qcResults = data.qcResult?.filter((qc) => qc.escalationLogId === undefined) || []; // Remove old QC data | |||
// const qcResults = data.qcResult as PurchaseQcResult[]; // qcItems; | |||
// const qcResults = viewOnly? data.qcResult as PurchaseQcResult[] : qcItems; | |||
@@ -290,16 +285,17 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||
qcAccept: qcAccept? qcAccept : false, | |||
acceptQty: acceptQty? acceptQty : 0, | |||
qcResult: itemDetail.status != "escalated" ? qcResults.map(item => ({ | |||
id: item.id, | |||
qcItemId: item.id, | |||
// qcResult: itemDetail.status != "escalated" ? qcResults.map(item => ({ | |||
qcResult: qcResults.map(item => ({ | |||
// id: item.id, | |||
qcItemId: item.qcItemId, | |||
// code: item.code, | |||
// qcDescription: item.qcDescription, | |||
qcPassed: item.qcPassed? item.qcPassed : false, | |||
failQty: (item.failQty && !item.qcPassed) ? item.failQty : 0, | |||
// failedQty: (typeof item.failedQty === "number" && !item.isPassed) ? item.failedQty : 0, | |||
remarks: item.remarks || '' | |||
})) : [], | |||
remarks: item.remarks || '', | |||
})), | |||
}; | |||
// const qcData = data; | |||
@@ -389,7 +385,7 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||
status: data.status, //TODO Fix it! | |||
// ...data, | |||
dnDate : data.dnDate? arrayToDateString(data.dnDate) : dayjsToInputDateString(dayjs()), | |||
dnDate : data.dnDate? arrayToDateString(data.dnDate, "input") : dayjsToInputDateString(dayjs()), | |||
productionDate : arrayToDateString(data.productionDate, "input"), | |||
expiryDate : arrayToDateString(data.expiryDate, "input"), | |||
receiptDate : arrayToDateString(data.receiptDate, "input"), | |||
@@ -406,8 +402,6 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||
alert("請新增上架資料!"); | |||
return; | |||
} | |||
console.log(typeof data.putAwayLines!![0].qty + " = 'number'"); | |||
console.log(typeof data.putAwayLines!![0].qty !== "number"); | |||
if (data.putAwayLines!!.filter((line) => /[^0-9]/.test(String(line.qty))).length > 0) { //TODO Improve | |||
alert("上架數量不正確!"); | |||
return; | |||
@@ -471,11 +465,11 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||
return isPassed | |||
}, [acceptQty, formProps]) | |||
useEffect(() => { | |||
// maybe check if submitted before | |||
console.log("Modal QC Items updated:", qcItems); | |||
// checkQcIsPassed(qcItems) | |||
}, [qcItems, checkQcIsPassed]) | |||
// useEffect(() => { | |||
// // maybe check if submitted before | |||
// console.log("Modal QC Items updated:", qcItems); | |||
// // checkQcIsPassed(qcItems) | |||
// }, [qcItems, checkQcIsPassed]) | |||
return ( | |||
<> | |||
@@ -576,10 +570,9 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||
alignItems="flex-start" | |||
> | |||
<QcComponent | |||
qc={qc!} | |||
// qc={qc!} | |||
itemDetail={itemDetail} | |||
disabled={viewOnly} | |||
escalationCombo={escalationCombo} | |||
// qcItems={qcItems} | |||
// setQcItems={setQcItems} | |||
/> | |||
@@ -12,7 +12,8 @@ import { QcData } from "@/app/api/qc" | |||
export const dummyQCData: QcData[] = [ | |||
{ | |||
id: 4, | |||
id: 1, | |||
qcItemId: 4, | |||
code: "包裝", | |||
qcDescription: "有破爛、污糟、脹袋、積水、與實物不符等任何一種情況,則不合格", | |||
name: "有破爛、污糟、脹袋、積水、與實物不符等任何一種情況,則不合格", | |||
@@ -21,7 +22,8 @@ export const dummyQCData: QcData[] = [ | |||
remarks: undefined, | |||
}, | |||
{ | |||
id: 5, | |||
id: 2, | |||
qcItemId: 5, | |||
code: "肉質", | |||
qcDescription: "肉質鬆散,則不合格", | |||
name: "肉質鬆散,則不合格", | |||
@@ -30,7 +32,8 @@ export const dummyQCData: QcData[] = [ | |||
remarks: undefined, | |||
}, | |||
{ | |||
id: 6, | |||
id: 3, | |||
qcItemId: 6, | |||
code: "顔色", | |||
qcDescription: "不是食材應有的顔色、顔色不均匀、出現其他顔色、腌料/醬顔色不均匀,油脂部分變綠色、黃色,則不合格", | |||
name: "不是食材應有的顔色、顔色不均匀、出現其他顔色、腌料/醬顔色不均匀,油脂部分變綠色、黃色,則不合格", | |||
@@ -39,7 +42,8 @@ export const dummyQCData: QcData[] = [ | |||
remarks: undefined, | |||
}, | |||
{ | |||
id: 7, | |||
id: 4, | |||
qcItemId: 7, | |||
code: "狀態", | |||
qcDescription: "有結晶、結霜、解凍跡象、發霉、散發異味等任何一種情況,則不合格", | |||
name: "有結晶、結霜、解凍跡象、發霉、散發異味等任何一種情況,則不合格", | |||
@@ -48,7 +52,8 @@ export const dummyQCData: QcData[] = [ | |||
remarks: undefined, | |||
}, | |||
{ | |||
id: 8, | |||
id: 5, | |||
qcItemId: 8, | |||
code: "異物", | |||
qcDescription: "有不屬於本食材的雜質,則不合格", | |||
name: "有不屬於本食材的雜質,則不合格", | |||
@@ -34,6 +34,7 @@ | |||
"Pending application": "待處理提料申請", | |||
"pending inspection material": "待品檢物料", | |||
"rejected": "已拒絕", | |||
"accepted": "已收貨", | |||
"escalated": "已上報", | |||
"inspected material": "已品檢物料", | |||
"total material": "物料總數", | |||
@@ -50,5 +51,6 @@ | |||
"QC Completed Count": "品檢完成數量", | |||
"QC Fail-Total Count": "品檢不合格/總數", | |||
"escalationStatus": "上報狀態", | |||
"escalated datetime": "上報時間" | |||
"escalated datetime": "上報時間", | |||
"escalateFrom": "上報同事" | |||
} |