| @@ -156,16 +156,21 @@ const QcComponent: React.FC<Props> = ({ itemDetail, disabled = false }) => { | |||
| } | |||
| },[setError, qcDecision, accQty, itemDetail]) | |||
| useEffect(() => { // W I P // ----- | |||
| if (qcDecision == 1) { | |||
| if (validateFieldFail("acceptQty", accQty > itemDetail.acceptedQty, `${t("acceptQty must not greater than")} ${ | |||
| itemDetail.acceptedQty}`)) return; | |||
| useEffect(() => { // W I P // ----- | |||
| if (qcDecision == 1) { | |||
| if (validateFieldFail("acceptQty", accQty > itemDetail.acceptedQty, `${t("acceptQty must not greater than")} ${ | |||
| itemDetail.acceptedQty}`)) return; | |||
| if (validateFieldFail("acceptQty", accQty < 1, t("minimal value is 1"))) return; | |||
| if (validateFieldFail("acceptQty", isNaN(accQty), t("value must be a number"))) return; | |||
| } | |||
| if (validateFieldFail("acceptQty", accQty < 1, t("minimal value is 1"))) return; | |||
| if (validateFieldFail("acceptQty", isNaN(accQty), t("value must be a number"))) return; | |||
| } | |||
| const qcResultItems = qcResult; //console.log("Validating:", qcResultItems); | |||
| const qcResultItems = qcResult; //console.log("Validating:", qcResultItems); | |||
| // Allow empty QC items for default template (when qcCategory exists but has no items) | |||
| const hasEmptyDefaultTemplate = qcCategory && qcCategory.qcItems.length === 0 && qcResultItems.length === 0; | |||
| if (!hasEmptyDefaultTemplate) { | |||
| // Check if failed items have failed quantity | |||
| const failedItemsWithoutQty = qcResultItems.filter(item => | |||
| item.qcPassed === false && (!item.failQty || item.failQty <= 0) | |||
| @@ -179,12 +184,10 @@ const QcComponent: React.FC<Props> = ({ itemDetail, disabled = false }) => { | |||
| if (validateFieldFail("qcDecision", (!qcResultItems.every((qc) => qc.qcPassed) && qcDecision == 1 && itemDetail.status != "escalated"), | |||
| "有不合格檢查項目,無法收貨!")) return; // TODO: Fix it please | |||
| // submitDialogWithWarning(() => postStockInLineWithQc(qcData), t, {title:"有不合格檢查項目,確認接受收貨?", | |||
| // confirmButtonText: t("confirm putaway"), html: ""}); | |||
| // return; | |||
| } | |||
| // console.log("Validated without errors"); | |||
| }, [accQty, qcDecision, watch("qcResult")]); | |||
| // console.log("Validated without errors"); | |||
| }, [accQty, qcDecision, watch("qcResult"), qcCategory, qcResult]); | |||
| useEffect(() => { | |||
| clearErrors(); | |||
| @@ -225,24 +228,29 @@ const QcComponent: React.FC<Props> = ({ itemDetail, disabled = false }) => { | |||
| } | |||
| }, [itemDetail]); | |||
| const fetchNewQcData = useCallback( | |||
| async (input: QcInput) => { | |||
| try { | |||
| const res = await fetchQcCategory(input.itemId, qcType); | |||
| if (res.qcItems.length > 0) { | |||
| console.log("%c Fetched Qc Template: ", "color:orange", res); | |||
| setQcCategory(res); | |||
| // setQcResult(res.qcItems); | |||
| // setValue("qcResult", res.qcItems); | |||
| } else throw("Result is undefined"); | |||
| } catch (e) { | |||
| console.log("%c Error when fetching Qc Template: ", "color:red", e); | |||
| alert(t("Missing QC Template, please contact administrator")); | |||
| // closeHandler({}, "backdropClick"); | |||
| const fetchNewQcData = useCallback( | |||
| async (input: QcInput) => { | |||
| try { | |||
| const res = await fetchQcCategory(input.itemId, qcType); | |||
| // Allow templates even if they have no QC items (for default template case) | |||
| if (res && res.id) { | |||
| console.log("%c Fetched Qc Template: ", "color:orange", res); | |||
| setQcCategory(res); | |||
| // If template has no items, set empty array to allow proceeding | |||
| if (res.qcItems.length === 0) { | |||
| console.log("%c Default QC Template with no items, allowing empty QC", "color:yellow"); | |||
| setValue("qcResult", []); | |||
| } | |||
| } else { | |||
| throw new Error("QC Template not found"); | |||
| } | |||
| },[fetchQcCategory, setValue] | |||
| ); | |||
| } catch (e) { | |||
| console.log("%c Error when fetching Qc Template: ", "color:red", e); | |||
| alert(t("Missing QC Template, please contact administrator")); | |||
| // closeHandler({}, "backdropClick"); | |||
| } | |||
| },[fetchQcCategory, setValue, qcType] | |||
| ); | |||
| const fetchQcResultData = useCallback( | |||
| async (input: QcInput) => { | |||
| @@ -282,61 +290,65 @@ const QcComponent: React.FC<Props> = ({ itemDetail, disabled = false }) => { | |||
| ); | |||
| // Set QC Data | |||
| useEffect(() => { | |||
| if (itemDetail) { | |||
| const d = itemDetail; | |||
| if (qcRecord.length < 1) { // No QC Data | |||
| if (d.status == "pending") { // New QC | |||
| if (qcCategory) { | |||
| if (qcCategory.qcItems.length > 0) { | |||
| const filledQcItems = fillQcResult(qcCategory.qcItems); | |||
| setValue("qcResult", filledQcItems); | |||
| console.log("%c New QC Record applied:", "color:green", filledQcItems); | |||
| } | |||
| useEffect(() => { | |||
| if (itemDetail) { | |||
| const d = itemDetail; | |||
| if (qcRecord.length < 1) { // No QC Data | |||
| if (d.status == "pending") { // New QC | |||
| if (qcCategory) { | |||
| if (qcCategory.qcItems.length > 0) { | |||
| const filledQcItems = fillQcResult(qcCategory.qcItems); | |||
| setValue("qcResult", filledQcItems); | |||
| console.log("%c New QC Record applied:", "color:green", filledQcItems); | |||
| } else { | |||
| // Default template with no items - set empty array to allow proceeding | |||
| setValue("qcResult", []); | |||
| console.log("%c Default QC Template with no items applied:", "color:yellow"); | |||
| } | |||
| } else { | |||
| console.log("%c No QC Record loaded:", "color:green"); | |||
| // | |||
| } | |||
| } else { // QC Result fetched | |||
| if (qcRecord.some(qc => qc.order !== undefined)) { // If QC Result is filled with order | |||
| if (d.status == "escalated") { // Copy the previous QC data for editing | |||
| // If no editable Qc Data | |||
| if (!qcRecord.some((qc) => !isExist(qc.escalationLogId))) { | |||
| const mutableQcData = qcRecord.map(qc => ({ ...qc, escalationLogId: undefined })); | |||
| const copiedQcData = [...mutableQcData, ...qcRecord]; | |||
| setValue("qcResult", copiedQcData); | |||
| console.log("%c QC Record copied:", "color:green", copiedQcData); | |||
| return; | |||
| } | |||
| } else { | |||
| console.log("%c No QC Record loaded:", "color:green"); | |||
| // | |||
| } | |||
| } else { // QC Result fetched | |||
| if (qcRecord.some(qc => qc.order !== undefined)) { // If QC Result is filled with order | |||
| if (d.status == "escalated") { // Copy the previous QC data for editing | |||
| // If no editable Qc Data | |||
| if (!qcRecord.some((qc) => !isExist(qc.escalationLogId))) { | |||
| const mutableQcData = qcRecord.map(qc => ({ ...qc, escalationLogId: undefined })); | |||
| const copiedQcData = [...mutableQcData, ...qcRecord]; | |||
| setValue("qcResult", copiedQcData); | |||
| console.log("%c QC Record copied:", "color:green", copiedQcData); | |||
| return; | |||
| } | |||
| } | |||
| // Set QC Result | |||
| // const filteredQcResult = qcRecord; | |||
| const filteredQcResult = qcRecord.filter((qc) => !isExist(qc.escalationLogId)); | |||
| console.log("%c QC Result loaded:", "color:green", filteredQcResult); | |||
| setQcResult(filteredQcResult); | |||
| // Set QC History | |||
| if (filteredQcResult.length < qcRecord.length) { // If there are Qc History | |||
| if (qcHistory.length < 1) { | |||
| const filteredQcHistory = qcRecord.filter((qc) => isExist(qc.escalationLogId)); | |||
| console.log("%c QC History loaded:", "color:green", filteredQcHistory); | |||
| setQcHistory(filteredQcHistory); | |||
| } | |||
| } | |||
| } else { | |||
| if (qcCategory) { | |||
| const filledQcData = fillQcResult(qcRecord, qcCategory?.qcItems); | |||
| console.log("%c QC Result filled:", "color:green", filledQcData); | |||
| setValue("qcResult", filledQcData); | |||
| // Set QC Result | |||
| // const filteredQcResult = qcRecord; | |||
| const filteredQcResult = qcRecord.filter((qc) => !isExist(qc.escalationLogId)); | |||
| console.log("%c QC Result loaded:", "color:green", filteredQcResult); | |||
| setQcResult(filteredQcResult); | |||
| // Set QC History | |||
| if (filteredQcResult.length < qcRecord.length) { // If there are Qc History | |||
| if (qcHistory.length < 1) { | |||
| const filteredQcHistory = qcRecord.filter((qc) => isExist(qc.escalationLogId)); | |||
| console.log("%c QC History loaded:", "color:green", filteredQcHistory); | |||
| setQcHistory(filteredQcHistory); | |||
| } | |||
| } | |||
| } else { | |||
| if (qcCategory) { | |||
| const filledQcData = fillQcResult(qcRecord, qcCategory?.qcItems); | |||
| console.log("%c QC Result filled:", "color:green", filledQcData); | |||
| setValue("qcResult", filledQcData); | |||
| } | |||
| } | |||
| } | |||
| }, [qcRecord, qcCategory, setValue, itemDetail]) | |||
| } | |||
| }, [qcRecord, qcCategory, setValue, itemDetail]) | |||
| const fillQcResult = (qcResults: QcResult[], qcItems: QcData[] = []) => { | |||
| let result = [] as QcResult[]; | |||
| @@ -439,7 +451,7 @@ const QcComponent: React.FC<Props> = ({ itemDetail, disabled = false }) => { | |||
| return ( | |||
| <> | |||
| <Grid container justifyContent="flex-start" alignItems="flex-start"> | |||
| {(qcRecord.length > 0) ? ( | |||
| {(qcCategory && (qcRecord.length >= 0)) ? ( // Changed: check qcCategory exists and allow empty qcRecord | |||
| // {(qcRecord.length > 0 && qcCategory) ? ( | |||
| <Grid | |||
| container | |||