diff options
Diffstat (limited to 'lib/rfq-last/approval-handlers.ts')
| -rw-r--r-- | lib/rfq-last/approval-handlers.ts | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/lib/rfq-last/approval-handlers.ts b/lib/rfq-last/approval-handlers.ts new file mode 100644 index 00000000..ed082a8b --- /dev/null +++ b/lib/rfq-last/approval-handlers.ts @@ -0,0 +1,151 @@ +/** + * RFQ 발송 결재 핸들러 + * + * 첨부파일이 있는 RFQ 발송 시 결재 승인 후 실제 발송을 처리하는 핸들러 + */ + +'use server'; + +import { sendRfqToVendors } from './service'; + +/** + * RFQ 발송 핸들러 (결재 승인 후 자동 실행) + * + * @param payload - 결재 상신 시 저장한 RFQ 발송 데이터 + */ +export async function sendRfqWithApprovalInternal(payload: { + 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[]; + message?: string; + generatedPdfs?: Array<{ + key: string; + buffer: number[]; + fileName: string; + }>; + hasToSendEmail?: boolean; + currentUser: { // cronjob 환경을 위한 필수 정보 + id: string | number; + name?: string | null; + email?: string | null; + epId?: string | null; + }; +}) { + console.log('[RFQ Approval Handler] Starting RFQ send after approval'); + console.log('[RFQ Approval Handler] RFQ ID:', payload.rfqId); + console.log('[RFQ Approval Handler] Vendors count:', payload.vendors.length); + console.log('[RFQ Approval Handler] Attachments count:', payload.attachmentIds.length); + console.log('[RFQ Approval Handler] User ID:', payload.currentUser.id); + + try { + // 결재 승인 후 실제 RFQ 발송 처리 + // currentUser를 payload에서 전달 (cronjob 환경에서는 session 없음) + const result = await sendRfqToVendors({ + rfqId: payload.rfqId, + rfqCode: payload.rfqCode, + vendors: payload.vendors, + attachmentIds: payload.attachmentIds, + message: payload.message, + generatedPdfs: payload.generatedPdfs, + hasToSendEmail: payload.hasToSendEmail ?? true, + currentUser: payload.currentUser, // ✅ payload의 currentUser 전달 + }); + + console.log('[RFQ Approval Handler] ✅ RFQ sent successfully'); + console.log('[RFQ Approval Handler] Total sent:', result.totalSent); + console.log('[RFQ Approval Handler] Total contracts:', result.totalContracts); + + return { + success: true, + ...result, + }; + } catch (error) { + console.error('[RFQ Approval Handler] ❌ Failed to send RFQ:', error); + throw new Error( + error instanceof Error + ? `RFQ 발송 실패: ${error.message}` + : 'RFQ 발송 중 오류가 발생했습니다.' + ); + } +} + +/** + * 템플릿 변수 매핑 함수 + * RFQ 발송 정보를 결재 템플릿 변수로 변환 + */ +export async function mapRfqSendToTemplateVariables(data: { + attachments: Array<{ + fileName?: string | null; + fileSize?: number | null; + }>; + vendorNames: string[]; + applicationReason: string; +}) { + const { htmlTableConverter, htmlListConverter } = await import('@/lib/approval/template-utils'); + + // 파일 크기를 읽기 쉬운 형식으로 변환 + const formatFileSize = (bytes?: number | null): string => { + if (!bytes || bytes === 0) return '-'; + + const units = ['B', 'KB', 'MB', 'GB']; + let size = bytes; + let unitIndex = 0; + + while (size >= 1024 && unitIndex < units.length - 1) { + size /= 1024; + unitIndex++; + } + + return `${size.toFixed(2)} ${units[unitIndex]}`; + }; + + // 첨부파일 테이블 데이터 준비 (순번, 파일명, 파일크기만) + const attachmentTableData = data.attachments.map((att, index) => ({ + '순번': String(index + 1), + '파일명': att.fileName || '-', + '파일 크기': formatFileSize(att.fileSize), + })); + + // 첨부파일 테이블 HTML 생성 + const attachmentTableHtml = await htmlTableConverter( + attachmentTableData.length > 0 ? attachmentTableData : [], + [ + { key: '순번', label: '순번' }, + { key: '파일명', label: '파일명' }, + { key: '파일 크기', label: '파일 크기' }, + ] + ); + + // 제출처 (벤더 이름들) HTML 생성 + const vendorListHtml = await htmlListConverter( + data.vendorNames.length > 0 + ? data.vendorNames + : ['제출처가 없습니다.'] + ); + + return { + '파일 테이블': attachmentTableHtml, + '제출처': vendorListHtml, + '신청사유': data.applicationReason || '사유 없음', + }; +} + |
