/** * 정규업체 등록 관련 결재 액션 핸들러 * * 실제 비즈니스 로직만 포함 (결재 로직은 approval-workflow에서 처리) */ 'use server'; import { sendRegistrationRequestToMDG } from './service'; import { debugLog, debugError, debugSuccess } from '@/lib/debug-utils'; import type { RegistrationRequestData } from '@/components/vendor-regular-registrations/registration-request-dialog'; import db from '@/db/db'; import { eq } from 'drizzle-orm'; import { vendors } from '@/db/schema/vendors'; import { vendorAdditionalInfo, vendorRegularRegistrations } from '@/db/schema/vendorRegistrations'; /** * 정규업체 등록 핸들러 (결재 승인 후 MDG 전송 실행) * * 결재 승인 후 자동으로 MDG로 정규업체 등록 요청을 전송함 * 이 함수는 직접 호출하지 않고, 결재 워크플로우에서 자동으로 호출됨 * * @param payload - withApproval()에서 전달한 actionPayload */ export async function registerVendorInternal(payload: { registrationId: number; requestData: RegistrationRequestData; }) { debugLog('[VendorRegistrationHandler] 정규업체 등록 핸들러 시작', { registrationId: payload.registrationId, companyName: payload.requestData.companyNameKor, }); try { // 1. MDG로 정규업체 등록 요청 데이터 전송 debugLog('[VendorRegistrationHandler] sendRegistrationRequestToMDG 호출'); const mdgResult = await sendRegistrationRequestToMDG( payload.registrationId, payload.requestData ); if (!mdgResult.success) { debugError('[VendorRegistrationHandler] MDG 전송 실패', mdgResult.error); // MDG 전송 실패 시 상태를 registration_failed로 변경 await db.update(vendorRegularRegistrations) .set({ status: 'registration_failed', updatedAt: new Date() }) .where(eq(vendorRegularRegistrations.id, payload.registrationId)); throw new Error(mdgResult.error || 'MDG 전송에 실패했습니다.'); } // 3. MDG 전송 성공 시 상태를 registration_completed로 변경 debugLog('[VendorRegistrationHandler] MDG 전송 성공, 상태를 registration_completed로 변경'); await db.update(vendorRegularRegistrations) .set({ status: 'registration_completed', updatedAt: new Date() }) .where(eq(vendorRegularRegistrations.id, payload.registrationId)); debugSuccess('[VendorRegistrationHandler] 정규업체 등록 완료', { registrationId: payload.registrationId, mdgResult: mdgResult }); return { success: true, message: '정규업체 등록이 완료되었습니다.', mdgResult: mdgResult }; } catch (error) { debugError('[VendorRegistrationHandler] 정규업체 등록 중 에러', error); // 에러 발생 시 상태를 registration_failed로 변경 try { await db.update(vendorRegularRegistrations) .set({ status: 'registration_failed', updatedAt: new Date() }) .where(eq(vendorRegularRegistrations.id, payload.registrationId)); } catch (updateError) { debugError('[VendorRegistrationHandler] 상태 업데이트 실패', updateError); } throw error; } } /** * 정규업체 등록 데이터를 결재 템플릿 변수로 매핑 * * 제공된 HTML 템플릿의 변수명에 맞춰 매핑 * * @param payload - 정규업체 등록 데이터 * @returns 템플릿 변수 객체 (Record) */ export async function mapRegistrationToTemplateVariables(payload: { requestData: RegistrationRequestData; requestedAt: Date; vendorId?: number; // vendors 테이블에서 정보를 가져오기 위한 vendorId }): Promise> { const { requestData, requestedAt, vendorId } = payload; // vendors 테이블에서 추가 정보 가져오기 let vendorInfo: { postalCode?: string | null; businessSize?: string | null; addressDetail?: string | null; } = {}; if (vendorId) { try { const vendorResult = await db .select({ postalCode: vendors.postalCode, businessSize: vendors.businessSize, addressDetail: vendors.addressDetail, }) .from(vendors) .where(eq(vendors.id, vendorId)) .limit(1); vendorInfo = vendorResult[0] || {}; } catch (error) { console.warn('[Template Variables] Failed to fetch vendor info:', error); } } // 추가정보 조회 let additionalInfo = { businessType: '', industryType: '', companySize: '', revenue: '', factoryEstablishedDate: '', preferredContractTerms: '', }; if (vendorId) { try { const additionalInfoResult = await db .select({ businessType: vendorAdditionalInfo.businessType, industryType: vendorAdditionalInfo.industryType, companySize: vendorAdditionalInfo.companySize, revenue: vendorAdditionalInfo.revenue, factoryEstablishedDate: vendorAdditionalInfo.factoryEstablishedDate, preferredContractTerms: vendorAdditionalInfo.preferredContractTerms, }) .from(vendorAdditionalInfo) .where(eq(vendorAdditionalInfo.vendorId, vendorId)) .limit(1); const info = additionalInfoResult[0]; if (info) { additionalInfo = { businessType: info.businessType ?? '', industryType: info.industryType ?? '', companySize: info.companySize ?? '', revenue: info.revenue ?? '', factoryEstablishedDate: info.factoryEstablishedDate ?? '', preferredContractTerms: info.preferredContractTerms ?? '', }; } } catch (error) { console.warn('[Template Variables] Failed to fetch additional info:', error); } } console.log('[Template Variables] Additional info:', additionalInfo); // 변수명은 공백 없이 깔끔하게 정의 (template-utils.ts에서 자동으로 trim 처리됨) const variables = { // 협력업체 기본정보 '협력업체기본정보-사업자번호': requestData.businessNumber || '', '협력업체기본정보-업체명': requestData.companyNameKor || '', '협력업체기본정보-대표자명': requestData.representativeNameKor || '', '협력업체기본정보-대표전화': requestData.headOfficePhone || '', '협력업체기본정보-FAX': '', // FAX 정보는 vendors 테이블에 없으므로 빈 문자열 '협력업체기본정보-Email': requestData.representativeEmail || '', '협력업체기본정보-우편번호': vendorInfo.postalCode || '', '협력업체기본정보-회사주소': requestData.headOfficeAddress || '', '협력업체기본정보-상세주소': vendorInfo.addressDetail || '', '협력업체기본정보-사업유형': additionalInfo.businessType || '', '협력업체기본정보-산업유형': additionalInfo.industryType || '', '협력업체기본정보-회사규모': additionalInfo.companySize || '', // 담당자 연락처 - 영업담당자 '영업담당자-담당자명': requestData.businessContacts.sales.name || '', '영업담당자-직급': requestData.businessContacts.sales.position || '', '영업담당자-부서': requestData.businessContacts.sales.department || '', '영업담당자-담당업무': requestData.businessContacts.sales.responsibility || '', '영업담당자-이메일': requestData.businessContacts.sales.email || '', // 담당자 연락처 - 설계담당자 '설계담당자-담당자명': requestData.businessContacts.design.name || '', '설계담당자-직급': requestData.businessContacts.design.position || '', '설계담당자-부서': requestData.businessContacts.design.department || '', '설계담당자-담당업무': requestData.businessContacts.design.responsibility || '', '설계담당자-이메일': requestData.businessContacts.design.email || '', // 담당자 연락처 - 납기담당자 '납기담당자-담당자명': requestData.businessContacts.delivery.name || '', '납기담당자-직급': requestData.businessContacts.delivery.position || '', '납기담당자-부서': requestData.businessContacts.delivery.department || '', '납기담당자-담당업무': requestData.businessContacts.delivery.responsibility || '', '납기담당자-이메일': requestData.businessContacts.delivery.email || '', // 담당자 연락처 - 품질담당자 '품질담당자-담당자명': requestData.businessContacts.quality.name || '', '품질담당자-직급': requestData.businessContacts.quality.position || '', '품질담당자-부서': requestData.businessContacts.quality.department || '', '품질담당자-담당업무': requestData.businessContacts.quality.responsibility || '', '품질담당자-이메일': requestData.businessContacts.quality.email || '', // 담당자 연락처 - 세금계산서담당자 '세금계산서담당자-담당자명': requestData.businessContacts.taxInvoice.name || '', '세금계산서담당자-직급': requestData.businessContacts.taxInvoice.position || '', '세금계산서담당자-부서': requestData.businessContacts.taxInvoice.department || '', '세금계산서담당자-담당업무': requestData.businessContacts.taxInvoice.responsibility || '', '세금계산서담당자-이메일': requestData.businessContacts.taxInvoice.email || '', // 기본계약서 현황 '계약유형': '정규업체 등록 요청', '계약상태': '등록 대기', '서약일자': new Date(requestedAt).toLocaleDateString('ko-KR'), }; // 디버깅을 위한 로그 출력 console.log('[Template Variables] Generated variables:', Object.keys(variables)); console.log('[Template Variables] Sample values:', { companyName: variables['협력업체기본정보-업체명'], businessNumber: variables['협력업체기본정보-사업자번호'], representative: variables['협력업체기본정보-대표자명'], }); return variables; }