11import uuid
22from datetime import datetime
33from typing import Optional , List
4- from fastapi import HTTPException
5-
6-
7-
84from ..models .project import Project , ProjectsBySeasonResponse
95from ..models .certificate import CertificateResponse , CertificateData , CertificateStatus , Role
10- from ..constants .error_codes import ErrorCodes , ResponseStatus
116from ..utils .notion_client import NotionClient
127from ..utils .pdf_generator import PDFGenerator
138from ..utils .email_sender import EmailSender
@@ -49,7 +44,122 @@ async def create_certificate(certificate_data: dict) -> CertificateResponse:
4944 notion_client = NotionClient ()
5045
5146 try :
47+ # 1. 기존 수료증 확인 (재발급 여부 판단)
48+ existing_cert = await notion_client .check_existing_certificate (
49+ applicant_name = certificate_data ["applicant_name" ],
50+ course_name = certificate_data ["course_name" ],
51+ season = certificate_data ["season" ],
52+ recipient_email = certificate_data .get ("recipient_email" )
53+ )
54+
55+ # 기존 수료증 확인이 성공하고 기존 수료증이 있는 경우 재발급 처리
56+ if existing_cert and existing_cert .get ("found" ):
57+ print (f"기존 수료증 발견: { existing_cert .get ('certificate_number' )} " )
58+ return await CertificateService ._reissue_certificate (
59+ certificate_data , existing_cert , notion_client
60+ )
61+
62+ # 2. 신규 수료증 발급 처리
63+ return await CertificateService ._create_new_certificate (
64+ certificate_data , notion_client
65+ )
66+
67+ except Exception as e :
68+ print (f"수료증 발급 중 오류: { e } " )
69+ return CertificateResponse (
70+ status = "500" ,
71+ message = f"수료증 발급 중 오류가 발생했습니다: { str (e )} " ,
72+ data = None
73+ )
74+
75+ @staticmethod
76+ async def _reissue_certificate (
77+ certificate_data : dict ,
78+ existing_cert : dict ,
79+ notion_client : NotionClient
80+ ) -> CertificateResponse :
81+ """기존 수료증 재발급"""
82+ try :
83+ # 기존 수료증 정보 사용
84+ existing_page_id = existing_cert .get ("page_id" )
85+ existing_cert_number = existing_cert .get ("certificate_number" )
86+
87+ print ("🔄 기존 수료증 재발급 시작 (이름, 코스, 기수 일치):" )
88+ print (f" - 기존 수료증 번호: '{ existing_cert_number } '" )
89+ print (f" - 요청 이메일: '{ certificate_data .get ('recipient_email' , '' )} '" )
90+
91+ # 사용자 참여 이력 재확인 (역할 정보 가져오기)
92+ participation_info = await notion_client .verify_user_participation (
93+ user_name = certificate_data ["applicant_name" ],
94+ course_name = certificate_data ["course_name" ],
95+ season = certificate_data ["season" ]
96+ )
97+
98+ # 수료증 번호가 없는 경우 새로 생성
99+ if not existing_cert_number :
100+ print ("⚠️ 기존 수료증에 번호가 없어 새로 생성합니다." )
101+ existing_cert_number = f"CERT-{ datetime .now ().year } { participation_info ['project_code' ]} { str (uuid .uuid4 ())[:2 ].upper ()} "
102+ print (f"🆕 새로 생성된 수료증 번호: { existing_cert_number } " )
103+
104+ # PDF 수료증 재생성
105+ pdf_generator = PDFGenerator ()
106+ pdf_bytes = pdf_generator .create_certificate (
107+ name = certificate_data ["applicant_name" ],
108+ season = certificate_data ['season' ],
109+ course_name = certificate_data ["course_name" ],
110+ role = participation_info ["user_role" ],
111+ period = participation_info ["period" ],
112+ )
52113
114+ # 이메일 재발송
115+ email_sender = EmailSender ()
116+ await email_sender .send_certificate_email (
117+ recipient_email = certificate_data ["recipient_email" ],
118+ recipient_name = certificate_data ["applicant_name" ],
119+ course_name = certificate_data ["course_name" ],
120+ season = certificate_data ["season" ],
121+ role = participation_info ["user_role" ],
122+ certificate_bytes = pdf_bytes
123+ )
124+
125+ # 기존 수료증 상태를 재발급으로 업데이트
126+ await notion_client .update_certificate_status (
127+ page_id = existing_page_id ,
128+ status = CertificateStatus .ISSUED ,
129+ certificate_number = existing_cert_number ,
130+ role = participation_info ["user_role" ]
131+ )
132+
133+ print (f"수료증 재발급 완료: { existing_cert_number } " )
134+
135+ return CertificateResponse (
136+ status = "200" ,
137+ message = "기존 수료증이 재발급되었습니다.\n 제출하신 이메일로 수료증이 발송되었습니다." ,
138+ data = CertificateData (
139+ id = existing_page_id ,
140+ name = certificate_data ["applicant_name" ],
141+ recipient_email = certificate_data ["recipient_email" ],
142+ certificate_number = existing_cert_number ,
143+ issue_date = datetime .now ().strftime ("%Y-%m-%d" ),
144+ certificate_status = CertificateStatus .ISSUED ,
145+ season = certificate_data ["season" ],
146+ course_name = certificate_data ["course_name" ],
147+ role = Role .BUILDER if participation_info ["user_role" ] == "BUILDER" else Role .RUNNER
148+ )
149+ )
150+
151+ except Exception as e :
152+ print (f"수료증 재발급 중 오류: { e } " )
153+ raise e
154+
155+ @staticmethod
156+ async def _create_new_certificate (
157+ certificate_data : dict ,
158+ notion_client : NotionClient
159+ ) -> CertificateResponse :
160+ """신규 수료증 발급"""
161+ request_id = None
162+ try :
53163 # 수료증 요청 내역 생성
54164 certificate_request = await notion_client .create_certificate_request (certificate_data )
55165
@@ -121,17 +231,10 @@ async def create_certificate(certificate_data: dict) -> CertificateResponse:
121231
122232 except Exception as e :
123233 # 시스템 오류
124- print (f"시스템 오류: { e } " )
234+ print (f"신규 수료증 발급 중 시스템 오류: { e } " )
125235 if request_id : # request_id가 존재하는 경우에만 상태 업데이트
126236 await notion_client .update_certificate_status (
127237 page_id = request_id ,
128238 status = CertificateStatus .SYSTEM_ERROR
129239 )
130- raise HTTPException (
131- status_code = 500 ,
132- detail = {
133- "status" : ResponseStatus .FAIL ,
134- "error_code" : ErrorCodes .PIPELINE_ERROR ,
135- "message" : f"{ str (e )} "
136- }
137- )
240+ raise e
0 commit comments