diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-11-24 10:47:34 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-11-24 10:47:34 +0000 |
| commit | 8238c0c0ed6fd182d33f3437a22da1d80cfa928f (patch) | |
| tree | 32982329788c38e515866de2338584eede8a5924 /lib/basic-contract/status-detail | |
| parent | d79f56ae5a9e5f72781f78fe0399018cfac44081 (diff) | |
(임수민) 법무검토 요청 데이터 조회 수정
Diffstat (limited to 'lib/basic-contract/status-detail')
3 files changed, 67 insertions, 55 deletions
diff --git a/lib/basic-contract/status-detail/basic-contract-detail-table-toolbar-actions.tsx b/lib/basic-contract/status-detail/basic-contract-detail-table-toolbar-actions.tsx index e62a6cb7..b2cc5055 100644 --- a/lib/basic-contract/status-detail/basic-contract-detail-table-toolbar-actions.tsx +++ b/lib/basic-contract/status-detail/basic-contract-detail-table-toolbar-actions.tsx @@ -22,11 +22,19 @@ import { prepareFinalApprovalAction, quickFinalApprovalAction, resendContractsAc import { BasicContractSignDialog } from "../vendor-table/basic-contract-sign-dialog" import { SSLVWPurInqReqDialog } from "@/components/common/legal/sslvw-pur-inq-req-dialog" import { requestRedFlagResolution } from "@/lib/compliance/red-flag-resolution" +import { useRouter } from "next/navigation" + +interface RedFlagResolutionState { + resolved: boolean + resolvedAt: Date | null + pendingApprovalId: string | null +} interface BasicContractDetailTableToolbarActionsProps { table: Table<BasicContractView> gtcData?: Record<number, { gtcDocumentId: number | null; hasComments: boolean }> redFlagData?: Record<number, boolean> + redFlagResolutionData?: Record<number, RedFlagResolutionState> isComplianceTemplate?: boolean } @@ -34,6 +42,7 @@ export function BasicContractDetailTableToolbarActions({ table, gtcData = {}, redFlagData = {}, + redFlagResolutionData = {}, isComplianceTemplate = false }: BasicContractDetailTableToolbarActionsProps) { // 선택된 행들 가져오기 @@ -47,6 +56,7 @@ export function BasicContractDetailTableToolbarActions({ const [loading, setLoading] = React.useState(false) const [buyerSignDialog, setBuyerSignDialog] = React.useState(false) const [contractsToSign, setContractsToSign] = React.useState<any[]>([]) + const router = useRouter() // 각 버튼별 활성화 조건 계산 const canBulkDownload = hasSelectedRows && selectedRows.some(row => @@ -339,6 +349,11 @@ export function BasicContractDetailTableToolbarActions({ return } + if (selectedRows.length !== 1) { + toast.error("계약서 한 건을 선택해주세요.") + return + } + try { setLoading(true) @@ -350,7 +365,7 @@ export function BasicContractDetailTableToolbarActions({ if (result.success) { toast.success(result.message) - // 테이블 데이터 갱신 + router.refresh() table.toggleAllPageRowsSelected(false) } else { toast.error(result.message) @@ -391,27 +406,48 @@ export function BasicContractDetailTableToolbarActions({ } } - // RED FLAG 해소요청 가능 여부 - const canRequestRedFlagResolution = hasSelectedRows && isComplianceTemplate && selectedRows.some(row => { - const contract = row.original - return redFlagData[contract.id] === true - }) + const hasPendingResolution = (contractId: number) => { + const state = redFlagResolutionData[contractId] + return Boolean(state?.pendingApprovalId && !state?.resolved) + } - // RED FLAG 해소요청 가능한 계약서들 - const redFlagResolutionContracts = selectedRows + const redFlagEligibleContracts = selectedRows .map(row => row.original) - .filter(contract => redFlagData[contract.id] === true) + .filter(contract => { + if (redFlagData[contract.id] !== true) return false + return !hasPendingResolution(contract.id) + }) + + const redFlagPendingContracts = selectedRows + .map(row => row.original) + .filter(contract => hasPendingResolution(contract.id)) + + const canRequestRedFlagResolution = + hasSelectedRows && isComplianceTemplate && redFlagEligibleContracts.length > 0 // RED FLAG 해소요청 const handleRequestRedFlagResolution = async () => { if (!canRequestRedFlagResolution) { - toast.error("RED FLAG가 있는 계약서를 선택해주세요") + toast.error("해소요청 가능한 RED FLAG 계약서를 선택해주세요") return } + if (redFlagPendingContracts.length > 0) { + const preview = redFlagPendingContracts + .map((contract) => contract.vendorName || `계약 ${contract.id}`) + .slice(0, 2) + .join(", ") + toast.info( + `${preview}${redFlagPendingContracts.length > 2 ? ` 외 ${redFlagPendingContracts.length - 2}건` : ""}은 해소요청이 이미 진행 중입니다.`, + { + description: "진행 중인 계약서는 자동으로 제외하고 요청합니다.", + } + ) + } + setLoading(true) try { - const contractIds = redFlagResolutionContracts.map(c => c.id) + const contractIds = redFlagEligibleContracts.map(c => c.id) const result = await requestRedFlagResolution(contractIds) toast.success("RED FLAG 해소요청 결재가 상신되었습니다.", { @@ -503,13 +539,15 @@ export function BasicContractDetailTableToolbarActions({ title={!hasSelectedRows ? "계약서를 선택해주세요" : !canRequestRedFlagResolution - ? "RED FLAG가 있는 계약서를 선택해주세요" - : `${redFlagResolutionContracts.length}건 RED FLAG 해소요청` + ? redFlagPendingContracts.length > 0 + ? "이미 해소요청이 진행 중인 계약서만 선택되어 있습니다" + : "RED FLAG가 있는 계약서를 선택해주세요" + : `${redFlagEligibleContracts.length}건 RED FLAG 해소요청` } > <Flag className="size-4" aria-hidden="true" /> <span className="hidden sm:inline"> - RED FLAG 해소요청 {hasSelectedRows ? `(${redFlagResolutionContracts.length})` : ''} + RED FLAG 해소요청 {hasSelectedRows ? `(${redFlagEligibleContracts.length})` : ''} </span> </Button> )} @@ -530,7 +568,16 @@ export function BasicContractDetailTableToolbarActions({ </Button> {/* 법무검토 버튼 (SSLVW 데이터 조회) */} - <SSLVWPurInqReqDialog onConfirm={handleSSLVWConfirm} /> + <SSLVWPurInqReqDialog + onConfirm={handleSSLVWConfirm} + requireSingleSelection + triggerDisabled={selectedRows.length !== 1 || loading} + triggerTitle={ + selectedRows.length !== 1 + ? "계약서 한 건을 선택해주세요" + : undefined + } + /> {/* 법무검토 요청 버튼 */} <Button diff --git a/lib/basic-contract/status-detail/basic-contracts-detail-columns.tsx b/lib/basic-contract/status-detail/basic-contracts-detail-columns.tsx index 2ab39880..d03d0720 100644 --- a/lib/basic-contract/status-detail/basic-contracts-detail-columns.tsx +++ b/lib/basic-contract/status-detail/basic-contracts-detail-columns.tsx @@ -531,50 +531,14 @@ export function getDetailColumns({ ), cell: ({ row }) => { const status = row.getValue("legalReviewStatus") as string | null - const contract = row.original - const requestedDate = contract.legalReviewRequestedAt as Date | null - const completedDate = contract.legalReviewCompletedAt as Date | null - // 법무검토 상태 우선, 없으면 기존 로직으로 판단 + // PRGS_STAT_DSC 연동값 우선 표시 if (status) { - const statusColors: Record<string, string> = { - '신규등록': 'text-blue-600', - '검토요청': 'text-purple-600', - '담당자배정': 'text-orange-600', - '검토중': 'text-yellow-600', - '답변완료': 'text-green-600', - '재검토요청': 'text-red-600', - '보류': 'text-gray-500', - '취소': 'text-red-700' - } - - return ( - <div className={`text-sm ${statusColors[status] || 'text-gray-600'}`}> - <div className="font-medium">{status}</div> - </div> - ) + return <div className="text-sm text-gray-800">{status}</div> } - // legalWorks에 데이터가 없는 경우 기존 로직 사용 - if (completedDate) { - return ( - <div className="text-sm text-green-600"> - <div className="font-medium">완료</div> - <div className="text-xs">{formatDateTime(completedDate, "KR")}</div> - </div> - ) - } else if (requestedDate) { - return ( - <div className="text-sm text-orange-600"> - <div className="font-medium">진행중</div> - <div className="text-xs">검토 대기</div> - </div> - ) - } else { - return ( - <div className="text-sm text-gray-400">-</div> - ) - } + // 동기화된 값이 없으면 빈 값 처리 + return <div className="text-sm text-gray-400">-</div> }, minSize: 140, }, diff --git a/lib/basic-contract/status-detail/basic-contracts-detail-table.tsx b/lib/basic-contract/status-detail/basic-contracts-detail-table.tsx index 010b4713..a2e1c5e4 100644 --- a/lib/basic-contract/status-detail/basic-contracts-detail-table.tsx +++ b/lib/basic-contract/status-detail/basic-contracts-detail-table.tsx @@ -266,6 +266,7 @@ type RedFlagResolutionState = { table={table} gtcData={gtcData} redFlagData={redFlagData} + redFlagResolutionData={redFlagResolutionData} isComplianceTemplate={isComplianceTemplate} /> </DataTableAdvancedToolbar> |
