summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/approval-log/service.ts59
-rw-r--r--lib/approval-log/table/approval-log-table-column.tsx10
-rw-r--r--lib/pq/service.ts22
-rw-r--r--lib/vendor-investigation/approval-actions.ts2
-rw-r--r--lib/vendor-investigation/handlers.ts25
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);