From 5068f3573340b57c5d62a4699bd16e9dbd711b31 Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Thu, 18 Sep 2025 05:37:24 +0000
Subject: (최겸) 구매 실사 재의뢰 기능 추가
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../vendors-table-toolbar-actions.tsx              | 69 +++++++++++++++++++++-
 1 file changed, 66 insertions(+), 3 deletions(-)

(limited to 'lib/pq/pq-review-table-new/vendors-table-toolbar-actions.tsx')

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 8398c2e7..95cdd4d1 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
@@ -2,7 +2,7 @@
 
 import * as React from "react"
 import { type Table } from "@tanstack/react-table"
-import { Download, ClipboardCheck, X, Send } from "lucide-react"
+import { Download, ClipboardCheck, X, Send, RefreshCw } from "lucide-react"
 import { toast } from "sonner"
 
 import { exportTableToExcel } from "@/lib/export"
@@ -12,10 +12,11 @@ import {
   requestInvestigationAction,
   cancelInvestigationAction,
   sendInvestigationResultsAction,
-  getFactoryLocationAnswer
+  getFactoryLocationAnswer,
+  reRequestInvestigationAction
 } from "@/lib/pq/service"
 import { RequestInvestigationDialog } from "./request-investigation-dialog"
-import { CancelInvestigationDialog } from "./cancel-investigation-dialog"
+import { CancelInvestigationDialog, ReRequestInvestigationDialog } from "./cancel-investigation-dialog"
 import { SendResultsDialog } from "./send-results-dialog"
 
 interface VendorsTableToolbarActionsProps {
@@ -39,6 +40,7 @@ export function VendorsTableToolbarActions({ table }: VendorsTableToolbarActions
   const [isRequestDialogOpen, setIsRequestDialogOpen] = React.useState(false)
   const [isCancelDialogOpen, setIsCancelDialogOpen] = React.useState(false)
   const [isSendResultsDialogOpen, setIsSendResultsDialogOpen] = React.useState(false)
+  const [isReRequestDialogOpen, setIsReRequestDialogOpen] = React.useState(false)
 
   // 초기 데이터 상태
   const [dialogInitialData, setDialogInitialData] = React.useState<InvestigationInitialData | undefined>(undefined)
@@ -219,6 +221,41 @@ const handleOpenRequestDialog = async () => {
     }
   }
 
+  // 실사 재의뢰 처리
+  const handleReRequestInvestigation = async () => {
+    setIsLoading(true)
+    try {
+      // 취소된 실사만 필터링
+      const canceledInvestigations = selectedRows.filter(row =>
+        row.original.investigation &&
+        row.original.investigation.investigationStatus === "CANCELED"
+      )
+
+      if (canceledInvestigations.length === 0) {
+        toast.error("재의뢰할 수 있는 실사가 없습니다. 취소 상태의 실사만 재의뢰할 수 있습니다.")
+        return
+      }
+
+      // 서버 액션 호출
+      const result = await reRequestInvestigationAction(
+        canceledInvestigations.map(row => row.original.investigation!.id)
+      )
+
+      if (result.success) {
+        toast.success(`${result.count}개 업체에 대한 실사가 재의뢰되었습니다.`)
+        window.location.reload()
+      } else {
+        toast.error(result.error || "실사 재의뢰 처리 중 오류가 발생했습니다.")
+      }
+    } catch (error) {
+      console.error("실사 재의뢰 중 오류 발생:", error)
+      toast.error("실사 재의뢰 중 오류가 발생했습니다.")
+    } finally {
+      setIsLoading(false)
+      setIsReRequestDialogOpen(false)
+    }
+  }
+
   // 실사 결과 발송 처리
   const handleSendInvestigationResults = async (data: { purchaseComment?: string }) => {
     try {
@@ -277,6 +314,12 @@ const handleOpenRequestDialog = async () => {
     row.original.investigation.evaluationResult === "APPROVED"
   ).length
 
+  // 취소된 실사 수 확인
+  const canceledInvestigationsCount = selectedRows.filter(row =>
+    row.original.investigation &&
+    row.original.investigation.investigationStatus === "CANCELED"
+  ).length
+
   // 미실사 PQ가 선택되었는지 확인
   const hasNonInspectionPQ = selectedRows.some(row => 
     row.original.type === "NON_INSPECTION"
@@ -403,6 +446,18 @@ const handleOpenRequestDialog = async () => {
           <span className="hidden sm:inline">실사 취소</span>
         </Button>
 
+        {/* 실사 재의뢰 버튼 */}
+        <Button
+          variant="outline"
+          size="sm"
+          onClick={() => setIsReRequestDialogOpen(true)}
+          disabled={isLoading || selectedRows.length === 0}
+          className="gap-2"
+        >
+          <RefreshCw className="size-4" aria-hidden="true" />
+          <span className="hidden sm:inline">실사 재의뢰</span>
+        </Button>
+
         {/* 실사 결과 발송 버튼 */}
         <Button
           variant="outline"
@@ -450,6 +505,14 @@ const handleOpenRequestDialog = async () => {
         selectedCount={plannedInvestigationsCount}
       />
 
+      {/* 실사 재의뢰 Dialog */}
+      <ReRequestInvestigationDialog
+        isOpen={isReRequestDialogOpen}
+        onClose={() => setIsReRequestDialogOpen(false)}
+        onConfirm={handleReRequestInvestigation}
+        selectedCount={canceledInvestigationsCount}
+      />
+
       {/* 결과 발송 Dialog */}
       <SendResultsDialog
         isOpen={isSendResultsDialogOpen}
-- 
cgit v1.2.3

