|
|
@@ -0,0 +1,610 @@ |
|
|
|
"use client"; |
|
|
|
import { StockInLine } from "@/app/api/po"; |
|
|
|
import { ModalFormInput, PurchaseQcResult, StockInLineEntry, updateStockInLine, PurchaseQCInput, printQrCodeForSil, PrintQrCodeForSilRequest } from "@/app/api/po/actions"; |
|
|
|
import { QcItemWithChecks, QcData } from "@/app/api/qc"; |
|
|
|
import { |
|
|
|
Autocomplete, |
|
|
|
Box, |
|
|
|
Button, |
|
|
|
Grid, |
|
|
|
Modal, |
|
|
|
ModalProps, |
|
|
|
Stack, |
|
|
|
TextField, |
|
|
|
Typography, |
|
|
|
} from "@mui/material"; |
|
|
|
import { Dispatch, SetStateAction, useCallback, useEffect, useMemo, useState } from "react"; |
|
|
|
import { FormProvider, SubmitErrorHandler, SubmitHandler, useForm } from "react-hook-form"; |
|
|
|
import { StockInLineRow } from "./PoInputGrid"; |
|
|
|
import { useTranslation } from "react-i18next"; |
|
|
|
import StockInForm from "./StockInForm"; |
|
|
|
import QcComponent from "./QcComponent"; |
|
|
|
import { dummyPutAwayLine, dummyQCData } from "./dummyQcTemplate"; |
|
|
|
import PutAwayForm from "./PutAwayForm"; |
|
|
|
import { GridRowModes, GridRowSelectionModel, useGridApiRef } from "@mui/x-data-grid"; |
|
|
|
import {submitDialogWithWarning} from "../Swal/CustomAlerts"; |
|
|
|
import { INPUT_DATE_FORMAT, arrayToDateString, dayjsToInputDateString } from "@/app/utils/formatUtil"; |
|
|
|
import dayjs from "dayjs"; |
|
|
|
import { fetchPoQrcode } from "@/app/api/pdf/actions"; |
|
|
|
import { downloadFile } from "@/app/utils/commonUtil"; |
|
|
|
import { PrinterCombo } from "@/app/api/settings/printer"; |
|
|
|
import { EscalationResult } from "@/app/api/escalation"; |
|
|
|
import { SessionWithTokens } from "@/config/authConfig"; |
|
|
|
import { GridRowModesModel } from "@mui/x-data-grid"; |
|
|
|
import { isEmpty } from "lodash"; |
|
|
|
import { EscalationCombo } from "@/app/api/user"; |
|
|
|
import { truncateSync } from "fs"; |
|
|
|
|
|
|
|
|
|
|
|
const style = { |
|
|
|
position: "absolute", |
|
|
|
top: "50%", |
|
|
|
left: "50%", |
|
|
|
transform: "translate(-50%, -50%)", |
|
|
|
bgcolor: "background.paper", |
|
|
|
pt: 5, |
|
|
|
px: 5, |
|
|
|
pb: 10, |
|
|
|
display: "block", |
|
|
|
width: { xs: "90%", sm: "90%", md: "90%" }, |
|
|
|
// height: { xs: "60%", sm: "60%", md: "60%" }, |
|
|
|
}; |
|
|
|
interface CommonProps extends Omit<ModalProps, "children"> { |
|
|
|
// setRows: Dispatch<SetStateAction<PurchaseOrderLine[]>>; |
|
|
|
setEntries?: Dispatch<SetStateAction<StockInLineRow[]>>; |
|
|
|
setStockInLine?: Dispatch<SetStateAction<StockInLine[]>>; |
|
|
|
itemDetail: StockInLine & { qcResult?: PurchaseQcResult[] } & { escResult?: EscalationResult[] }; |
|
|
|
setItemDetail: Dispatch< |
|
|
|
SetStateAction< |
|
|
|
| (StockInLine & { |
|
|
|
warehouseId?: number; |
|
|
|
}) |
|
|
|
| undefined |
|
|
|
> |
|
|
|
>; |
|
|
|
session: SessionWithTokens | null; |
|
|
|
qc?: QcItemWithChecks[]; |
|
|
|
warehouse?: any[]; |
|
|
|
// type: "qc" | "stockIn" | "escalation" | "putaway" | "reject"; |
|
|
|
handleMailTemplateForStockInLine: (stockInLineId: number) => void; |
|
|
|
printerCombo: PrinterCombo[]; |
|
|
|
onClose: () => void; |
|
|
|
} |
|
|
|
interface Props extends CommonProps { |
|
|
|
itemDetail: StockInLine & { qcResult?: PurchaseQcResult[] } & { escResult?: EscalationResult[] }; |
|
|
|
} |
|
|
|
const PoQcStockInModalVer2: React.FC<Props> = ({ |
|
|
|
// type, |
|
|
|
// setRows, |
|
|
|
setEntries, |
|
|
|
setStockInLine, |
|
|
|
open, |
|
|
|
onClose, |
|
|
|
itemDetail, |
|
|
|
setItemDetail, |
|
|
|
session, |
|
|
|
qc, |
|
|
|
warehouse, |
|
|
|
handleMailTemplateForStockInLine, |
|
|
|
printerCombo, |
|
|
|
}) => { |
|
|
|
const { |
|
|
|
t, |
|
|
|
i18n: { language }, |
|
|
|
} = useTranslation("purchaseOrder"); |
|
|
|
|
|
|
|
// Select Printer |
|
|
|
const [selectedPrinter, setSelectedPrinter] = useState(printerCombo[0]); |
|
|
|
|
|
|
|
const defaultNewValue = useMemo(() => { |
|
|
|
return ( |
|
|
|
{ |
|
|
|
...itemDetail, |
|
|
|
status: itemDetail.status ?? "pending", |
|
|
|
dnDate: arrayToDateString(itemDetail.dnDate, "input")?? dayjsToInputDateString(dayjs()), |
|
|
|
// putAwayLines: dummyPutAwayLine, |
|
|
|
// putAwayLines: itemDetail.putAwayLines.map((line) => (return {...line, printQty: 1})) ?? [], |
|
|
|
putAwayLines: itemDetail.putAwayLines?.map((line) => ({...line, printQty: 1, _isNew: false, _disableDelete: true})) ?? [], |
|
|
|
// qcResult: (itemDetail.qcResult && itemDetail.qcResult?.length > 0) ? itemDetail.qcResult : [],//[...dummyQCData], |
|
|
|
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 ? arrayToDateString(itemDetail.receiptDate, "input") |
|
|
|
: dayjs().add(0, "month").format(INPUT_DATE_FORMAT), |
|
|
|
acceptQty: itemDetail.demandQty?? itemDetail.acceptedQty, |
|
|
|
warehouseId: itemDetail.defaultWarehouseId ?? 1, |
|
|
|
} |
|
|
|
) |
|
|
|
},[itemDetail]) |
|
|
|
|
|
|
|
const [qcItems, setQcItems] = useState(dummyQCData) |
|
|
|
const formProps = useForm<ModalFormInput>({ |
|
|
|
defaultValues: { |
|
|
|
...defaultNewValue, |
|
|
|
}, |
|
|
|
}); |
|
|
|
|
|
|
|
const closeHandler = useCallback<NonNullable<ModalProps["onClose"]>>( |
|
|
|
() => { |
|
|
|
onClose?.(); |
|
|
|
// reset(); |
|
|
|
}, |
|
|
|
[onClose], |
|
|
|
); |
|
|
|
|
|
|
|
const isPutaway = () => { |
|
|
|
if (itemDetail) { |
|
|
|
const status = itemDetail.status; |
|
|
|
return status == "received"; |
|
|
|
|
|
|
|
} else return false; |
|
|
|
}; |
|
|
|
|
|
|
|
const [viewOnly, setViewOnly] = useState(false); |
|
|
|
useEffect(() => { |
|
|
|
if (itemDetail && itemDetail.status) { |
|
|
|
const isViewOnly = itemDetail.status.toLowerCase() == "completed" |
|
|
|
|| itemDetail.status.toLowerCase() == "partially_completed" // TODO update DB |
|
|
|
|| itemDetail.status.toLowerCase() == "rejected" |
|
|
|
|| (itemDetail.status.toLowerCase() == "escalated" && session?.id != itemDetail.handlerId) |
|
|
|
setViewOnly(isViewOnly) |
|
|
|
} |
|
|
|
console.log("Modal ItemDetail updated:", itemDetail); |
|
|
|
}, [itemDetail]); |
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
formProps.reset({ |
|
|
|
...defaultNewValue |
|
|
|
}) |
|
|
|
|
|
|
|
setQcItems(dummyQCData); |
|
|
|
setOpenPutaway(isPutaway); |
|
|
|
|
|
|
|
}, [open]) |
|
|
|
|
|
|
|
const [openPutaway, setOpenPutaway] = useState(false); |
|
|
|
const onOpenPutaway = useCallback(() => { |
|
|
|
|
|
|
|
setOpenPutaway(true); |
|
|
|
}, []); |
|
|
|
const onClosePutaway = useCallback(() => { |
|
|
|
setOpenPutaway(false); |
|
|
|
}, []); |
|
|
|
|
|
|
|
// Stock In submission handler |
|
|
|
const onSubmitStockIn = useCallback<SubmitHandler<ModalFormInput>>( |
|
|
|
async (data, event) => { |
|
|
|
console.log("Stock In Submission:", event!.nativeEvent); |
|
|
|
// Extract only stock-in related fields |
|
|
|
const stockInData = { |
|
|
|
// quantity: data.quantity, |
|
|
|
// receiptDate: data.receiptDate, |
|
|
|
// batchNumber: data.batchNumber, |
|
|
|
// expiryDate: data.expiryDate, |
|
|
|
// warehouseId: data.warehouseId, |
|
|
|
// location: data.location, |
|
|
|
// unitCost: data.unitCost, |
|
|
|
data: data, |
|
|
|
// Add other stock-in specific fields from your form |
|
|
|
}; |
|
|
|
console.log("Stock In Data:", stockInData); |
|
|
|
// Handle stock-in submission logic here |
|
|
|
// e.g., call API, update state, etc. |
|
|
|
}, |
|
|
|
[], |
|
|
|
); |
|
|
|
|
|
|
|
// QC submission handler |
|
|
|
const onSubmitErrorQc = useCallback<SubmitErrorHandler<ModalFormInput>>( |
|
|
|
async (data, event) => { |
|
|
|
console.log("Error", data); |
|
|
|
}, [] |
|
|
|
); |
|
|
|
|
|
|
|
// QC submission handler |
|
|
|
const onSubmitQc = useCallback<SubmitHandler<ModalFormInput>>( |
|
|
|
async (data, event) => { |
|
|
|
console.log("QC Submission:", event!.nativeEvent); |
|
|
|
// TODO: Move validation into QC page |
|
|
|
|
|
|
|
// if (errors.length > 0) { |
|
|
|
// alert(`未完成品檢: ${errors.map((err) => err[1].message)}`); |
|
|
|
// return; |
|
|
|
// } |
|
|
|
|
|
|
|
// Get QC data from the shared form context |
|
|
|
const qcAccept = data.qcDecision == 1; |
|
|
|
// const qcAccept = data.qcAccept; |
|
|
|
let acceptQty = Number(data.acceptQty); |
|
|
|
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; |
|
|
|
|
|
|
|
// Validate QC data |
|
|
|
const validationErrors : string[] = []; |
|
|
|
|
|
|
|
|
|
|
|
// Check if failed items have failed quantity |
|
|
|
const failedItemsWithoutQty = qcResults.filter(item => |
|
|
|
item.qcPassed === false && (!item.failQty || item.failQty <= 0) |
|
|
|
); |
|
|
|
if (failedItemsWithoutQty.length > 0) { |
|
|
|
validationErrors.push(`${t("Failed items must have failed quantity")}`); |
|
|
|
// validationErrors.push(`${t("Failed items must have failed quantity")}: ${failedItemsWithoutQty.map(item => item.code).join(', ')}`); |
|
|
|
} |
|
|
|
|
|
|
|
// Check if QC accept decision is made |
|
|
|
if (data.qcDecision === undefined) { |
|
|
|
// if (qcAccept === undefined) { |
|
|
|
validationErrors.push(t("QC decision is required")); |
|
|
|
} |
|
|
|
|
|
|
|
// Check if accept quantity is valid |
|
|
|
if (data.qcDecision == 2) { |
|
|
|
acceptQty = 0; |
|
|
|
} else { |
|
|
|
if (acceptQty === undefined || acceptQty <= 0) { |
|
|
|
validationErrors.push("Accept quantity must be greater than 0"); |
|
|
|
} |
|
|
|
} |
|
|
|
// Check if dates are input |
|
|
|
if (data.productionDate === undefined || data.productionDate == null) { |
|
|
|
alert("請輸入生產日期!"); |
|
|
|
return; |
|
|
|
} |
|
|
|
if (data.expiryDate === undefined || data.expiryDate == null) { |
|
|
|
alert("請輸入到期日!"); |
|
|
|
return; |
|
|
|
} |
|
|
|
if (!qcResults.every((qc) => qc.qcPassed) && qcAccept && itemDetail.status != "escalated") { //TODO: fix it please! |
|
|
|
validationErrors.push("有不合格檢查項目,無法收貨!"); |
|
|
|
// submitDialogWithWarning(() => postStockInLineWithQc(qcData), t, {title:"有不合格檢查項目,確認接受收貨?", |
|
|
|
// confirmButtonText: t("confirm putaway"), html: ""}); |
|
|
|
// return; |
|
|
|
} |
|
|
|
|
|
|
|
// Check if all QC items have results |
|
|
|
const itemsWithoutResult = qcResults.filter(item => item.qcPassed === undefined); |
|
|
|
|
|
|
|
if (itemsWithoutResult.length > 0 && itemDetail.status != "escalated") { //TODO: fix it please! |
|
|
|
validationErrors.push(`${t("QC items without result")}`); |
|
|
|
// validationErrors.push(`${t("QC items without result")}: ${itemsWithoutResult.map(item => item.code).join(', ')}`); |
|
|
|
} |
|
|
|
|
|
|
|
if (validationErrors.length > 0) { |
|
|
|
console.error("QC Validation failed:", validationErrors); |
|
|
|
alert(`未完成品檢: ${validationErrors}`); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
const qcData = { |
|
|
|
dnNo : data.dnNo? data.dnNo : "DN00000", |
|
|
|
dnDate : data.dnDate? arrayToDateString(data.dnDate, "input") : dayjsToInputDateString(dayjs()), |
|
|
|
productionDate : arrayToDateString(data.productionDate, "input"), |
|
|
|
expiryDate : arrayToDateString(data.expiryDate, "input"), |
|
|
|
receiptDate : arrayToDateString(data.receiptDate, "input"), |
|
|
|
|
|
|
|
qcAccept: qcAccept? qcAccept : false, |
|
|
|
acceptQty: acceptQty? acceptQty : 0, |
|
|
|
// 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 || '', |
|
|
|
})), |
|
|
|
}; |
|
|
|
// const qcData = data; |
|
|
|
|
|
|
|
console.log("QC Data for submission:", qcData); |
|
|
|
if (data.qcDecision == 3) { // Escalate |
|
|
|
if (data.escalationLog?.handlerId == undefined) { alert("請選擇上報負責同事!"); return; } |
|
|
|
else if (data.escalationLog?.handlerId < 1) { alert("上報負責同事資料有誤"); return; } |
|
|
|
|
|
|
|
const escalationLog = { |
|
|
|
type : "qc", |
|
|
|
status : "pending", // TODO: update with supervisor decision |
|
|
|
reason : data.escalationLog?.reason, |
|
|
|
recordDate : dayjsToInputDateString(dayjs()), |
|
|
|
handlerId : data.escalationLog?.handlerId, |
|
|
|
} |
|
|
|
console.log("Escalation Data for submission", escalationLog); |
|
|
|
await postStockInLine({...qcData, escalationLog}); |
|
|
|
|
|
|
|
} else { |
|
|
|
await postStockInLine(qcData); |
|
|
|
} |
|
|
|
|
|
|
|
if (qcData.qcAccept) { |
|
|
|
// submitDialogWithWarning(onOpenPutaway, t, {title:"Save success, confirm to proceed?", |
|
|
|
// confirmButtonText: t("confirm putaway"), html: ""}); |
|
|
|
onOpenPutaway(); |
|
|
|
} else { |
|
|
|
closeHandler({}, "backdropClick"); |
|
|
|
} |
|
|
|
return ; |
|
|
|
|
|
|
|
}, |
|
|
|
[onOpenPutaway, qcItems, formProps.formState.errors], |
|
|
|
); |
|
|
|
|
|
|
|
const postStockInLine = useCallback(async (args: ModalFormInput) => { |
|
|
|
const submitData = { |
|
|
|
...itemDetail, ...args |
|
|
|
} as StockInLineEntry & ModalFormInput; |
|
|
|
console.log("Submitting", submitData); |
|
|
|
|
|
|
|
const res = await updateStockInLine(submitData); |
|
|
|
return res; |
|
|
|
},[itemDetail]) |
|
|
|
|
|
|
|
// Email supplier handler |
|
|
|
const onSubmitEmailSupplier = useCallback<SubmitHandler<ModalFormInput>>( |
|
|
|
async (data, event) => { |
|
|
|
console.log("Email Supplier Submission:", event!.nativeEvent); |
|
|
|
// Extract only email supplier related fields |
|
|
|
const emailData = { |
|
|
|
// supplierEmail: data.supplierEmail, |
|
|
|
// issueDescription: data.issueDescription, |
|
|
|
// qcComments: data.qcComments, |
|
|
|
// defectNotes: data.defectNotes, |
|
|
|
// attachments: data.attachments, |
|
|
|
// escalationReason: data.escalationReason, |
|
|
|
data: data, |
|
|
|
|
|
|
|
// Add other email-specific fields |
|
|
|
}; |
|
|
|
console.log("Email Supplier Data:", emailData); |
|
|
|
// Handle email supplier logic here |
|
|
|
// e.g., send email to supplier, log escalation, etc. |
|
|
|
}, |
|
|
|
[], |
|
|
|
); |
|
|
|
|
|
|
|
// Put away model |
|
|
|
const [pafRowModesModel, setPafRowModesModel] = useState<GridRowModesModel>({}) |
|
|
|
const [pafRowSelectionModel, setPafRowSelectionModel] = useState<GridRowSelectionModel>([]) |
|
|
|
const pafSubmitDisable = useMemo(() => { |
|
|
|
// console.log("%c mode: ", "background:#90EE90; color:red", Object.entries(pafRowModesModel)) |
|
|
|
// console.log("%c mode: ", "background:pink; color:#87CEEB", Object.entries(pafRowModesModel)) |
|
|
|
return Object.entries(pafRowModesModel).length > 0 || Object.entries(pafRowModesModel).some(([key, value], index) => value.mode === GridRowModes.Edit) |
|
|
|
}, [pafRowModesModel]) |
|
|
|
// Putaway submission handler |
|
|
|
const onSubmitPutaway = useCallback<SubmitHandler<ModalFormInput>>( |
|
|
|
async (data, event) => { |
|
|
|
// console.log("Putaway Submission:", event!.nativeEvent); |
|
|
|
// console.log(data.putAwayLines) |
|
|
|
// console.log(data.putAwayLines?.filter((line) => line._isNew !== false)) |
|
|
|
// Extract only putaway related fields |
|
|
|
const putawayData = { |
|
|
|
// putawayLine: data.putawayLine, |
|
|
|
// putawayLocation: data.putawayLocation, |
|
|
|
// binLocation: data.binLocation, |
|
|
|
// putawayQuantity: data.putawayQuantity, |
|
|
|
// putawayNotes: data.putawayNotes, |
|
|
|
acceptQty: Number(data.acceptQty?? (itemDetail.demandQty?? (itemDetail.acceptedQty))), //TODO improve |
|
|
|
warehouseId: data.warehouseId, |
|
|
|
status: data.status, //TODO Fix it! |
|
|
|
// ...data, |
|
|
|
|
|
|
|
dnDate : data.dnDate? arrayToDateString(data.dnDate, "input") : dayjsToInputDateString(dayjs()), |
|
|
|
productionDate : arrayToDateString(data.productionDate, "input"), |
|
|
|
expiryDate : arrayToDateString(data.expiryDate, "input"), |
|
|
|
receiptDate : arrayToDateString(data.receiptDate, "input"), |
|
|
|
|
|
|
|
// for putaway data |
|
|
|
inventoryLotLines: data.putAwayLines?.filter((line) => line._isNew !== false) |
|
|
|
|
|
|
|
// Add other putaway specific fields |
|
|
|
} as ModalFormInput; |
|
|
|
console.log("Putaway Data:", putawayData); |
|
|
|
|
|
|
|
console.log("DEBUG",data.putAwayLines); |
|
|
|
if (data.putAwayLines!!.filter((line) => line._isNew !== false).length <= 0) { |
|
|
|
alert("請新增上架資料!"); |
|
|
|
return; |
|
|
|
} |
|
|
|
if (data.putAwayLines!!.filter((line) => /[^0-9]/.test(String(line.qty))).length > 0) { //TODO Improve |
|
|
|
alert("上架數量不正確!"); |
|
|
|
return; |
|
|
|
} |
|
|
|
if (data.putAwayLines!!.reduce((acc, cur) => acc + Number(cur.qty), 0) > putawayData.acceptQty!!) { |
|
|
|
alert(`上架數量不能大於 ${putawayData.acceptQty}!`); |
|
|
|
return; |
|
|
|
} |
|
|
|
// Handle putaway submission logic here |
|
|
|
const res = await postStockInLine(putawayData); |
|
|
|
console.log("result ", res); |
|
|
|
|
|
|
|
// Close modal after successful putaway |
|
|
|
closeHandler({}, "backdropClick"); |
|
|
|
}, |
|
|
|
[closeHandler], |
|
|
|
); |
|
|
|
// Print handler |
|
|
|
const [isPrinting, setIsPrinting] = useState(false) |
|
|
|
const handlePrint = useCallback(async () => { |
|
|
|
// console.log("Print putaway documents"); |
|
|
|
console.log("%c data", "background: white; color: red", formProps.watch("putAwayLines")); |
|
|
|
// Handle print logic here |
|
|
|
// window.print(); |
|
|
|
// const postData = { stockInLineIds: [itemDetail.id]}; |
|
|
|
// const response = await fetchPoQrcode(postData); |
|
|
|
// if (response) { |
|
|
|
// downloadFile(new Uint8Array(response.blobValue), response.filename) |
|
|
|
// } |
|
|
|
try { |
|
|
|
setIsPrinting(() => true) |
|
|
|
if ((formProps.watch("putAwayLines") ?? []).filter((line) => /[^0-9]/.test(String(line.printQty))).length > 0) { //TODO Improve |
|
|
|
alert("列印數量不正確!"); |
|
|
|
return; |
|
|
|
} |
|
|
|
// console.log(pafRowSelectionModel) |
|
|
|
const printList = formProps.watch("putAwayLines")?.filter((line) => ((pafRowSelectionModel ?? []).some((model) => model === line.id))) ?? [] |
|
|
|
const printQty = printList.reduce((acc, cur) => acc + cur.printQty, 0) |
|
|
|
// console.log(printQty) |
|
|
|
const data: PrintQrCodeForSilRequest = { |
|
|
|
stockInLineId: itemDetail.id, |
|
|
|
printerId: selectedPrinter.id, |
|
|
|
printQty: printQty |
|
|
|
} |
|
|
|
const response = await printQrCodeForSil(data); |
|
|
|
if (response) { |
|
|
|
console.log(response) |
|
|
|
} |
|
|
|
} finally { |
|
|
|
setIsPrinting(() => false) |
|
|
|
} |
|
|
|
}, [itemDetail.id, pafRowSelectionModel]); |
|
|
|
|
|
|
|
const acceptQty = formProps.watch("acceptedQty") |
|
|
|
|
|
|
|
const checkQcIsPassed = useCallback((qcItems: PurchaseQcResult[]) => { |
|
|
|
const isPassed = qcItems.every((qc) => qc.qcPassed); |
|
|
|
console.log(isPassed) |
|
|
|
if (isPassed) { |
|
|
|
formProps.setValue("passingQty", acceptQty) |
|
|
|
} else { |
|
|
|
formProps.setValue("passingQty", 0) |
|
|
|
} |
|
|
|
return isPassed |
|
|
|
}, [acceptQty, formProps]) |
|
|
|
|
|
|
|
// useEffect(() => { |
|
|
|
// // maybe check if submitted before |
|
|
|
// console.log("Modal QC Items updated:", qcItems); |
|
|
|
// // checkQcIsPassed(qcItems) |
|
|
|
// }, [qcItems, checkQcIsPassed]) |
|
|
|
|
|
|
|
return ( |
|
|
|
<> |
|
|
|
<FormProvider {...formProps}> |
|
|
|
<Modal open={open} onClose={closeHandler}> |
|
|
|
<Box |
|
|
|
sx={{ |
|
|
|
...style, |
|
|
|
padding: 2, |
|
|
|
maxHeight: "90vh", |
|
|
|
overflowY: "auto", |
|
|
|
marginLeft: 3, |
|
|
|
marginRight: 3, |
|
|
|
}} |
|
|
|
> |
|
|
|
{openPutaway ? ( |
|
|
|
<Box |
|
|
|
component="form" |
|
|
|
onSubmit={formProps.handleSubmit(onSubmitPutaway)} |
|
|
|
> |
|
|
|
<PutAwayForm |
|
|
|
itemDetail={itemDetail} |
|
|
|
warehouse={warehouse!} |
|
|
|
disabled={viewOnly} |
|
|
|
setRowModesModel={setPafRowModesModel} |
|
|
|
setRowSelectionModel={setPafRowSelectionModel} |
|
|
|
/> |
|
|
|
<Stack direction="row" justifyContent="flex-end" gap={1}> |
|
|
|
<Autocomplete |
|
|
|
disableClearable |
|
|
|
options={printerCombo} |
|
|
|
defaultValue={selectedPrinter} |
|
|
|
onChange={(event, value) => { |
|
|
|
setSelectedPrinter(value) |
|
|
|
}} |
|
|
|
renderInput={(params) => ( |
|
|
|
<TextField |
|
|
|
{...params} |
|
|
|
variant="outlined" |
|
|
|
label={t("Printer")} |
|
|
|
sx={{ width: 300}} |
|
|
|
/> |
|
|
|
)} |
|
|
|
/> |
|
|
|
<Button |
|
|
|
id="printButton" |
|
|
|
type="button" |
|
|
|
variant="contained" |
|
|
|
color="primary" |
|
|
|
sx={{ mt: 1 }} |
|
|
|
onClick={handlePrint} |
|
|
|
disabled={isPrinting || printerCombo.length <= 0 || pafSubmitDisable} |
|
|
|
> |
|
|
|
{isPrinting ? t("Printing") : t("print")} |
|
|
|
</Button> |
|
|
|
<Button |
|
|
|
id="putawaySubmit" |
|
|
|
type="submit" |
|
|
|
variant="contained" |
|
|
|
color="primary" |
|
|
|
sx={{ mt: 1 }} |
|
|
|
onClick={formProps.handleSubmit(onSubmitPutaway)} |
|
|
|
disabled={pafSubmitDisable} |
|
|
|
> |
|
|
|
{t("confirm putaway")} |
|
|
|
</Button> |
|
|
|
</Stack> |
|
|
|
</Box> |
|
|
|
) : ( |
|
|
|
<> |
|
|
|
<Grid |
|
|
|
container |
|
|
|
justifyContent="flex-start" |
|
|
|
alignItems="flex-start" |
|
|
|
> |
|
|
|
<Grid item xs={12}> |
|
|
|
<Typography variant="h6" display="block" marginBlockEnd={1}> |
|
|
|
{t("qc processing")} |
|
|
|
</Typography> |
|
|
|
</Grid> |
|
|
|
<Grid item xs={12}> |
|
|
|
<StockInForm itemDetail={itemDetail} disabled={viewOnly} /> |
|
|
|
</Grid> |
|
|
|
</Grid> |
|
|
|
{/* <Stack direction="row" justifyContent="flex-end" gap={1}> |
|
|
|
<Button |
|
|
|
id="stockInSubmit" |
|
|
|
type="button" |
|
|
|
variant="contained" |
|
|
|
color="primary" |
|
|
|
onClick={formProps.handleSubmit(onSubmitStockIn)} |
|
|
|
> |
|
|
|
{t("submitStockIn")} |
|
|
|
</Button> |
|
|
|
</Stack> */} |
|
|
|
<Grid |
|
|
|
container |
|
|
|
justifyContent="flex-start" |
|
|
|
alignItems="flex-start" |
|
|
|
> |
|
|
|
<QcComponent |
|
|
|
// qc={qc!} |
|
|
|
itemDetail={itemDetail} |
|
|
|
disabled={viewOnly} |
|
|
|
// qcItems={qcItems} |
|
|
|
// setQcItems={setQcItems} |
|
|
|
/> |
|
|
|
</Grid> |
|
|
|
<Stack direction="row" justifyContent="flex-end" gap={1}> |
|
|
|
{!viewOnly && (<Button |
|
|
|
id="qcSubmit" |
|
|
|
type="button" |
|
|
|
variant="contained" |
|
|
|
color="primary" |
|
|
|
sx={{ mt: 1 }} |
|
|
|
onClick={formProps.handleSubmit(onSubmitQc, onSubmitErrorQc)} |
|
|
|
> |
|
|
|
{t("confirm qc result")} |
|
|
|
</Button>)} |
|
|
|
</Stack> |
|
|
|
</> |
|
|
|
)} |
|
|
|
</Box> |
|
|
|
</Modal> |
|
|
|
</FormProvider> |
|
|
|
</> |
|
|
|
); |
|
|
|
}; |
|
|
|
export default PoQcStockInModalVer2; |