""" Сервисы для работы с пользователями. """ import json import logging from django.utils import timezone from django.db.models import Q from django.http import HttpResponse logger = logging.getLogger(__name__) class DataExportService: """Сервис для экспорта данных пользователя (GDPR compliance).""" @staticmethod def export_user_data(user): """ Экспортировать все данные пользователя. Args: user: Объект User Returns: dict: Данные пользователя в формате JSON """ try: data = { 'export_date': timezone.now().isoformat(), 'user': { 'id': user.id, 'email': user.email, 'first_name': user.first_name, 'last_name': user.last_name, 'phone': str(user.phone) if hasattr(user, 'phone') and user.phone else None, 'telegram_id': user.telegram_id, 'telegram_username': user.telegram_username, 'birth_date': user.birth_date.isoformat() if hasattr(user, 'birth_date') and user.birth_date else None, 'date_joined': user.date_joined.isoformat(), 'last_login': user.last_login.isoformat() if user.last_login else None, 'role': user.role, 'is_active': user.is_active, }, 'lessons': [], 'homework': [], 'materials': [], 'subscriptions': [], 'payments': [], 'notifications': [], } # Занятия from apps.schedule.models import Lesson lessons = Lesson.objects.filter( Q(mentor=user) | Q(client__user=user) ).select_related('mentor', 'client', 'subject') for lesson in lessons: lesson_data = { 'id': lesson.id, 'title': lesson.title, 'start_time': lesson.start_time.isoformat() if lesson.start_time else None, 'end_time': lesson.end_time.isoformat() if lesson.end_time else None, 'status': lesson.status, 'subject': lesson.subject.name if lesson.subject else None, 'price': float(lesson.price) if lesson.price else None, 'description': lesson.description, 'created_at': lesson.created_at.isoformat() if lesson.created_at else None, } data['lessons'].append(lesson_data) # Домашние задания from apps.homework.models import Homework, HomeworkSubmission if user.role == 'mentor': homeworks = Homework.objects.filter(mentor=user) else: homeworks = Homework.objects.filter(assigned_to=user) for homework in homeworks: homework_data = { 'id': homework.id, 'title': homework.title, 'description': homework.description, 'deadline': homework.deadline.isoformat() if homework.deadline else None, 'max_score': homework.max_score, 'status': homework.status, 'created_at': homework.created_at.isoformat() if homework.created_at else None, } data['homework'].append(homework_data) # Решения ДЗ # Оптимизация: используем select_related для избежания N+1 запросов submissions = HomeworkSubmission.objects.filter(student=user).select_related('homework') for submission in submissions: submission_data = { 'id': submission.id, 'homework_id': submission.homework.id, 'homework_title': submission.homework.title, 'content': submission.content, 'score': submission.score, 'feedback': submission.feedback, 'status': submission.status, 'submitted_at': submission.submitted_at.isoformat() if submission.submitted_at else None, } data['homework'].append({ 'type': 'submission', **submission_data }) # Подписки from apps.subscriptions.models import Subscription # Оптимизация: используем select_related для избежания N+1 запросов subscriptions = Subscription.objects.filter(user=user).select_related('plan') for subscription in subscriptions: subscription_data = { 'id': subscription.id, 'plan_name': subscription.plan.name if subscription.plan else None, 'status': subscription.status, 'start_date': subscription.start_date.isoformat() if subscription.start_date else None, 'end_date': subscription.end_date.isoformat() if subscription.end_date else None, 'created_at': subscription.created_at.isoformat() if subscription.created_at else None, } data['subscriptions'].append(subscription_data) # Платежи from apps.subscriptions.models import Payment payments = Payment.objects.filter(user=user) for payment in payments: payment_data = { 'id': payment.id, 'amount': float(payment.amount), 'currency': payment.currency, 'status': payment.status, 'payment_method': payment.payment_method, 'created_at': payment.created_at.isoformat() if payment.created_at else None, } data['payments'].append(payment_data) # Уведомления (последние 100) from apps.notifications.models import Notification notifications = Notification.objects.filter(recipient=user).order_by('-created_at')[:100] for notification in notifications: notification_data = { 'id': notification.id, 'title': notification.title, 'message': notification.message, 'notification_type': notification.notification_type, 'is_read': notification.is_read, 'created_at': notification.created_at.isoformat() if notification.created_at else None, } data['notifications'].append(notification_data) return data except Exception as e: logger.error(f"Ошибка экспорта данных пользователя {user.id}: {str(e)}", exc_info=True) return None @staticmethod def generate_export_file(user, format='json'): """ Сгенерировать файл экспорта. Args: user: Объект User format: Формат экспорта ('json') Returns: HttpResponse или None """ data = DataExportService.export_user_data(user) if not data: return None if format == 'json': json_data = json.dumps(data, indent=2, ensure_ascii=False) response = HttpResponse(json_data, content_type='application/json; charset=utf-8') filename = f"user_data_{user.id}_{timezone.now().strftime('%Y%m%d')}.json" response['Content-Disposition'] = f'attachment; filename="{filename}"' return response return None