summaryrefslogtreecommitdiff
path: root/lib/basic-contract/status-detail
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-11-24 10:47:34 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-11-24 10:47:34 +0000
commit8238c0c0ed6fd182d33f3437a22da1d80cfa928f (patch)
tree32982329788c38e515866de2338584eede8a5924 /lib/basic-contract/status-detail
parentd79f56ae5a9e5f72781f78fe0399018cfac44081 (diff)
(임수민) 법무검토 요청 데이터 조회 수정
Diffstat (limited to 'lib/basic-contract/status-detail')
-rw-r--r--lib/basic-contract/status-detail/basic-contract-detail-table-toolbar-actions.tsx77
-rw-r--r--lib/basic-contract/status-detail/basic-contracts-detail-columns.tsx44
-rw-r--r--lib/basic-contract/status-detail/basic-contracts-detail-table.tsx1
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>