diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/approval-log/service.ts | 59 | ||||
| -rw-r--r-- | lib/approval-log/table/approval-log-table-column.tsx | 10 | ||||
| -rw-r--r-- | lib/pq/service.ts | 22 | ||||
| -rw-r--r-- | lib/vendor-investigation/approval-actions.ts | 2 | ||||
| -rw-r--r-- | lib/vendor-investigation/handlers.ts | 25 |
5 files changed, 112 insertions, 6 deletions
diff --git a/lib/approval-log/service.ts b/lib/approval-log/service.ts index 4d1ad7f8..5690e0f9 100644 --- a/lib/approval-log/service.ts +++ b/lib/approval-log/service.ts @@ -13,6 +13,7 @@ import { import db from '@/db/db'; import { approvalLogs } from '@/db/schema/knox/approvals'; +import { pendingActions } from '@/db/schema/knox/pending-actions'; import { filterColumns } from '@/lib/filter-columns'; // --------------------------------------------- @@ -198,3 +199,61 @@ export async function getApprovalLogListAction(input: ListInput) { }; } } + +// ---------------------------------------------------- +// Get approval log detail with pending action +// ---------------------------------------------------- +export type PendingAction = typeof pendingActions.$inferSelect; + +export interface ApprovalLogDetail { + approvalLog: ApprovalLog; + pendingAction: PendingAction | null; +} + +export async function getApprovalLogDetail(apInfId: string): Promise<ApprovalLogDetail | null> { + try { + // approvalLog 조회 + const approvalLog = await getApprovalLog(apInfId); + if (!approvalLog) { + return null; + } + + // pendingAction 조회 + const [pendingAction] = await db + .select() + .from(pendingActions) + .where(eq(pendingActions.apInfId, apInfId)) + .limit(1); + + return { + approvalLog, + pendingAction: pendingAction || null, + }; + } catch (error) { + console.error('Error fetching approval log detail:', error); + return null; + } +} + +// ---------------------------------------------------- +// Server Action for getting approval log detail +// ---------------------------------------------------- +export async function getApprovalLogDetailAction(apInfId: string) { + try { + const data = await getApprovalLogDetail(apInfId); + if (!data) { + return { + success: false, + error: '결재 로그를 찾을 수 없습니다.', + data: null, + }; + } + return { success: true, data }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error.message : '결재 로그 상세 조회에 실패했습니다.', + data: null, + }; + } +} diff --git a/lib/approval-log/table/approval-log-table-column.tsx b/lib/approval-log/table/approval-log-table-column.tsx index a77ed0d3..747ce5ce 100644 --- a/lib/approval-log/table/approval-log-table-column.tsx +++ b/lib/approval-log/table/approval-log-table-column.tsx @@ -15,6 +15,7 @@ import { DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" +import { useParams, useRouter } from "next/navigation" interface GetColumnsProps { setRowAction: React.Dispatch<React.SetStateAction<{ @@ -24,6 +25,12 @@ interface GetColumnsProps { } export function getColumns({ setRowAction }: GetColumnsProps): ColumnDef<ApprovalLog>[] { + // eslint-disable-next-line react-hooks/rules-of-hooks + const router = useRouter(); + // eslint-disable-next-line react-hooks/rules-of-hooks + const params = useParams(); + const lng = params.lng as string; + return [ { id: "select", @@ -248,6 +255,7 @@ export function getColumns({ setRowAction }: GetColumnsProps): ColumnDef<Approva { id: "actions", cell: ({ row }) => { + const apInfId = row.original.apInfId; return ( <DropdownMenu> <DropdownMenuTrigger asChild> @@ -262,7 +270,7 @@ export function getColumns({ setRowAction }: GetColumnsProps): ColumnDef<Approva <DropdownMenuContent align="end" className="w-40"> <DropdownMenuItem onClick={() => { - setRowAction({ type: "view", row }); + router.push(`/${lng}/evcp/approval/log/${apInfId}`); }} > <Eye className="mr-2 size-4" aria-hidden="true" /> diff --git a/lib/pq/service.ts b/lib/pq/service.ts index d3974964..b39bf7bd 100644 --- a/lib/pq/service.ts +++ b/lib/pq/service.ts @@ -2985,10 +2985,26 @@ export async function cancelInvestigationAction(investigationIds: number[]) { }
// 실사 재의뢰 서버 액션
-export async function reRequestInvestigationAction(investigationIds: number[]) {
+export async function reRequestInvestigationAction(
+ investigationIds: number[],
+ currentUser?: { id: number } // ✅ 핸들러에서 호출 시 사용자 정보 전달
+) {
try {
- const session = await getServerSession(authOptions)
- const userId = session?.user?.id ? Number(session.user.id) : null
+ let userId: number | null = null;
+
+ if (currentUser) {
+ // 핸들러에서 호출 시 (결재 승인 후)
+ userId = currentUser.id;
+
+ // ✅ 핸들러에서 호출 시 userId 검증: 없으면 잘못된 상황 (예외 처리)
+ if (!userId || userId <= 0) {
+ throw new Error('핸들러에서 호출 시 currentUser.id가 필수입니다.');
+ }
+ } else {
+ // 직접 호출 시 (세션에서 가져오기)
+ const session = await getServerSession(authOptions);
+ userId = session?.user?.id ? Number(session.user.id) : null;
+ }
if (!userId) {
return { success: false, error: "인증된 사용자만 실사를 재의뢰할 수 있습니다." }
diff --git a/lib/vendor-investigation/approval-actions.ts b/lib/vendor-investigation/approval-actions.ts index 5da30011..e8e24ddc 100644 --- a/lib/vendor-investigation/approval-actions.ts +++ b/lib/vendor-investigation/approval-actions.ts @@ -100,6 +100,7 @@ export async function requestPQInvestigationWithApproval(data: { forecastedAt: data.forecastedAt, investigationAddress: data.investigationAddress, investigationNotes: data.investigationNotes, + currentUserId: data.currentUser.id, // ✅ 결재 승인 후 핸들러 실행 시 필요 }, // approvalConfig: 결재 상신 정보 (템플릿 포함) @@ -227,6 +228,7 @@ export async function reRequestPQInvestigationWithApproval(data: { // actionPayload: 결재 승인 후 핸들러에 전달될 데이터 (최소 데이터만) { investigationIds: data.investigationIds, + currentUserId: data.currentUser.id, // ✅ 결재 승인 후 핸들러 실행 시 필요 }, // approvalConfig: 결재 상신 정보 (템플릿 포함) diff --git a/lib/vendor-investigation/handlers.ts b/lib/vendor-investigation/handlers.ts index 28a218b5..3165df06 100644 --- a/lib/vendor-investigation/handlers.ts +++ b/lib/vendor-investigation/handlers.ts @@ -22,19 +22,28 @@ export async function requestPQInvestigationInternal(payload: { forecastedAt: Date; investigationAddress: string; investigationNotes?: string; + currentUserId: number; // ✅ 결재 상신한 사용자 ID }) { debugLog('[PQInvestigationHandler] 실사 의뢰 핸들러 시작', { pqCount: payload.pqSubmissionIds.length, qmManagerId: payload.qmManagerId, + currentUserId: payload.currentUserId, }); + // ✅ userId 검증: 핸들러에서 userId가 없으면 잘못된 상황 (예외 처리) + if (!payload.currentUserId || payload.currentUserId <= 0) { + const errorMessage = 'currentUserId가 없습니다. actionPayload에 currentUserId가 포함되지 않았습니다.'; + debugError('[PQInvestigationHandler]', errorMessage); + throw new Error(errorMessage); + } + try { // 기존 PQ 서비스 함수 사용 (DB 트랜잭션 포함) const { requestInvestigationAction } = await import('@/lib/pq/service'); const result = await requestInvestigationAction( payload.pqSubmissionIds, - { id: 0, epId: null, email: undefined }, // 핸들러에서는 currentUser 불필요 + { id: payload.currentUserId, epId: null, email: undefined }, // ✅ 실제 사용자 ID 전달 { qmManagerId: payload.qmManagerId, forecastedAt: payload.forecastedAt, @@ -106,16 +115,28 @@ export async function mapPQInvestigationToTemplateVariables(payload: { */ export async function reRequestPQInvestigationInternal(payload: { investigationIds: number[]; + currentUserId: number; // ✅ 결재 상신한 사용자 ID }) { debugLog('[PQReRequestHandler] 실사 재의뢰 핸들러 시작', { investigationCount: payload.investigationIds.length, + currentUserId: payload.currentUserId, }); + // ✅ userId 검증: 핸들러에서 userId가 없으면 잘못된 상황 (예외 처리) + if (!payload.currentUserId || payload.currentUserId <= 0) { + const errorMessage = 'currentUserId가 없습니다. actionPayload에 currentUserId가 포함되지 않았습니다.'; + debugError('[PQReRequestHandler]', errorMessage); + throw new Error(errorMessage); + } + try { // 기존 PQ 서비스 함수 사용 const { reRequestInvestigationAction } = await import('@/lib/pq/service'); - const result = await reRequestInvestigationAction(payload.investigationIds); + const result = await reRequestInvestigationAction( + payload.investigationIds, + { id: payload.currentUserId } // ✅ 실제 사용자 ID 전달 + ); if (!result.success) { debugError('[PQReRequestHandler] 실사 재의뢰 실패', result.error); |
