summaryrefslogtreecommitdiff
path: root/lib/rfq-last/approval-handlers.ts
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rfq-last/approval-handlers.ts')
-rw-r--r--lib/rfq-last/approval-handlers.ts151
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 || '사유 없음',
+ };
+}
+