|
|
|
@ -129,49 +129,88 @@ class LessonCompletionToggleAPIView(GenericAPIView): |
|
|
|
authentication_classes = [TokenAuthentication] |
|
|
|
|
|
|
|
@swagger_auto_schema( |
|
|
|
operation_description="Toggle lesson completion status (Check/Uncheck)", |
|
|
|
operation_description="Toggle lesson completion status (for single ID) or mark multiple lessons as completed (for list of IDs)", |
|
|
|
tags=["Imam-Javad - Course"], |
|
|
|
request_body=openapi.Schema( |
|
|
|
type=openapi.TYPE_OBJECT, |
|
|
|
required=['lesson_id'], |
|
|
|
properties={ |
|
|
|
'lesson_id': openapi.Schema(type=openapi.TYPE_INTEGER, description='ID of the lesson to toggle'), |
|
|
|
'lesson_id': openapi.Schema( |
|
|
|
type=openapi.TYPE_INTEGER, |
|
|
|
description='ID of the lesson to toggle (integer), or list of IDs to mark completed (array of integers)' |
|
|
|
), |
|
|
|
}, |
|
|
|
), |
|
|
|
responses={ |
|
|
|
201: 'Lesson marked as COMPLETED.', |
|
|
|
200: 'Lesson marked as INCOMPLETE (Unchecked).', |
|
|
|
400: 'Lesson ID is required.', |
|
|
|
200: 'Lesson marked as INCOMPLETE (Unchecked) or Bulk operation completed.', |
|
|
|
400: 'Lesson ID is required or invalid.', |
|
|
|
404: 'Lesson not found.', |
|
|
|
} |
|
|
|
) |
|
|
|
def post(self, request): |
|
|
|
student = request.user |
|
|
|
lesson_id = request.data.get('lesson_id') |
|
|
|
lesson_id_data = request.data.get('lesson_id') |
|
|
|
|
|
|
|
if not lesson_id: |
|
|
|
if not lesson_id_data: |
|
|
|
return Response({'error': 'Lesson ID is required.'}, status=status.HTTP_400_BAD_REQUEST) |
|
|
|
|
|
|
|
# List Case: |
|
|
|
if isinstance(lesson_id_data, list): |
|
|
|
try: |
|
|
|
lesson_ids = [int(lid) for lid in lesson_id_data] |
|
|
|
except (ValueError, TypeError): |
|
|
|
return Response({'error': 'Invalid lesson ID in list.'}, status=status.HTTP_400_BAD_REQUEST) |
|
|
|
|
|
|
|
course_lessons = CourseLesson.objects.filter(id__in=lesson_ids) |
|
|
|
found_ids = set(course_lessons.values_list('id', flat=True)) |
|
|
|
|
|
|
|
existing_completions = LessonCompletion.objects.filter( |
|
|
|
student=student, |
|
|
|
course_lesson_id__in=found_ids |
|
|
|
).values_list('course_lesson_id', flat=True) |
|
|
|
existing_completed_set = set(existing_completions) |
|
|
|
|
|
|
|
completions_to_create = [] |
|
|
|
for cl in course_lessons: |
|
|
|
if cl.id not in existing_completed_set: |
|
|
|
completions_to_create.append( |
|
|
|
LessonCompletion(student=student, course_lesson=cl) |
|
|
|
) |
|
|
|
|
|
|
|
if completions_to_create: |
|
|
|
LessonCompletion.objects.bulk_create(completions_to_create) |
|
|
|
|
|
|
|
return Response( |
|
|
|
{ |
|
|
|
'message': f'Completed {len(completions_to_create)} new lessons.', |
|
|
|
'completed_ids': list(found_ids) |
|
|
|
}, |
|
|
|
status=status.HTTP_200_OK |
|
|
|
) |
|
|
|
|
|
|
|
# Single Integer Case: |
|
|
|
else: |
|
|
|
try: |
|
|
|
lesson_id = int(lesson_id_data) |
|
|
|
except (ValueError, TypeError): |
|
|
|
return Response({'error': 'Invalid lesson ID.'}, status=status.HTTP_400_BAD_REQUEST) |
|
|
|
|
|
|
|
try: |
|
|
|
course_lesson = CourseLesson.objects.get(id=lesson_id) |
|
|
|
except CourseLesson.DoesNotExist: |
|
|
|
return Response({'error': 'Lesson not found.'}, status=status.HTTP_404_NOT_FOUND) |
|
|
|
|
|
|
|
# TOGGLE LOGIC |
|
|
|
# Try to find an existing completion record |
|
|
|
completion = LessonCompletion.objects.filter(student=student, course_lesson=course_lesson).first() |
|
|
|
|
|
|
|
if completion: |
|
|
|
# Scenario: The user clicked by mistake or wants to un-check |
|
|
|
# Action: Delete the record |
|
|
|
completion.delete() |
|
|
|
return Response( |
|
|
|
{'message': 'Lesson marked as incomplete.', 'is_completed': False}, |
|
|
|
status=status.HTTP_200_OK |
|
|
|
) |
|
|
|
else: |
|
|
|
# Scenario: The lesson is not finished yet |
|
|
|
# Action: Create the record |
|
|
|
LessonCompletion.objects.create(student=student, course_lesson=course_lesson) |
|
|
|
return Response( |
|
|
|
{'message': 'Lesson completed successfully.', 'is_completed': True}, |
|
|
|
|