From 871a6d46a769cbe9e87146434f4bcb2d6792ab81 Mon Sep 17 00:00:00 2001 From: dujinkim Date: Thu, 30 Oct 2025 10:44:47 +0000 Subject: (최겸) 구매 PQ/실사 재개발(테스트 필요), 정규업체등록 결재 개발, 실사 의뢰 결재 후처리 등 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/approval/handlers-registry.ts | 7 +- lib/mail/templates/pq-approved-vendor.hbs | 7 +- .../pq-investigation-supplement-request.hbs | 54 ++ lib/mail/templates/pq-rejected-vendor.hbs | 7 +- lib/mail/templates/pq-submitted-vendor.hbs | 9 +- lib/mail/templates/pq-supplement-request.hbs | 56 ++ .../edit-investigation-dialog.tsx | 6 +- lib/pq/pq-review-table-new/site-visit-dialog.tsx | 135 +++-- .../pq-review-table-new/vendors-table-columns.tsx | 43 +- .../vendors-table-toolbar-actions.tsx | 91 +++- lib/pq/pq-review-table-new/vendors-table.tsx | 5 +- lib/pq/service.ts | 266 +++++++--- lib/site-visit/service.ts | 131 +++++ lib/site-visit/vendor-info-view-dialog.tsx | 110 +++- lib/vendor-investigation/approval-actions.ts | 1 + lib/vendor-investigation/handlers.ts | 3 + lib/vendor-investigation/service.ts | 139 ++++- .../table/investigation-cancel-plan-button.tsx | 91 ++++ .../table/investigation-progress-sheet.tsx | 14 +- .../table/investigation-result-sheet.tsx | 580 ++++++++++----------- .../table/investigation-table-columns.tsx | 60 ++- .../table/investigation-table-toolbar-actions.tsx | 4 +- lib/vendor-investigation/validations.ts | 71 ++- .../approval-actions.ts | 14 + lib/vendor-regular-registrations/handlers.ts | 56 +- lib/vendor-regular-registrations/repository.ts | 5 +- lib/vendor-regular-registrations/service.ts | 487 ++++------------- .../vendor-regular-registrations-table-columns.tsx | 19 +- ...regular-registrations-table-toolbar-actions.tsx | 5 +- .../table/vendor-regular-registrations-table.tsx | 1 - 30 files changed, 1519 insertions(+), 958 deletions(-) create mode 100644 lib/mail/templates/pq-investigation-supplement-request.hbs create mode 100644 lib/mail/templates/pq-supplement-request.hbs create mode 100644 lib/vendor-investigation/table/investigation-cancel-plan-button.tsx (limited to 'lib') diff --git a/lib/approval/handlers-registry.ts b/lib/approval/handlers-registry.ts index 1db79974..6306f811 100644 --- a/lib/approval/handlers-registry.ts +++ b/lib/approval/handlers-registry.ts @@ -1,5 +1,5 @@ /** - * 결재 액션 핸들러 중앙 등록소 + * 결재 후 실행될 액션 핸들러 중앙 등록소 * * 모든 결재 가능한 액션의 핸들러를 한 곳에서 등록 * instrumentation.ts 또는 Next.js middleware에서 import하여 초기화 @@ -20,10 +20,10 @@ export async function initializeApprovalHandlers() { reRequestPQInvestigationInternal } = await import('@/lib/vendor-investigation/handlers'); - // PQ 실사의뢰 핸들러 등록 + // PQ 실사의뢰 핸들러 등록 (결재 승인 후 실행될 함수 requestPQInvestigationInternal ) registerActionHandler('pq_investigation_request', requestPQInvestigationInternal); - // PQ 실사 재의뢰 핸들러 등록 + // PQ 실사 재의뢰 핸들러 등록 (결재 승인 후 실행될 함수 reRequestPQInvestigationInternal ) registerActionHandler('pq_investigation_rerequest', reRequestPQInvestigationInternal); // 2. 발주 요청 핸들러 @@ -32,6 +32,7 @@ export async function initializeApprovalHandlers() { // 3. 정규업체 등록 핸들러 const { registerVendorInternal } = await import('@/lib/vendor-regular-registrations/handlers'); + // 정규업체 등록 핸들러 등록 (결재 승인 후 실행될 함수 registerVendorInternal ) registerActionHandler('vendor_regular_registration', registerVendorInternal); // 4. 계약 승인 핸들러 diff --git a/lib/mail/templates/pq-approved-vendor.hbs b/lib/mail/templates/pq-approved-vendor.hbs index 1ded76ef..e357958a 100644 --- a/lib/mail/templates/pq-approved-vendor.hbs +++ b/lib/mail/templates/pq-approved-vendor.hbs @@ -97,11 +97,12 @@ -
- +

+ 협력업체 포털로 이동 -

+

diff --git a/lib/mail/templates/pq-investigation-supplement-request.hbs b/lib/mail/templates/pq-investigation-supplement-request.hbs new file mode 100644 index 00000000..c869b2bd --- /dev/null +++ b/lib/mail/templates/pq-investigation-supplement-request.hbs @@ -0,0 +1,54 @@ + + + + + + + 실사 보완요청 + + + +

+

실사 보완요청 안내

+

eVCP 실사 시스템에서 실사 보완요청이 접수되었습니다.

+ +
+
협력업체
+
{{vendorName}}
+ +
실사 번호
+
{{investigationNumber}}
+ +
보완 내용
+
{{supplementComment}}
+ +
요청일
+
{{requestedAt}}
+
+ +
+ 실사 확인 및 보완하기 +
+ +

+ 위 보완 사항을 확인하시고, 시스템에서 필요한 자료를 제출해 주시기 바랍니다.
+ 추가 문의사항이 있으시면 담당자에게 연락 부탁드립니다. +

+ + +
+ + diff --git a/lib/mail/templates/pq-rejected-vendor.hbs b/lib/mail/templates/pq-rejected-vendor.hbs index 3cb8aea6..f75e9037 100644 --- a/lib/mail/templates/pq-rejected-vendor.hbs +++ b/lib/mail/templates/pq-rejected-vendor.hbs @@ -114,11 +114,12 @@ -
- +

+ 협력업체 포털로 이동 -

+

diff --git a/lib/mail/templates/pq-submitted-vendor.hbs b/lib/mail/templates/pq-submitted-vendor.hbs index 0d35c33b..8e40334a 100644 --- a/lib/mail/templates/pq-submitted-vendor.hbs +++ b/lib/mail/templates/pq-submitted-vendor.hbs @@ -57,10 +57,11 @@ 대시보드에 접속하여 제출 상태를 확인하고 업체 프로필을 관리하실 수 있습니다.

-

- - 협력업체 포털로 이동 - +

+ + 협력업체 포털로 이동 +

diff --git a/lib/mail/templates/pq-supplement-request.hbs b/lib/mail/templates/pq-supplement-request.hbs new file mode 100644 index 00000000..68ea64f6 --- /dev/null +++ b/lib/mail/templates/pq-supplement-request.hbs @@ -0,0 +1,56 @@ + + + + + + + PQ 보완요청 + + + +
+

[eVCP] PQ 보완요청 안내

+ +

+ 안녕하세요, {{vendorName}} 담당자님.
+ 아래 PQ에 대해 보완 요청 사항이 접수되었습니다. +

+ +
+
PQ 번호
+
{{pqNumber}}
+
+ +
+
보완 요청 내용
+
{{comment}}
+
+ + {{#if reviewUrl}} +

+ PQ 확인 및 수정하기 +

+ {{/if}} + +

+ 본 메일은 시스템에서 자동 발송되었습니다. 문의가 필요하신 경우 회신 또는 담당자에게 연락해 주세요. +

+ + +
+ + + + diff --git a/lib/pq/pq-review-table-new/edit-investigation-dialog.tsx b/lib/pq/pq-review-table-new/edit-investigation-dialog.tsx index c4057798..8e139b79 100644 --- a/lib/pq/pq-review-table-new/edit-investigation-dialog.tsx +++ b/lib/pq/pq-review-table-new/edit-investigation-dialog.tsx @@ -51,7 +51,7 @@ const editInvestigationSchema = z.object({ z.string().transform((str) => str ? new Date(str) : undefined) ]).optional(), evaluationResult: z.enum(["APPROVED", "SUPPLEMENT", "REJECTED"]).optional(), - investigationNotes: z.string().max(1000, "QM 의견은 1000자 이내로 입력해주세요.").optional(), + investigationNotes: z.string().max(1000, "구매 의견은 1000자 이내로 입력해주세요.").optional(), attachments: z.array(z.instanceof(File)).optional(), }) @@ -210,9 +210,9 @@ export function EditInvestigationDialog({ - 실사 정보 수정 + 구매자체평가 실사 결과 수정 - 구매자체평가 실사 정보를 수정합니다. + 구매자체평가 실사 결과를 수정합니다. diff --git a/lib/pq/pq-review-table-new/site-visit-dialog.tsx b/lib/pq/pq-review-table-new/site-visit-dialog.tsx index 2b65d03e..b1474150 100644 --- a/lib/pq/pq-review-table-new/site-visit-dialog.tsx +++ b/lib/pq/pq-review-table-new/site-visit-dialog.tsx @@ -140,6 +140,7 @@ interface SiteVisitDialogProps { projectCode?: string pqItems?: Array<{itemCode: string, itemName: string}> | null } + isReinspection?: boolean // 재실사 모드 플래그 } export function SiteVisitDialog({ @@ -147,6 +148,7 @@ export function SiteVisitDialog({ onClose, onSubmit, investigation, + isReinspection = false, }: SiteVisitDialogProps) { const [isPending, setIsPending] = React.useState(false) const [selectedFiles, setSelectedFiles] = React.useState([]) @@ -184,58 +186,88 @@ export function SiteVisitDialog({ }, }) - // Dialog가 열릴 때마다 폼 재설정 및 기존 요청 확인 + // Dialog가 열릴 때마다 폼 재설정 및 기존 요청 로딩 React.useEffect(() => { if (isOpen) { - // 기존 방문실사 요청이 있는지 확인 - const checkExistingRequest = async () => { + const loadExistingRequest = async () => { try { + // 기존 방문실사 요청이 있는지 확인하고 최신 것을 로드 const existingRequest = await getSiteVisitRequestAction(investigation.id) - + if (existingRequest.success && existingRequest.data) { - toast.error("이미 방문실사 요청이 존재합니다. 추가 요청은 불가능합니다.") - onClose() + // 기존 데이터를 form에 로드 + const data = existingRequest.data + form.reset({ + inspectionDuration: data.inspectionDuration || 1.0, + requestedStartDate: data.requestedStartDate ? new Date(data.requestedStartDate) : undefined, + requestedEndDate: data.requestedEndDate ? new Date(data.requestedEndDate) : undefined, + shiAttendees: data.shiAttendees || { + technicalSales: { checked: false, count: 0, details: "" }, + design: { checked: false, count: 0, details: "" }, + procurement: { checked: false, count: 0, details: "" }, + quality: { checked: false, count: 0, details: "" }, + production: { checked: false, count: 0, details: "" }, + commissioning: { checked: false, count: 0, details: "" }, + other: { checked: false, count: 0, details: "" }, + }, + shiAttendeeDetails: data.shiAttendeeDetails || "", + vendorRequests: data.vendorRequests || { + availableDates: false, + factoryName: false, + factoryLocation: false, + factoryAddress: false, + factoryPicName: false, + factoryPicPhone: false, + factoryPicEmail: false, + factoryDirections: false, + accessProcedure: false, + other: false, + }, + otherVendorRequests: data.otherVendorRequests || "", + additionalRequests: data.additionalRequests || "", + }) return } + + // 기본값으로 폼 초기화 (기존 요청이 없는 경우) + form.reset({ + inspectionDuration: 1.0, + requestedStartDate: undefined, + requestedEndDate: undefined, + shiAttendees: { + technicalSales: { checked: false, count: 0, details: "" }, + design: { checked: false, count: 0, details: "" }, + procurement: { checked: false, count: 0, details: "" }, + quality: { checked: false, count: 0, details: "" }, + production: { checked: false, count: 0, details: "" }, + commissioning: { checked: false, count: 0, details: "" }, + other: { checked: false, count: 0, details: "" }, + }, + shiAttendeeDetails: "", + vendorRequests: { + availableDates: false, + factoryName: false, + factoryLocation: false, + factoryAddress: false, + factoryPicName: false, + factoryPicPhone: false, + factoryPicEmail: false, + factoryDirections: false, + accessProcedure: false, + other: false, + }, + otherVendorRequests: "", + additionalRequests: "", + }) } catch (error) { - console.error("방문실사 요청 상태 확인 중 오류:", error) - toast.error("방문실사 요청 상태 확인 중 오류가 발생했습니다.") + console.error("방문실사 요청 데이터 로드 중 오류:", error) + toast.error("방문실사 요청 데이터 로드 중 오류가 발생했습니다.") onClose() return } } - - checkExistingRequest() - - form.reset({ - inspectionDuration: 1.0, - requestedStartDate: undefined, - requestedEndDate: undefined, - shiAttendees: { - technicalSales: { checked: false, count: 0, details: "" }, - design: { checked: false, count: 0, details: "" }, - procurement: { checked: false, count: 0, details: "" }, - quality: { checked: false, count: 0, details: "" }, - production: { checked: false, count: 0, details: "" }, - commissioning: { checked: false, count: 0, details: "" }, - other: { checked: false, count: 0, details: "" }, - }, - shiAttendeeDetails: "", - vendorRequests: { - availableDates: false, - factoryName: false, - factoryLocation: false, - factoryAddress: false, - factoryPicName: false, - factoryPicPhone: false, - factoryPicEmail: false, - factoryDirections: false, - accessProcedure: false, - other: false, - }, - otherVendorRequests: "", - additionalRequests: "", - }) + + loadExistingRequest() setSelectedFiles([]) } }, [isOpen, form, investigation.id, onClose]) @@ -243,19 +275,11 @@ export function SiteVisitDialog({ async function handleSubmit(data: SiteVisitRequestFormValues) { setIsPending(true) try { - // 제출 전에 한 번 더 기존 요청이 있는지 확인 - const existingRequest = await getSiteVisitRequestAction(investigation.id) - - if (existingRequest.success && existingRequest.data) { - toast.error("이미 방문실사 요청이 존재합니다. 추가 요청은 불가능합니다.") - onClose() - return - } - + await onSubmit(data, selectedFiles) - toast.success("방문실사 요청이 성공적으로 발송되었습니다.") + toast.success(isReinspection ? "재실사 요청이 성공적으로 발송되었습니다." : "방문실사 요청이 성공적으로 발송되었습니다.") } catch (error) { - toast.error("방문실사 요청 발송 중 오류가 발생했습니다.") + toast.error(isReinspection ? "재실사 요청 발송 중 오류가 발생했습니다." : "방문실사 요청 발송 중 오류가 발생했습니다.") console.error("방문실사 요청 오류:", error) } finally { setIsPending(false) @@ -294,9 +318,12 @@ export function SiteVisitDialog({ !open && onClose()}> - 방문실사 요청 생성 + {isReinspection ? "재실사 요청 생성" : "방문실사 요청 생성"} - 협력업체에 방문실사 요청을 생성하고, 협력업체가 입력할 정보 항목을 설정합니다. + {isReinspection + ? "협력업체에 재실사 요청을 생성하고, 협력업체가 입력할 정보 항목을 설정합니다." + : "협력업체에 방문실사 요청을 생성하고, 협력업체가 입력할 정보 항목을 설정합니다." + } @@ -710,7 +737,7 @@ export function SiteVisitDialog({ 취소 diff --git a/lib/pq/pq-review-table-new/vendors-table-columns.tsx b/lib/pq/pq-review-table-new/vendors-table-columns.tsx index b4d7d038..3e10177d 100644 --- a/lib/pq/pq-review-table-new/vendors-table-columns.tsx +++ b/lib/pq/pq-review-table-new/vendors-table-columns.tsx @@ -75,6 +75,7 @@ export interface PQSubmission { qmManagerEmail: string | null // QM 담당자 이메일 investigationAddress: string | null investigationMethod: string | null + hasSupplementRequested: boolean scheduledStartAt: Date | null scheduledEndAt: Date | null requestedAt: Date | null @@ -100,24 +101,6 @@ interface GetColumnsProps { router: NextRouter; } -// 상태에 따른 Badge 변형 결정 함수 -function getStatusBadge(status: string) { - switch (status) { - case "REQUESTED": - return 요청됨 - case "IN_PROGRESS": - return 진행 중 - case "SUBMITTED": - return 제출됨 - case "APPROVED": - return 승인됨 - case "REJECTED": - return 거부됨 - default: - return {status} - } -} - /** * tanstack table 컬럼 정의 */ @@ -285,15 +268,15 @@ export function getColumns({ setRowAction, router }: GetColumnsProps): ExtendedC const combinedStatus = getCombinedStatus(row.original); return value.includes(combinedStatus.status); }, - enableSorting: true, + enableSorting: false, enableHiding: true, excelHeader: "진행현황", }; // PQ 상태와 실사 상태를 결합하는 헬퍼 함수 function getCombinedStatus(submission: PQSubmission) { - // PQ가 승인되지 않은 경우, PQ 상태를 우선 표시 - if (submission.status !== "APPROVED") { + // PQ가 QM 승인되지 않은 경우, PQ 상태를 우선 표시 + if (submission.status !== "QM_APPROVED") { switch (submission.status) { case "REQUESTED": return { status: "PQ_REQUESTED", label: "PQ 요청됨", variant: "outline" as const }; @@ -301,22 +284,30 @@ export function getColumns({ setRowAction, router }: GetColumnsProps): ExtendedC return { status: "PQ_IN_PROGRESS", label: "PQ 진행 중", variant: "secondary" as const }; case "SUBMITTED": return { status: "PQ_SUBMITTED", label: "PQ 제출됨", variant: "default" as const }; + case "APPROVED": + return { status: "PQ_APPROVED", label: "PQ 승인됨", variant: "success" as const }; case "REJECTED": return { status: "PQ_REJECTED", label: "PQ 거부됨", variant: "destructive" as const }; + case "QM_REVIEWING": + return { status: "PQ_QM_REVIEWING", label: "QM 검토 중", variant: "secondary" as const }; + case "QM_REJECTED": + return { status: "PQ_QM_REJECTED", label: "QM 거부됨", variant: "destructive" as const }; default: return { status: submission.status, label: submission.status, variant: "outline" as const }; } } - // PQ가 승인되었지만 실사가 없는 경우 + // PQ가 QM 승인되었지만 실사가 없는 경우 if (!submission.investigation) { - return { status: "PQ_APPROVED", label: "PQ 승인됨", variant: "success" as const }; + return { status: "PQ_QM_APPROVED", label: "PQ 승인됨", variant: "success" as const }; } // PQ가 승인되고 실사가 있는 경우 switch (submission.investigation.investigationStatus) { case "PLANNED": return { status: "INVESTIGATION_PLANNED", label: "실사 계획됨", variant: "outline" as const }; + case "QM_REVIEW_CONFIRMED": + return { status: "INVESTIGATION_QM_REVIEW_CONFIRMED", label: "QM 검토 완료", variant: "outline" as const }; case "IN_PROGRESS": return { status: "INVESTIGATION_IN_PROGRESS", label: "실사 진행 중", variant: "secondary" as const }; case "COMPLETED": @@ -343,6 +334,10 @@ export function getColumns({ setRowAction, router }: GetColumnsProps): ExtendedC case "SUPPLEMENT_REQUIRED": return { status: "INVESTIGATION_SUPPLEMENT_REQUIRED", label: "실사 보완 요구됨", variant: "secondary" as const }; case "RESULT_SENT": + // 보완을 통해 최종 합격/불합격한 경우 + if (submission.investigation.hasSupplementRequested) { + return { status: "INVESTIGATION_RESULT_SENT_SUPPLEMENT", label: "실사 결과 발송(보완)", variant: "success" as const }; + } return { status: "INVESTIGATION_RESULT_SENT", label: "실사 결과 발송", variant: "success" as const }; default: return { @@ -761,7 +756,7 @@ export function getColumns({ setRowAction, router }: GetColumnsProps): ExtendedC }} > - 실사 정보 수정 + 구매 자체 평가 )} diff --git a/lib/pq/pq-review-table-new/vendors-table-toolbar-actions.tsx b/lib/pq/pq-review-table-new/vendors-table-toolbar-actions.tsx index ea6b6189..98b1cc76 100644 --- a/lib/pq/pq-review-table-new/vendors-table-toolbar-actions.tsx +++ b/lib/pq/pq-review-table-new/vendors-table-toolbar-actions.tsx @@ -15,6 +15,7 @@ import { getFactoryLocationAnswer, getQMManagers } from "@/lib/pq/service" +import { SiteVisitDialog } from "./site-visit-dialog" import { RequestInvestigationDialog } from "./request-investigation-dialog" import { CancelInvestigationDialog, ReRequestInvestigationDialog } from "./cancel-investigation-dialog" import { SendResultsDialog } from "./send-results-dialog" @@ -49,6 +50,7 @@ export function VendorsTableToolbarActions({ table }: VendorsTableToolbarActions const [isCancelDialogOpen, setIsCancelDialogOpen] = React.useState(false) const [isSendResultsDialogOpen, setIsSendResultsDialogOpen] = React.useState(false) const [isReRequestDialogOpen, setIsReRequestDialogOpen] = React.useState(false) + const [isReinspectionDialogOpen, setIsReinspectionDialogOpen] = React.useState(false) const [isApprovalDialogOpen, setIsApprovalDialogOpen] = React.useState(false) const [isReRequestApprovalDialogOpen, setIsReRequestApprovalDialogOpen] = React.useState(false) @@ -441,6 +443,53 @@ const handleOpenRequestDialog = async () => { } } + // 재실사 요청 처리 + const handleRequestReinspection = async (data: { + qmManagerId: number, + forecastedAt: Date, + investigationAddress: string, + investigationNotes?: string + }) => { + try { + // 보완-재실사 대상 실사만 필터링 + const supplementReinspectInvestigations = selectedRows.filter(row => + row.original.investigation && + row.original.investigation.evaluationResult === "SUPPLEMENT_REINSPECT" + ); + + if (supplementReinspectInvestigations.length === 0) { + toast.error("보완-재실사 대상 실사가 없습니다."); + return; + } + + // 첫 번째 대상 실사로 재실사 요청 생성 + const targetInvestigation = supplementReinspectInvestigations[0].original.investigation!; + const { requestSupplementReinspectionAction } = await import('@/lib/vendor-investigation/service'); + + const result = await requestSupplementReinspectionAction({ + investigationId: targetInvestigation.id, + siteVisitData: { + inspectionDuration: 1.0, // 기본 1일 + requestedStartDate: data.forecastedAt, + requestedEndDate: new Date(data.forecastedAt.getTime() + 24 * 60 * 60 * 1000), // 1일 후 + shiAttendees: {}, + vendorRequests: {}, + additionalRequests: data.investigationNotes || "보완을 위한 재실사 요청입니다.", + } + }); + + if (result.success) { + toast.success("재실사 요청이 생성되었습니다."); + window.location.reload(); + } else { + toast.error(result.error || "재실사 요청 생성 중 오류가 발생했습니다."); + } + } catch (error) { + console.error("재실사 요청 오류:", error); + toast.error("재실사 요청 중 오류가 발생했습니다."); + } + }; + // 실사 결과 발송 처리 const handleSendInvestigationResults = async (data: { purchaseComment?: string }) => { try { @@ -505,8 +554,14 @@ const handleOpenRequestDialog = async () => { row.original.investigation.investigationStatus === "CANCELED" ).length + // 재실사 요청 대상 수 확인 (보완-재실사 결과만) + const reinspectInvestigationsCount = selectedRows.filter(row => + row.original.investigation && + row.original.investigation.evaluationResult === "SUPPLEMENT_REINSPECT" + ).length + // 미실사 PQ가 선택되었는지 확인 - const hasNonInspectionPQ = selectedRows.some(row => + const hasNonInspectionPQ = selectedRows.some(row => row.original.type === "NON_INSPECTION" ) @@ -651,6 +706,22 @@ const handleOpenRequestDialog = async () => { 실사 재의뢰 + {/* 재실사 요청 버튼 */} + + {/* 실사 결과 발송 버튼 */} + ) +} + + diff --git a/lib/vendor-investigation/table/investigation-progress-sheet.tsx b/lib/vendor-investigation/table/investigation-progress-sheet.tsx index c0357f5c..a9fbdfdb 100644 --- a/lib/vendor-investigation/table/investigation-progress-sheet.tsx +++ b/lib/vendor-investigation/table/investigation-progress-sheet.tsx @@ -45,7 +45,7 @@ import { updateVendorInvestigationProgressSchema, type UpdateVendorInvestigationProgressSchema, } from "../validations" -import { updateVendorInvestigationProgressAction } from "../service" +import getPQSubmissionTypeAction, { updateVendorInvestigationProgressAction } from "../service" import { VendorInvestigationsViewWithContacts } from "@/config/vendorInvestigationsColumnsConfig" interface InvestigationProgressSheetProps @@ -61,6 +61,7 @@ export function InvestigationProgressSheet({ ...props }: InvestigationProgressSheetProps) { const [isPending, startTransition] = React.useTransition() + const [isProjectPQ, setIsProjectPQ] = React.useState(false) // RHF + Zod const form = useForm({ @@ -84,6 +85,14 @@ export function InvestigationProgressSheet({ forecastedAt: investigation.forecastedAt ?? undefined, confirmedAt: investigation.confirmedAt ?? undefined, }) + // PQ 타입 조회 (PROJECT면 구매자체평가 비활성화) + if (investigation.pqSubmissionId) { + getPQSubmissionTypeAction(investigation.pqSubmissionId).then((res) => { + if (res.success) setIsProjectPQ(res.type === "PROJECT") + }) + } else { + setIsProjectPQ(false) + } } }, [investigation, form]) @@ -211,7 +220,7 @@ export function InvestigationProgressSheet({ - 구매자체평가 + 구매자체평가 서류평가 제품검사평가 방문실사평가 @@ -237,6 +246,7 @@ export function InvestigationProgressSheet({