""" 회원탈퇴 처리를 위한 유틸리티 함수들 """ from django.contrib.auth.models import User from django.utils import timezone from .models import Person, WithdrawalRequest from .peopleinfo import PEOPLE from .log_utils import log_user_activity from datetime import datetime def find_original_person_data(person_name, phone_number): """ peopleinfo.py에서 원본 Person 데이터 찾기 Args: person_name: 사람 이름 phone_number: 전화번호 (대시 포함 또는 미포함) Returns: dict: 원본 Person 데이터 또는 None """ # 전화번호 정규화 (대시 제거) clean_phone = phone_number.replace('-', '').replace(' ', '') for person_data in PEOPLE: original_name = person_data.get('이름', '') original_phone = person_data.get('연락처', '').replace('-', '').replace(' ', '') if original_name == person_name and original_phone == clean_phone: return person_data return None def backup_user_data(withdrawal_request): """ 탈퇴 전 사용자 데이터 백업 Args: withdrawal_request: WithdrawalRequest 객체 """ try: person = withdrawal_request.person user = withdrawal_request.user backup_data = { 'user_info': { 'username': user.username, 'email': user.email, 'date_joined': user.date_joined.isoformat() if user.date_joined else None, 'last_login': user.last_login.isoformat() if user.last_login else None, }, 'person_info': { '이름': person.이름, '소속': person.소속, '생년월일': person.생년월일.isoformat() if person.생년월일 else None, '직책': person.직책, '연락처': person.연락처, '주소': person.주소, '사진': person.사진.name if person.사진 else None, 'TITLE': person.TITLE, 'SEQUENCE': person.SEQUENCE, 'keyword1': person.keyword1, '소개글': person.소개글, '모든사람보기권한': person.모든사람보기권한, '비밀번호설정필요': person.비밀번호설정필요, '가입일시': person.가입일시.isoformat() if person.가입일시 else None, } } withdrawal_request.backup_data = backup_data withdrawal_request.save() print(f"[WITHDRAWAL] 사용자 데이터 백업 완료: {person.이름}") return True except Exception as e: print(f"[WITHDRAWAL_ERROR] 사용자 데이터 백업 실패: {e}") return False def restore_person_to_original(person): """ Person 데이터를 peopleinfo.py의 원본으로 복원 Args: person: Person 객체 Returns: bool: 성공 여부 """ try: original_data = find_original_person_data(person.이름, person.연락처) if not original_data: print(f"[WITHDRAWAL_ERROR] 원본 데이터를 찾을 수 없음: {person.이름} ({person.연락처})") return False # 원본 데이터로 복원 person.소속 = original_data.get('소속', '') # 생년월일 파싱 birth_str = original_data.get('생년월일', '') if birth_str: try: if '.' in birth_str: person.생년월일 = datetime.strptime(birth_str, '%Y.%m.%d').date() elif len(birth_str) == 4: person.생년월일 = datetime.strptime(f"{birth_str}.01.01", '%Y.%m.%d').date() else: person.생년월일 = None except ValueError: person.생년월일 = None else: person.생년월일 = None person.직책 = original_data.get('직책', '') person.주소 = original_data.get('주소', '') # 사진 경로 처리 photo = original_data.get('사진', 'profile_photos/default_user.png') if photo.startswith('media/'): photo = photo[6:] person.사진 = photo person.TITLE = original_data.get('TITLE', '') # SEQUENCE 처리 sequence = original_data.get('SEQUENCE', None) if sequence and sequence != '': try: person.SEQUENCE = int(sequence) except ValueError: person.SEQUENCE = None else: person.SEQUENCE = None # 회원가입 시 추가된 정보들 초기화 person.user = None # User 연결 해제 person.keyword1 = None person.소개글 = None person.모든사람보기권한 = False person.비밀번호설정필요 = False person.가입일시 = None person.save() print(f"[WITHDRAWAL] Person 데이터 원본 복원 완료: {person.이름}") return True except Exception as e: print(f"[WITHDRAWAL_ERROR] Person 데이터 복원 실패: {e}") return False def process_withdrawal_approval(withdrawal_request, approved_by, admin_notes=None): """ 회원탈퇴 승인 처리 Args: withdrawal_request: WithdrawalRequest 객체 approved_by: 승인자 (User 객체) admin_notes: 관리자 메모 (선택사항) Returns: bool: 성공 여부 """ try: # 1. 사용자 데이터 백업 if not backup_user_data(withdrawal_request): return False # 2. Person 데이터를 원본으로 복원 if not restore_person_to_original(withdrawal_request.person): return False # 3. WithdrawalRequest 상태 업데이트 (User 삭제 전에) withdrawal_request.status = 'APPROVED' withdrawal_request.approved_by = approved_by withdrawal_request.approved_date = timezone.now() withdrawal_request.admin_notes = admin_notes withdrawal_request.save() # 4. SMS 발송 (User 삭제 전에) try: from A_core.sms_utils import send_withdrawal_approval_sms phone_number = withdrawal_request.user.username # username이 전화번호 name = withdrawal_request.person.이름 sms_result = send_withdrawal_approval_sms(phone_number, name) if sms_result.get('success'): print(f"[SMS] 탈퇴 승인 SMS 발송 성공: {name} ({phone_number})") else: print(f"[SMS_ERROR] 탈퇴 승인 SMS 발송 실패: {sms_result.get('error', 'Unknown error')}") except Exception as e: print(f"[SMS_ERROR] 탈퇴 승인 SMS 발송 중 오류: {e}") # 5. 탈퇴 로그 기록 (User 삭제 전에) try: from .log_utils import log_withdrawal_approval # 간단한 request 객체 모방 (로그 기록용) class SimpleRequest: def __init__(self): self.path = '/admin/withdrawal_approval/' self.method = 'POST' self.META = {'HTTP_REFERER': '', 'HTTP_USER_AGENT': 'Admin System'} self.session = {'session_key': 'admin_session'} def session_key(self): return 'admin_session' fake_request = SimpleRequest() log_withdrawal_approval( fake_request, approved_by, withdrawal_request.user.username, withdrawal_request.person.이름, withdrawal_request.id ) except Exception as e: print(f"[WITHDRAWAL_WARNING] 탈퇴 로그 기록 실패: {e}") # 6. User 삭제 user_to_delete = withdrawal_request.user user_username = user_to_delete.username user_to_delete.delete() # 7. WithdrawalRequest의 user 필드를 None으로 설정 (이미 SET_NULL이므로 자동 처리됨) print(f"[WITHDRAWAL] 회원탈퇴 승인 처리 완료: {user_username}") return True except Exception as e: print(f"[WITHDRAWAL_ERROR] 회원탈퇴 승인 처리 실패: {e}") return False def reject_withdrawal_request(withdrawal_request, approved_by, admin_notes=None): """ 회원탈퇴 요청 거부 Args: withdrawal_request: WithdrawalRequest 객체 approved_by: 처리자 (User 객체) admin_notes: 관리자 메모 (선택사항) Returns: bool: 성공 여부 """ try: # 1. SMS 발송 (상태 변경 전에) try: from A_core.sms_utils import send_withdrawal_rejection_sms phone_number = withdrawal_request.user.username # username이 전화번호 name = withdrawal_request.person.이름 reason = admin_notes # 관리자 메모를 거부 사유로 사용 sms_result = send_withdrawal_rejection_sms(phone_number, name, reason) if sms_result.get('success'): print(f"[SMS] 탈퇴 거부 SMS 발송 성공: {name} ({phone_number})") else: print(f"[SMS_ERROR] 탈퇴 거부 SMS 발송 실패: {sms_result.get('error', 'Unknown error')}") except Exception as e: print(f"[SMS_ERROR] 탈퇴 거부 SMS 발송 중 오류: {e}") # 2. 상태 변경 withdrawal_request.status = 'REJECTED' withdrawal_request.approved_by = approved_by withdrawal_request.approved_date = timezone.now() withdrawal_request.admin_notes = admin_notes withdrawal_request.save() print(f"[WITHDRAWAL] 회원탈퇴 요청 거부: {withdrawal_request.person.이름}") return True except Exception as e: print(f"[WITHDRAWAL_ERROR] 회원탈퇴 요청 거부 실패: {e}") return False