from rest_framework import serializers # from dj_filer.admin import get_thumbs from utils import get_thumbs from apps.course.models import Course, CourseCategory, Attachment, Glossary, LessonCompletion, Participant, Lesson, CourseAttachment, CourseGlossary, CourseLesson from apps.chat.models import RoomMessage from apps.account.serializers import UserProfileSerializer class CourseCategorySerializer(serializers.ModelSerializer): course_count = serializers.SerializerMethodField() class Meta: model = CourseCategory fields = ['name', 'slug', 'course_count'] def get_course_count(self, obj): return obj.course_count class CourseListSerializer(serializers.ModelSerializer): category = CourseCategorySerializer() thumbnail = serializers.SerializerMethodField() participant_count = serializers.SerializerMethodField() lessons_count = serializers.SerializerMethodField() price = serializers.SerializerMethodField() discount_percentage = serializers.SerializerMethodField() final_price = serializers.SerializerMethodField() class Meta: model = Course fields = [ 'id', 'title', 'slug', 'participant_count', 'category', 'thumbnail', 'is_online', 'online_link', 'level', 'duration', 'lessons_count', 'short_description', 'status', 'is_free', 'price', 'discount_percentage', 'final_price', ] def get_thumbnail(self, obj): return get_thumbs(obj.thumbnail, self.context.get('request')) def get_participant_count(self, obj): return obj.participants.count() def get_lessons_count(self, obj): lessons_count = obj.lessons.filter(is_active=True).count() return max(lessons_count, obj.lessons_count) def get_price(self, obj): return 0 if obj.is_free else obj.price def get_discount_percentage(self, obj): return 0 if obj.is_free else obj.discount_percentage def get_final_price(self, obj): return 0 if obj.is_free else obj.final_price class CourseDetailSerializer(serializers.ModelSerializer): category = CourseCategorySerializer() professor = UserProfileSerializer() thumbnail = serializers.SerializerMethodField() participant_count = serializers.SerializerMethodField() access = serializers.SerializerMethodField() lessons_complated_count = serializers.SerializerMethodField() lessons_count = serializers.SerializerMethodField() last_lesson_id = serializers.SerializerMethodField() room_id = serializers.SerializerMethodField() user_transaction_status = serializers.SerializerMethodField() price = serializers.SerializerMethodField() discount_percentage = serializers.SerializerMethodField() final_price = serializers.SerializerMethodField() class Meta: model = Course fields = [ 'id', 'title', 'slug', 'category', 'access', 'participant_count', 'professor', 'thumbnail', 'video_type', 'video_file', 'video_link', 'is_online', 'online_link', 'level', 'description', 'duration', 'lessons_count', 'lessons_complated_count', 'short_description', 'status', 'is_free', 'price', 'discount_percentage', 'final_price', 'timing', 'features', 'last_lesson_id', 'room_id', 'user_transaction_status' ] def get_room_id(self, obj): room_message = RoomMessage.objects.filter(course=obj).first() if room_message: return room_message.id return None def get_user_transaction_status(self, obj): from apps.transaction.models import TransactionParticipant if student := self._get_authenticated_user(): latest_transaction = TransactionParticipant.objects.filter( user=student, course=obj, is_deleted=False ).order_by('-created_at').first() if latest_transaction: return latest_transaction.status return None def get_last_lesson_id(self, obj): request = self.context.get('request') if request and request.user.is_authenticated: user = request.user # آخرین درس تکمیل‌شده توسط کاربر last_completed_lesson = LessonCompletion.objects.filter( student=user, course_lesson__course=obj ).order_by('-completed_at').first() if last_completed_lesson: # پیدا کردن درس بعدی بر اساس priority next_lesson = CourseLesson.objects.filter( course=obj, priority__gt=last_completed_lesson.course_lesson.priority, is_active=True ).order_by('priority').first() if not next_lesson: next_lesson = CourseLesson.objects.filter( course=obj, is_active=True ).order_by('priority').first() if next_lesson: return next_lesson.id return None def get_access(self, obj): if student := self._get_authenticated_user(): if not self._is_participant(student, obj): return False return True return False def get_is_professor(self, obj): if professor := self._get_authenticated_user(): return obj.professor == professor return False def get_lessons_count(self, obj): lessons_count = obj.lessons.filter(is_active=True).count() return max(lessons_count, obj.lessons_count) def get_lessons_complated_count(self, obj): if student := self._get_authenticated_user(): if not self._is_participant(student, obj): return None return self._get_completed_lessons_count(student, obj) return None def _is_participant(self, student, course): """Helper method to check if a student is a participant in the given course.""" return Participant.objects.filter(student=student, course=course).exists() def _get_authenticated_user(self): """Helper method to retrieve the authenticated user from the context.""" request = self.context.get('request') return request.user if request and request.user.is_authenticated else None def _get_completed_lessons_count(self, student, course): """Helper method to count completed lessons for the student in the given course.""" return LessonCompletion.objects.filter( student=student, course_lesson__course=course ).count() def get_thumbnail(self, obj): return get_thumbs(obj.thumbnail, self.context.get('request')) def get_participant_count(self, obj): return obj.participants.count() def get_price(self, obj): return 0 if obj.is_free else obj.price def get_discount_percentage(self, obj): return 0 if obj.is_free else obj.discount_percentage def get_final_price(self, obj): return 0 if obj.is_free else obj.final_price class MyCourseListSerializer(serializers.ModelSerializer): category = CourseCategorySerializer() thumbnail = serializers.SerializerMethodField() lessons_complated_count = serializers.SerializerMethodField() class Meta: model = Course fields = [ 'id', 'title', 'slug', 'category', 'thumbnail', 'lessons_count', 'lessons_complated_count', 'short_description', 'status', ] def get_thumbnail(self, obj): return get_thumbs(obj.thumbnail, self.context.get('request')) def get_lessons_complated_count(self, obj): if student := self._get_authenticated_user(): if not self._is_participant(student, obj): return None return self._get_completed_lessons_count(student, obj) return None def _is_participant(self, student, course): """Helper method to check if a student is a participant in the given course.""" return Participant.objects.filter(student=student, course=course).exists() def _get_authenticated_user(self): """Helper method to retrieve the authenticated user from the context.""" request = self.context.get('request') return request.user if request and request.user.is_authenticated else None def _get_completed_lessons_count(self, student, course): """Helper method to count completed lessons for the student in the given course.""" return LessonCompletion.objects.filter( student=student, course_lesson__course=course ).count() class AttachmentSerializer(serializers.ModelSerializer): class Meta: model = Attachment fields = ['id', 'title', 'file', 'file_size'] class CourseAttachmentSerializer(serializers.ModelSerializer): title = serializers.CharField(source='attachment.title', read_only=True) file = serializers.FileField(source='attachment.file', read_only=True) file_size = serializers.IntegerField(source='attachment.file_size', read_only=True) class Meta: model = CourseAttachment fields = ['id', 'title', 'file', 'file_size'] class GlossarySerializer(serializers.ModelSerializer): class Meta: model = Glossary fields = ['id', 'title', 'description'] class CourseGlossarySerializer(serializers.ModelSerializer): title = serializers.CharField(source='glossary.title', read_only=True) description = serializers.CharField(source='glossary.description', read_only=True) class Meta: model = CourseGlossary fields = ['id', 'title', 'description']