| @@ -37,7 +37,7 @@ export default async function MainLayout({ | |||||
| return ( | return ( | ||||
| <SessionProviderWrapper session={session}> | <SessionProviderWrapper session={session}> | ||||
| <UploadProvider> | <UploadProvider> | ||||
| <CameraProvider> | |||||
| {/* <CameraProvider> */} | |||||
| <AxiosProvider> | <AxiosProvider> | ||||
| <QrCodeScannerProvider> | <QrCodeScannerProvider> | ||||
| <> | <> | ||||
| @@ -62,7 +62,7 @@ export default async function MainLayout({ | |||||
| </> | </> | ||||
| </QrCodeScannerProvider> | </QrCodeScannerProvider> | ||||
| </AxiosProvider> | </AxiosProvider> | ||||
| </CameraProvider> | |||||
| {/* </CameraProvider> */} | |||||
| </UploadProvider> | </UploadProvider> | ||||
| </SessionProviderWrapper> | </SessionProviderWrapper> | ||||
| ); | ); | ||||
| @@ -30,9 +30,6 @@ export interface StockInLineEntry { | |||||
| acceptedQty: number; | acceptedQty: number; | ||||
| status?: string; | status?: string; | ||||
| expiryDate?: string; | expiryDate?: string; | ||||
| productLotNo?: string; | |||||
| receiptDate?: string; | |||||
| dnDate?: string; | |||||
| } | } | ||||
| export interface PurchaseQcResult { | export interface PurchaseQcResult { | ||||
| @@ -31,11 +31,14 @@ export interface StockInLineEntry { | |||||
| acceptedQty: number; | acceptedQty: number; | ||||
| status?: string; | status?: string; | ||||
| expiryDate?: string; | expiryDate?: string; | ||||
| productLotNo?: string; | |||||
| receiptDate?: string; | |||||
| dnDate?: string; | |||||
| } | } | ||||
| export interface PurchaseQcResult{ | export interface PurchaseQcResult{ | ||||
| qcItemId: number; | qcItemId: number; | ||||
| isPassed: boolean; | |||||
| qcPassed: boolean; | |||||
| failQty: number; | failQty: number; | ||||
| remarks?: string; | remarks?: string; | ||||
| @@ -111,7 +114,7 @@ export const fetchStockInLineInfo = cache(async (stockInLineId: number) => { | |||||
| export const createStockInLine = async (data: StockInLineEntry) => { | export const createStockInLine = async (data: StockInLineEntry) => { | ||||
| const stockInLine = await serverFetchJson< | const stockInLine = await serverFetchJson< | ||||
| PostStockInLineResponse<StockInLineEntry> | |||||
| PostStockInLineResponse<StockInLine> | |||||
| >(`${BASE_API_URL}/stockInLine/create`, { | >(`${BASE_API_URL}/stockInLine/create`, { | ||||
| method: "POST", | method: "POST", | ||||
| body: JSON.stringify(data), | body: JSON.stringify(data), | ||||
| @@ -125,7 +128,7 @@ export const updateStockInLine = async ( | |||||
| data: StockInLineEntry & ModalFormInput, | data: StockInLineEntry & ModalFormInput, | ||||
| ) => { | ) => { | ||||
| const stockInLine = await serverFetchJson< | const stockInLine = await serverFetchJson< | ||||
| PostStockInLineResponse<StockInLineEntry & ModalFormInput> | |||||
| PostStockInLineResponse<StockInLine & ModalFormInput> | |||||
| >(`${BASE_API_URL}/stockInLine/update`, { | >(`${BASE_API_URL}/stockInLine/update`, { | ||||
| method: "POST", | method: "POST", | ||||
| body: JSON.stringify(data), | body: JSON.stringify(data), | ||||
| @@ -54,7 +54,7 @@ export interface StockUomForPoLine { | |||||
| export interface StockInLine { | export interface StockInLine { | ||||
| id: number; | id: number; | ||||
| stockInId: number; | |||||
| stockInId?: number; | |||||
| purchaseOrderId?: number; | purchaseOrderId?: number; | ||||
| purchaseOrderLineId: number; | purchaseOrderLineId: number; | ||||
| itemId: number; | itemId: number; | ||||
| @@ -63,23 +63,24 @@ export interface StockInLine { | |||||
| itemType: string; | itemType: string; | ||||
| demandQty: number; | demandQty: number; | ||||
| acceptedQty: number; | acceptedQty: number; | ||||
| qty: number; | |||||
| processed: number; | |||||
| price: number; | |||||
| priceUnit: string; | |||||
| qty?: number; | |||||
| processed?: number; | |||||
| price?: number; | |||||
| priceUnit?: string; | |||||
| shelfLife?: number; | shelfLife?: number; | ||||
| receiptDate?: string; | receiptDate?: string; | ||||
| productionDate?: string; | productionDate?: string; | ||||
| productLotNo?: string; | |||||
| expiryDate?: string; | expiryDate?: string; | ||||
| status: string; | status: string; | ||||
| supplier: string; | |||||
| lotNo: string; | |||||
| poCode: string; | |||||
| uom: Uom; | |||||
| supplier?: string; | |||||
| lotNo?: string; | |||||
| poCode?: string; | |||||
| uom?: Uom; | |||||
| defaultWarehouseId: number; // id for now | defaultWarehouseId: number; // id for now | ||||
| dnNo: string; | |||||
| dnDate: number[]; | |||||
| stockQty: number; | |||||
| dnNo?: string; | |||||
| dnDate?: number[]; | |||||
| stockQty?: number; | |||||
| } | } | ||||
| export const fetchPoList = cache(async (queryParams?: Record<string, any>) => { | export const fetchPoList = cache(async (queryParams?: Record<string, any>) => { | ||||
| @@ -20,7 +20,7 @@ export interface QcData { | |||||
| code: string, | code: string, | ||||
| name: string, | name: string, | ||||
| qcDescription: string, | qcDescription: string, | ||||
| isPassed: boolean | undefined | |||||
| qcPassed: boolean | undefined | |||||
| failQty: number | undefined | failQty: number | undefined | ||||
| remarks: string | undefined | remarks: string | undefined | ||||
| } | } | ||||
| @@ -49,7 +49,7 @@ import EscalationComponent from "./EscalationComponent"; | |||||
| import QcDataGrid from "./QCDatagrid"; | import QcDataGrid from "./QCDatagrid"; | ||||
| import StockInFormVer2 from "./StockInFormVer2"; | import StockInFormVer2 from "./StockInFormVer2"; | ||||
| import { dummyEscalationHistory, dummyQCData, QcData } from "./dummyQcTemplate"; | import { dummyEscalationHistory, dummyQCData, QcData } from "./dummyQcTemplate"; | ||||
| import { ModalFormInput } from "@/app/api/dashboard/actions"; | |||||
| import { ModalFormInput } from "@/app/api/po/actions"; | |||||
| import { escape } from "lodash"; | import { escape } from "lodash"; | ||||
| interface Props { | interface Props { | ||||
| @@ -43,9 +43,11 @@ import { | |||||
| import { | import { | ||||
| checkPolAndCompletePo, | checkPolAndCompletePo, | ||||
| fetchPoInClient, | fetchPoInClient, | ||||
| fetchPoListClient, | |||||
| fetchStockInLineInfo, | fetchStockInLineInfo, | ||||
| PurchaseQcResult, | PurchaseQcResult, | ||||
| startPo, | startPo, | ||||
| createStockInLine | |||||
| } from "@/app/api/po/actions"; | } from "@/app/api/po/actions"; | ||||
| import { | import { | ||||
| useCallback, | useCallback, | ||||
| @@ -69,9 +71,7 @@ import DoneIcon from "@mui/icons-material/Done"; | |||||
| import { getCustomWidth } from "@/app/utils/commonUtil"; | import { getCustomWidth } from "@/app/utils/commonUtil"; | ||||
| import PoInfoCard from "./PoInfoCard"; | import PoInfoCard from "./PoInfoCard"; | ||||
| import { decimalFormatter, integerFormatter } from "@/app/utils/formatUtil"; | import { decimalFormatter, integerFormatter } from "@/app/utils/formatUtil"; | ||||
| import { fetchPoListClient } from "@/app/api/po/actions"; | |||||
| import { List, ListItem, ListItemButton, ListItemText, Divider } from "@mui/material"; | import { List, ListItem, ListItemButton, ListItemText, Divider } from "@mui/material"; | ||||
| import { createStockInLine } from "@/app/api/dashboard/actions"; | |||||
| import { Controller, FormProvider, useForm } from "react-hook-form"; | import { Controller, FormProvider, useForm } from "react-hook-form"; | ||||
| import dayjs, { Dayjs } from "dayjs"; | import dayjs, { Dayjs } from "dayjs"; | ||||
| import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; | import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; | ||||
| @@ -81,7 +81,6 @@ import LoadingComponent from "../General/LoadingComponent"; | |||||
| //import { useRouter } from "next/navigation"; | //import { useRouter } from "next/navigation"; | ||||
| type Props = { | type Props = { | ||||
| po: PoResult; | po: PoResult; | ||||
| qc: QcItemWithChecks[]; | qc: QcItemWithChecks[]; | ||||
| @@ -397,6 +396,9 @@ const PoDetail: React.FC<Props> = ({ po, qc, warehouse }) => { | |||||
| setTimeout(async () => { | setTimeout(async () => { | ||||
| // post stock in line | // post stock in line | ||||
| const oldId = row.id; | const oldId = row.id; | ||||
| const acceptedQty = Number(polInputList[rowIndex].dnQty); | |||||
| if (isNaN(acceptedQty) || acceptedQty <= 0) { alert("來貨數量必須大於0!"); return; } // Temp check, need update | |||||
| const postData = { | const postData = { | ||||
| dnNo: dnFormProps.watch("dnNo"), | dnNo: dnFormProps.watch("dnNo"), | ||||
| dnDate: outputDateStringToInputDateString(dnFormProps.watch("dnDate")), | dnDate: outputDateStringToInputDateString(dnFormProps.watch("dnDate")), | ||||
| @@ -405,7 +407,7 @@ const PoDetail: React.FC<Props> = ({ po, qc, warehouse }) => { | |||||
| itemName: row.itemName, | itemName: row.itemName, | ||||
| purchaseOrderId: row.purchaseOrderId, | purchaseOrderId: row.purchaseOrderId, | ||||
| purchaseOrderLineId: row.id, | purchaseOrderLineId: row.id, | ||||
| acceptedQty: polInputList[rowIndex].dnQty || 0, | |||||
| acceptedQty: acceptedQty, | |||||
| productLotNo: polInputList[rowIndex].lotNo || '', | productLotNo: polInputList[rowIndex].lotNo || '', | ||||
| // acceptedQty: secondReceiveQty || 0, | // acceptedQty: secondReceiveQty || 0, | ||||
| // acceptedQty: row.acceptedQty, | // acceptedQty: row.acceptedQty, | ||||
| @@ -535,7 +537,7 @@ const PoDetail: React.FC<Props> = ({ po, qc, warehouse }) => { | |||||
| handleStart() | handleStart() | ||||
| } | } | ||||
| > | > | ||||
| 提交 | |||||
| {t("submit")} | |||||
| </Button> | </Button> | ||||
| </TableCell> | </TableCell> | ||||
| </TableRow> | </TableRow> | ||||
| @@ -49,7 +49,7 @@ import EscalationComponent from "./EscalationComponent"; | |||||
| import QcDataGrid from "./QCDatagrid"; | import QcDataGrid from "./QCDatagrid"; | ||||
| import StockInFormVer2 from "./StockInFormVer2"; | import StockInFormVer2 from "./StockInFormVer2"; | ||||
| import { dummyEscalationHistory, dummyQCData } from "./dummyQcTemplate"; | import { dummyEscalationHistory, dummyQCData } from "./dummyQcTemplate"; | ||||
| import { ModalFormInput } from "@/app/api/dashboard/actions"; | |||||
| import { ModalFormInput } from "@/app/api/po/actions"; | |||||
| import { escape } from "lodash"; | import { escape } from "lodash"; | ||||
| import { PanoramaSharp } from "@mui/icons-material"; | import { PanoramaSharp } from "@mui/icons-material"; | ||||
| @@ -197,7 +197,7 @@ const QcFormVer2: React.FC<Props> = ({ qc, itemDetail, disabled, qcItems, setQcI | |||||
| ), | ), | ||||
| }, | }, | ||||
| { | { | ||||
| field: 'qcResult', | |||||
| field: 'qcPassed', | |||||
| headerName: t("qcResult"), | headerName: t("qcResult"), | ||||
| flex: 1.5, | flex: 1.5, | ||||
| renderCell: (params) => { | renderCell: (params) => { | ||||
| @@ -208,14 +208,15 @@ const QcFormVer2: React.FC<Props> = ({ qc, itemDetail, disabled, qcItems, setQcI | |||||
| <RadioGroup | <RadioGroup | ||||
| row | row | ||||
| aria-labelledby="demo-radio-buttons-group-label" | aria-labelledby="demo-radio-buttons-group-label" | ||||
| value={currentValue.isPassed === undefined ? (currentValue.failQty!==undefined?(currentValue.failQty==0?"true":"false"):"") : (currentValue.isPassed ? "true" : "false")} | |||||
| value={currentValue.qcPassed === undefined ? "" : (currentValue.qcPassed ? "true" : "false")} | |||||
| // value={currentValue.qcPassed === undefined ? (currentValue.failQty!==undefined?(currentValue.failQty==0?"true":"false"):"") : (currentValue.qcPassed ? "true" : "false")} | |||||
| onChange={(e) => { | onChange={(e) => { | ||||
| const value = e.target.value; | const value = e.target.value; | ||||
| setQcItems((prev) => | setQcItems((prev) => | ||||
| prev.map((r): QcData => (r.id === params.id ? { ...r, isPassed: value === "true" } : r)) | |||||
| prev.map((r): QcData => (r.id === params.id ? { ...r, qcPassed: value === "true" } : r)) | |||||
| ); | ); | ||||
| }} | }} | ||||
| name={`isPassed-${params.id}`} | |||||
| name={`qcPassed-${params.id}`} | |||||
| > | > | ||||
| <FormControlLabel | <FormControlLabel | ||||
| value="true" | value="true" | ||||
| @@ -223,7 +224,7 @@ const QcFormVer2: React.FC<Props> = ({ qc, itemDetail, disabled, qcItems, setQcI | |||||
| label="合格" | label="合格" | ||||
| disabled={disabled} | disabled={disabled} | ||||
| sx={{ | sx={{ | ||||
| color: currentValue.isPassed === true ? "green" : "inherit", | |||||
| color: currentValue.qcPassed === true ? "green" : "inherit", | |||||
| "& .Mui-checked": {color: "green"} | "& .Mui-checked": {color: "green"} | ||||
| }} | }} | ||||
| /> | /> | ||||
| @@ -233,7 +234,7 @@ const QcFormVer2: React.FC<Props> = ({ qc, itemDetail, disabled, qcItems, setQcI | |||||
| label="不合格" | label="不合格" | ||||
| disabled={disabled} | disabled={disabled} | ||||
| sx={{ | sx={{ | ||||
| color: currentValue.isPassed === false ? "red" : "inherit", | |||||
| color: currentValue.qcPassed === false ? "red" : "inherit", | |||||
| "& .Mui-checked": {color: "red"} | "& .Mui-checked": {color: "red"} | ||||
| }} | }} | ||||
| /> | /> | ||||
| @@ -251,8 +252,8 @@ const QcFormVer2: React.FC<Props> = ({ qc, itemDetail, disabled, qcItems, setQcI | |||||
| <TextField | <TextField | ||||
| type="number" | type="number" | ||||
| size="small" | size="small" | ||||
| value={!params.row.isPassed? (params.value ?? '') : '0'} | |||||
| disabled={params.row.isPassed || disabled} | |||||
| value={!params.row.qcPassed? (params.value ?? '') : '0'} | |||||
| disabled={params.row.qcPassed || disabled} | |||||
| onChange={(e) => { | onChange={(e) => { | ||||
| const v = e.target.value; | const v = e.target.value; | ||||
| const next = v === '' ? undefined : Number(v); | const next = v === '' ? undefined : Number(v); | ||||
| @@ -313,7 +314,7 @@ const QcFormVer2: React.FC<Props> = ({ qc, itemDetail, disabled, qcItems, setQcI | |||||
| const [isCollapsed, setIsCollapsed] = useState<boolean>(true); | const [isCollapsed, setIsCollapsed] = useState<boolean>(true); | ||||
| const onFailedOpenCollapse = useCallback((qcItems: PurchaseQcResult[]) => { | const onFailedOpenCollapse = useCallback((qcItems: PurchaseQcResult[]) => { | ||||
| const isFailed = qcItems.some((qc) => !qc.isPassed) | |||||
| const isFailed = qcItems.some((qc) => !qc.qcPassed) | |||||
| console.log(isFailed) | console.log(isFailed) | ||||
| if (isFailed) { | if (isFailed) { | ||||
| setIsCollapsed(true) | setIsCollapsed(true) | ||||
| @@ -439,7 +440,11 @@ const QcFormVer2: React.FC<Props> = ({ qc, itemDetail, disabled, qcItems, setQcI | |||||
| <FormControlLabel disabled={disabled} | <FormControlLabel disabled={disabled} | ||||
| value="false" control={<Radio />} | value="false" control={<Radio />} | ||||
| sx={{"& .Mui-checked": {color: "red"}}} | sx={{"& .Mui-checked": {color: "red"}}} | ||||
| label="不接受及上報" /> | |||||
| label="不接受" /> | |||||
| <FormControlLabel disabled={disabled} | |||||
| value="false" control={<Radio />} | |||||
| sx={{"& .Mui-checked": {color: "blue"}}} | |||||
| label="上報品檢結果" /> | |||||
| </RadioGroup> | </RadioGroup> | ||||
| )} | )} | ||||
| /> | /> | ||||
| @@ -1,6 +1,6 @@ | |||||
| "use client"; | "use client"; | ||||
| import { StockInLine } from "@/app/api/po"; | import { StockInLine } from "@/app/api/po"; | ||||
| import { ModalFormInput, PurchaseQcResult, StockInLineEntry, updateStockInLine } from "@/app/api/po/actions"; | |||||
| import { ModalFormInput, PurchaseQcResult, StockInLineEntry, updateStockInLine, PurchaseQCInput } from "@/app/api/po/actions"; | |||||
| import { QcItemWithChecks, QcData } from "@/app/api/qc"; | import { QcItemWithChecks, QcData } from "@/app/api/qc"; | ||||
| import { | import { | ||||
| Box, | Box, | ||||
| @@ -22,7 +22,6 @@ import PutawayForm from "./PutawayForm"; | |||||
| import { dummyPutawayLine, dummyQCData } from "./dummyQcTemplate"; | import { dummyPutawayLine, dummyQCData } from "./dummyQcTemplate"; | ||||
| import { useGridApiRef } from "@mui/x-data-grid"; | import { useGridApiRef } from "@mui/x-data-grid"; | ||||
| import {submitDialogWithWarning} from "../Swal/CustomAlerts"; | import {submitDialogWithWarning} from "../Swal/CustomAlerts"; | ||||
| import { PurchaseQCInput, PutawayInput } from "@/app/api/dashboard/actions"; | |||||
| import { arrayToDateString, arrayToInputDateString, dayjsToInputDateString } from "@/app/utils/formatUtil"; | import { arrayToDateString, arrayToInputDateString, dayjsToInputDateString } from "@/app/utils/formatUtil"; | ||||
| import dayjs from "dayjs"; | import dayjs from "dayjs"; | ||||
| @@ -114,10 +113,11 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
| }, [open]) | }, [open]) | ||||
| const [isCompleted, setIsCompleted] = useState(false); | |||||
| const [viewOnly, setViewOnly] = useState(false); | |||||
| useEffect(() => { | useEffect(() => { | ||||
| setIsCompleted(itemDetail.status.toLowerCase() == "completed") | |||||
| const isViewOnly = itemDetail.status.toLowerCase() == "completed" || itemDetail.status.toLowerCase() == "rejected" | |||||
| setViewOnly(isViewOnly) | |||||
| }, [itemDetail]); | }, [itemDetail]); | ||||
| const [openPutaway, setOpenPutaway] = useState(false); | const [openPutaway, setOpenPutaway] = useState(false); | ||||
| @@ -162,12 +162,12 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
| const qcAccept = data.qcAccept; | const qcAccept = data.qcAccept; | ||||
| const acceptQty = data.acceptQty as number; | const acceptQty = data.acceptQty as number; | ||||
| const qcResults = qcItems; | const qcResults = qcItems; | ||||
| // const qcResults = isCompleted? data.qcResult as PurchaseQcResult[] : qcItems; | |||||
| // const qcResults = viewOnly? data.qcResult as PurchaseQcResult[] : qcItems; | |||||
| // Validate QC data | // Validate QC data | ||||
| const validationErrors : string[] = []; | const validationErrors : string[] = []; | ||||
| // Check if all QC items have results | // Check if all QC items have results | ||||
| const itemsWithoutResult = qcResults.filter(item => item.isPassed === undefined); | |||||
| const itemsWithoutResult = qcResults.filter(item => item.qcPassed === undefined); | |||||
| if (itemsWithoutResult.length > 0) { | if (itemsWithoutResult.length > 0) { | ||||
| validationErrors.push(`${t("QC items without result")}`); | validationErrors.push(`${t("QC items without result")}`); | ||||
| // validationErrors.push(`${t("QC items without result")}: ${itemsWithoutResult.map(item => item.code).join(', ')}`); | // validationErrors.push(`${t("QC items without result")}: ${itemsWithoutResult.map(item => item.code).join(', ')}`); | ||||
| @@ -175,7 +175,7 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
| // Check if failed items have failed quantity | // Check if failed items have failed quantity | ||||
| const failedItemsWithoutQty = qcResults.filter(item => | const failedItemsWithoutQty = qcResults.filter(item => | ||||
| item.isPassed === false && (!item.failQty || item.failQty <= 0) | |||||
| item.qcPassed === false && (!item.failQty || item.failQty <= 0) | |||||
| ); | ); | ||||
| if (failedItemsWithoutQty.length > 0) { | if (failedItemsWithoutQty.length > 0) { | ||||
| validationErrors.push(`${t("Failed items must have failed quantity")}`); | validationErrors.push(`${t("Failed items must have failed quantity")}`); | ||||
| @@ -194,10 +194,16 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
| // Check if dates are input | // Check if dates are input | ||||
| if (data.productionDate === undefined || data.productionDate == null) { | if (data.productionDate === undefined || data.productionDate == null) { | ||||
| validationErrors.push("Production Date cannot be null!"); | |||||
| validationErrors.push("請輸入生產日期!"); | |||||
| } | } | ||||
| if (data.expiryDate === undefined || data.expiryDate == null) { | if (data.expiryDate === undefined || data.expiryDate == null) { | ||||
| validationErrors.push("Expiry Date cannot be null!"); | |||||
| validationErrors.push("請輸入到期日!"); | |||||
| } | |||||
| if (!qcResults.every((qc) => qc.qcPassed) && qcAccept) { | |||||
| validationErrors.push("有不合格檢查項目,無法收貨!"); | |||||
| // submitDialogWithWarning(() => postStockInLineWithQc(qcData), t, {title:"有不合格檢查項目,確認接受收貨?", | |||||
| // confirmButtonText: t("confirm putaway"), html: ""}); | |||||
| // return; | |||||
| } | } | ||||
| if (validationErrors.length > 0) { | if (validationErrors.length > 0) { | ||||
| @@ -219,8 +225,8 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
| qcItemId: item.id, | qcItemId: item.id, | ||||
| // code: item.code, | // code: item.code, | ||||
| // qcDescription: item.qcDescription, | // qcDescription: item.qcDescription, | ||||
| isPassed: item.isPassed? item.isPassed : false, | |||||
| failQty: (item.failQty && !item.isPassed) ? item.failQty : 0, | |||||
| qcPassed: item.qcPassed? item.qcPassed : false, | |||||
| failQty: (item.failQty && !item.qcPassed) ? item.failQty : 0, | |||||
| // failedQty: (typeof item.failedQty === "number" && !item.isPassed) ? item.failedQty : 0, | // failedQty: (typeof item.failedQty === "number" && !item.isPassed) ? item.failedQty : 0, | ||||
| remarks: item.remarks || '' | remarks: item.remarks || '' | ||||
| })) | })) | ||||
| @@ -228,42 +234,21 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
| // const qcData = data; | // const qcData = data; | ||||
| console.log("QC Data for submission:", qcData); | console.log("QC Data for submission:", qcData); | ||||
| await postStockInLine(qcData); | |||||
| if (!qcData.qcResult.every((qc) => qc.isPassed) && qcData.qcAccept) { | |||||
| submitDialogWithWarning(() => postStockInLineWithQc(qcData), t, {title:"有不合格檢查項目,確認接受收貨?", | |||||
| confirmButtonText: t("confirm putaway"), html: ""}); | |||||
| return; | |||||
| if (qcData.qcAccept) { | |||||
| // submitDialogWithWarning(onOpenPutaway, t, {title:"Save success, confirm to proceed?", | |||||
| // confirmButtonText: t("confirm putaway"), html: ""}); | |||||
| onOpenPutaway(); | |||||
| } else { | |||||
| closeHandler({}, "backdropClick"); | |||||
| } | } | ||||
| await postStockInLineWithQc(qcData); | |||||
| // return; | |||||
| return ; | |||||
| }, | }, | ||||
| [onOpenPutaway, qcItems], | [onOpenPutaway, qcItems], | ||||
| ); | ); | ||||
| const postStockInLineWithQc = useCallback(async (qcData: PurchaseQCInput) => { | |||||
| const args = { | |||||
| ...qcData | |||||
| // id: itemDetail.id, | |||||
| // purchaseOrderId: itemDetail.purchaseOrderId, | |||||
| // purchaseOrderLineId: itemDetail.purchaseOrderLineId, | |||||
| // itemId: itemDetail.itemId, | |||||
| // ...data, | |||||
| // productionDate: productionDate, | |||||
| // expiryDate: expiryDate, | |||||
| // receiptDate: receiptDate, | |||||
| } as ModalFormInput; | |||||
| await postStockInLine(args); | |||||
| if (qcData.qcAccept) { | |||||
| // submitDialogWithWarning(onOpenPutaway, t, {title:"Save success, confirm to proceed?", | |||||
| // confirmButtonText: t("confirm putaway"), html: ""}); | |||||
| onOpenPutaway(); | |||||
| } else { | |||||
| closeHandler({}, "backdropClick"); | |||||
| } | |||||
| return ; | |||||
| },[onOpenPutaway,closeHandler]); | |||||
| const postStockInLine = useCallback(async (args: ModalFormInput) => { | const postStockInLine = useCallback(async (args: ModalFormInput) => { | ||||
| const submitData = { | const submitData = { | ||||
| @@ -340,7 +325,7 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
| const acceptQty = formProps.watch("acceptedQty") | const acceptQty = formProps.watch("acceptedQty") | ||||
| const checkQcIsPassed = useCallback((qcItems: PurchaseQcResult[]) => { | const checkQcIsPassed = useCallback((qcItems: PurchaseQcResult[]) => { | ||||
| const isPassed = qcItems.every((qc) => qc.isPassed); | |||||
| const isPassed = qcItems.every((qc) => qc.qcPassed); | |||||
| console.log(isPassed) | console.log(isPassed) | ||||
| if (isPassed) { | if (isPassed) { | ||||
| formProps.setValue("passingQty", acceptQty) | formProps.setValue("passingQty", acceptQty) | ||||
| @@ -378,7 +363,7 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
| <PutawayForm | <PutawayForm | ||||
| itemDetail={itemDetail} | itemDetail={itemDetail} | ||||
| warehouse={warehouse!} | warehouse={warehouse!} | ||||
| disabled={isCompleted} | |||||
| disabled={viewOnly} | |||||
| /> | /> | ||||
| <Stack direction="row" justifyContent="flex-end" gap={1}> | <Stack direction="row" justifyContent="flex-end" gap={1}> | ||||
| <Button | <Button | ||||
| @@ -416,7 +401,7 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
| </Typography> | </Typography> | ||||
| </Grid> | </Grid> | ||||
| <Grid item xs={12}> | <Grid item xs={12}> | ||||
| <StockInFormVer2 itemDetail={itemDetail} disabled={isCompleted} /> | |||||
| <StockInFormVer2 itemDetail={itemDetail} disabled={viewOnly} /> | |||||
| </Grid> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| {/* <Stack direction="row" justifyContent="flex-end" gap={1}> | {/* <Stack direction="row" justifyContent="flex-end" gap={1}> | ||||
| @@ -438,13 +423,13 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
| <QcFormVer2 | <QcFormVer2 | ||||
| qc={qc!} | qc={qc!} | ||||
| itemDetail={itemDetail} | itemDetail={itemDetail} | ||||
| disabled={isCompleted} | |||||
| disabled={viewOnly} | |||||
| qcItems={qcItems} | qcItems={qcItems} | ||||
| setQcItems={setQcItems} | setQcItems={setQcItems} | ||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| <Stack direction="row" justifyContent="flex-end" gap={1}> | <Stack direction="row" justifyContent="flex-end" gap={1}> | ||||
| {!isCompleted && (<Button | |||||
| {!viewOnly && (<Button | |||||
| id="qcSubmit" | id="qcSubmit" | ||||
| type="button" | type="button" | ||||
| variant="contained" | variant="contained" | ||||
| @@ -16,7 +16,7 @@ export const dummyQCData: QcData[] = [ | |||||
| code: "包裝", | code: "包裝", | ||||
| qcDescription: "有破爛、污糟、脹袋、積水、與實物不符等任何一種情況,則不合格", | qcDescription: "有破爛、污糟、脹袋、積水、與實物不符等任何一種情況,則不合格", | ||||
| name: "有破爛、污糟、脹袋、積水、與實物不符等任何一種情況,則不合格", | name: "有破爛、污糟、脹袋、積水、與實物不符等任何一種情況,則不合格", | ||||
| isPassed: undefined, | |||||
| qcPassed: undefined, | |||||
| failQty: undefined, | failQty: undefined, | ||||
| remarks: undefined, | remarks: undefined, | ||||
| }, | }, | ||||
| @@ -25,7 +25,7 @@ export const dummyQCData: QcData[] = [ | |||||
| code: "肉質", | code: "肉質", | ||||
| qcDescription: "肉質鬆散,則不合格", | qcDescription: "肉質鬆散,則不合格", | ||||
| name: "肉質鬆散,則不合格", | name: "肉質鬆散,則不合格", | ||||
| isPassed: undefined, | |||||
| qcPassed: undefined, | |||||
| failQty: undefined, | failQty: undefined, | ||||
| remarks: undefined, | remarks: undefined, | ||||
| }, | }, | ||||
| @@ -34,7 +34,7 @@ export const dummyQCData: QcData[] = [ | |||||
| code: "顔色", | code: "顔色", | ||||
| qcDescription: "不是食材應有的顔色、顔色不均匀、出現其他顔色、腌料/醬顔色不均匀,油脂部分變綠色、黃色,則不合格", | qcDescription: "不是食材應有的顔色、顔色不均匀、出現其他顔色、腌料/醬顔色不均匀,油脂部分變綠色、黃色,則不合格", | ||||
| name: "不是食材應有的顔色、顔色不均匀、出現其他顔色、腌料/醬顔色不均匀,油脂部分變綠色、黃色,則不合格", | name: "不是食材應有的顔色、顔色不均匀、出現其他顔色、腌料/醬顔色不均匀,油脂部分變綠色、黃色,則不合格", | ||||
| isPassed: undefined, | |||||
| qcPassed: undefined, | |||||
| failQty: undefined, | failQty: undefined, | ||||
| remarks: undefined, | remarks: undefined, | ||||
| }, | }, | ||||
| @@ -43,7 +43,7 @@ export const dummyQCData: QcData[] = [ | |||||
| code: "狀態", | code: "狀態", | ||||
| qcDescription: "有結晶、結霜、解凍跡象、發霉、散發異味等任何一種情況,則不合格", | qcDescription: "有結晶、結霜、解凍跡象、發霉、散發異味等任何一種情況,則不合格", | ||||
| name: "有結晶、結霜、解凍跡象、發霉、散發異味等任何一種情況,則不合格", | name: "有結晶、結霜、解凍跡象、發霉、散發異味等任何一種情況,則不合格", | ||||
| isPassed: undefined, | |||||
| qcPassed: undefined, | |||||
| failQty: undefined, | failQty: undefined, | ||||
| remarks: undefined, | remarks: undefined, | ||||
| }, | }, | ||||
| @@ -52,7 +52,7 @@ export const dummyQCData: QcData[] = [ | |||||
| code: "異物", | code: "異物", | ||||
| qcDescription: "有不屬於本食材的雜質,則不合格", | qcDescription: "有不屬於本食材的雜質,則不合格", | ||||
| name: "有不屬於本食材的雜質,則不合格", | name: "有不屬於本食材的雜質,則不合格", | ||||
| isPassed: undefined, | |||||
| qcPassed: undefined, | |||||
| failQty: undefined, | failQty: undefined, | ||||
| remarks: undefined, | remarks: undefined, | ||||
| }, | }, | ||||