diff options
| author | joonhoekim <26rote@gmail.com> | 2025-11-06 20:01:16 +0900 |
|---|---|---|
| committer | joonhoekim <26rote@gmail.com> | 2025-11-06 20:01:16 +0900 |
| commit | 4c07f977c951cd99dd50d3bdaad0437e3dd55e6d (patch) | |
| tree | 77c0db24854ed1ecde821d4a79543e82fa75eaed /lib/rfq-last/approval-actions.ts | |
| parent | 1b843e0a7ea55c64992f55033b30037239ff67f5 (diff) | |
(김준회) ITB/RFQ/일반견적: 발송시 첨부파일 있는 경우 '암호화해제 결재' 프로세스 타도록 변경
Diffstat (limited to 'lib/rfq-last/approval-actions.ts')
| -rw-r--r-- | lib/rfq-last/approval-actions.ts | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/lib/rfq-last/approval-actions.ts b/lib/rfq-last/approval-actions.ts new file mode 100644 index 00000000..be435931 --- /dev/null +++ b/lib/rfq-last/approval-actions.ts @@ -0,0 +1,155 @@ +/** + * RFQ 발송 결재 서버 액션 + * + * 첨부파일이 있는 RFQ를 발송할 때 결재를 거치는 서버 액션 + */ + +'use server'; + +import { ApprovalSubmissionSaga } from '@/lib/approval'; +import { mapRfqSendToTemplateVariables } from './approval-handlers'; + +interface RfqSendApprovalData { + // RFQ 기본 정보 + rfqId: number; + rfqCode?: string; + + // 발송 데이터 + vendors: Array<{ + vendorId: number; + vendorName: string; + vendorCode?: string | null; + vendorCountry?: string | null; + selectedMainEmail: string; + additionalEmails: string[]; + customEmails?: Array<{ email: string; name?: string }>; + currency?: string | null; + contractRequirements?: { + ndaYn: boolean; + generalGtcYn: boolean; + projectGtcYn: boolean; + agreementYn: boolean; + projectCode?: string; + }; + isResend: boolean; + sendVersion?: number; + }>; + attachmentIds: number[]; + + // 첨부파일 정보 (파일명, 크기 등) + attachments: Array<{ + fileName?: string | null; + fileSize?: number | null; + }>; + + message?: string; + generatedPdfs?: Array<{ + key: string; + buffer: number[]; + fileName: string; + }>; + hasToSendEmail?: boolean; + + // 신청 사유 + applicationReason: string; + + // 결재 정보 + currentUser: { + id: number; + epId: string | null; + name?: string; + email?: string; + }; + approvers?: string[]; // Knox EP ID 배열 +} + +/** + * RFQ 발송 결재 상신 + * + * 첨부파일이 있는 경우 결재를 거쳐 RFQ를 발송합니다. + */ +export async function requestRfqSendWithApproval(data: RfqSendApprovalData) { + // 1. 입력 검증 + if (!data.currentUser.epId) { + throw new Error('Knox EP ID가 필요합니다. 시스템 관리자에게 문의하세요.'); + } + + if (!data.vendors || data.vendors.length === 0) { + throw new Error('발송할 벤더를 선택해주세요.'); + } + + if (!data.attachmentIds || data.attachmentIds.length === 0) { + throw new Error('첨부파일이 없습니다. 결재가 필요하지 않습니다.'); + } + + console.log('[RFQ Approval] Starting approval process for RFQ send'); + console.log('[RFQ Approval] RFQ ID:', data.rfqId); + console.log('[RFQ Approval] Vendors:', data.vendors.length); + console.log('[RFQ Approval] Attachments:', data.attachmentIds.length); + + try { + // 2. 템플릿 변수 매핑 + const variables = await mapRfqSendToTemplateVariables({ + attachments: data.attachments, + vendorNames: data.vendors.map(v => v.vendorName), + applicationReason: data.applicationReason, + }); + + // 3. 결재 상신용 payload 구성 + // ⚠️ cronjob 환경에서 실행되므로 currentUser 정보를 포함해야 함 + const approvalPayload = { + rfqId: data.rfqId, + rfqCode: data.rfqCode, + vendors: data.vendors, + attachmentIds: data.attachmentIds, + message: data.message, + generatedPdfs: data.generatedPdfs, + hasToSendEmail: data.hasToSendEmail, + currentUser: { + id: data.currentUser.id, + name: data.currentUser.name, + email: data.currentUser.email, + epId: data.currentUser.epId, + }, + }; + + // 4. Saga로 결재 상신 + const saga = new ApprovalSubmissionSaga( + 'rfq_send_with_attachments', // 핸들러 키 + approvalPayload, // 결재 승인 후 실행될 데이터 + { + title: `암호화해제 신청 - ${data.rfqCode || 'RFQ'}`, + description: `${data.vendors.length}개 업체에 첨부파일 ${data.attachmentIds.length}개를 포함한 암호화해제 신청`, + templateName: '암호화해제 신청', // DB에 있어야 함 + variables, + approvers: data.approvers, + currentUser: { + id: data.currentUser.id, + epId: data.currentUser.epId, + email: data.currentUser.email, + }, + } + ); + + const result = await saga.execute(); + + console.log('[RFQ Approval] ✅ Approval submitted successfully'); + console.log('[RFQ Approval] Approval ID:', result.approvalId); + console.log('[RFQ Approval] Pending Action ID:', result.pendingActionId); + + return { + success: true, + ...result, + message: `결재가 상신되었습니다. (결재 ID: ${result.approvalId})`, + }; + + } catch (error) { + console.error('[RFQ Approval] ❌ Failed to submit approval:', error); + throw new Error( + error instanceof Error + ? error.message + : 'RFQ 발송 결재 상신에 실패했습니다.' + ); + } +} + |
