SillaAMP_V2/B_main/withdrawal_utils.py

278 lines
10 KiB
Python
Raw Permalink Normal View History

"""
회원탈퇴 처리를 위한 유틸리티 함수들
"""
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