|
19 | 19 | PeerReviewState, |
20 | 20 | ReviewCriteria, |
21 | 21 | ProjectEvaluationScore, |
| 22 | + Enrollment, |
22 | 23 | ) |
23 | 24 | from courses.scoring import ( |
24 | 25 | score_homework_submissions, |
25 | 26 | fill_correct_answers, |
26 | 27 | calculate_homework_statistics, |
27 | 28 | calculate_project_statistics, |
| 29 | + update_leaderboard, |
28 | 30 | ) |
29 | 31 | from courses.projects import ( |
30 | 32 | assign_peer_reviews_for_project, |
@@ -346,3 +348,122 @@ def project_submission_edit(request, course_slug, project_slug, submission_id): |
346 | 348 |
|
347 | 349 | return render(request, "cadmin/project_submission_edit.html", context) |
348 | 350 |
|
| 351 | + |
| 352 | +@staff_required |
| 353 | +def enrollments_list(request, course_slug): |
| 354 | + """List all enrollments for a course""" |
| 355 | + from django.db.models import Count |
| 356 | + |
| 357 | + course = get_object_or_404(Course, slug=course_slug) |
| 358 | + |
| 359 | + # Get all enrollments with related student data and submission counts, ordered by leaderboard position |
| 360 | + enrollments = Enrollment.objects.filter(course=course).select_related('student').annotate( |
| 361 | + homework_count=Count('submission', distinct=True), |
| 362 | + project_count=Count('projectsubmission', distinct=True) |
| 363 | + ).order_by('position_on_leaderboard', 'id') |
| 364 | + |
| 365 | + context = { |
| 366 | + "course": course, |
| 367 | + "enrollments": enrollments, |
| 368 | + } |
| 369 | + |
| 370 | + return render(request, "cadmin/enrollments.html", context) |
| 371 | + |
| 372 | + |
| 373 | +@staff_required |
| 374 | +def enrollment_edit(request, course_slug, enrollment_id): |
| 375 | + """Edit an enrollment - mainly to disable learning in public""" |
| 376 | + course = get_object_or_404(Course, slug=course_slug) |
| 377 | + enrollment = get_object_or_404(Enrollment, id=enrollment_id, course=course) |
| 378 | + |
| 379 | + if request.method == "POST": |
| 380 | + # Handle the disable learning in public toggle |
| 381 | + action = request.POST.get("action") |
| 382 | + |
| 383 | + if action == "toggle_learning_in_public": |
| 384 | + # Toggle the flag |
| 385 | + enrollment.disable_learning_in_public = not enrollment.disable_learning_in_public |
| 386 | + enrollment.save() |
| 387 | + |
| 388 | + # If we're disabling, zero out all learning in public scores |
| 389 | + if enrollment.disable_learning_in_public: |
| 390 | + # Zero out homework learning in public scores |
| 391 | + homework_submissions = list(Submission.objects.filter(enrollment=enrollment)) |
| 392 | + submissions_to_update = [] |
| 393 | + for submission in homework_submissions: |
| 394 | + if submission.learning_in_public_score > 0: |
| 395 | + submission.learning_in_public_score = 0 |
| 396 | + # Recalculate total score |
| 397 | + submission.total_score = ( |
| 398 | + submission.questions_score + |
| 399 | + submission.faq_score + |
| 400 | + submission.learning_in_public_score |
| 401 | + ) |
| 402 | + submissions_to_update.append(submission) |
| 403 | + |
| 404 | + if submissions_to_update: |
| 405 | + Submission.objects.bulk_update( |
| 406 | + submissions_to_update, |
| 407 | + ['learning_in_public_score', 'total_score'] |
| 408 | + ) |
| 409 | + |
| 410 | + # Zero out project learning in public scores |
| 411 | + project_submissions = list(ProjectSubmission.objects.filter(enrollment=enrollment)) |
| 412 | + project_submissions_to_update = [] |
| 413 | + for submission in project_submissions: |
| 414 | + if submission.project_learning_in_public_score > 0 or submission.peer_review_learning_in_public_score > 0: |
| 415 | + submission.project_learning_in_public_score = 0 |
| 416 | + submission.peer_review_learning_in_public_score = 0 |
| 417 | + # Recalculate total score |
| 418 | + submission.total_score = ( |
| 419 | + submission.project_score + |
| 420 | + submission.project_faq_score + |
| 421 | + submission.project_learning_in_public_score + |
| 422 | + submission.peer_review_score + |
| 423 | + submission.peer_review_learning_in_public_score |
| 424 | + ) |
| 425 | + project_submissions_to_update.append(submission) |
| 426 | + |
| 427 | + if project_submissions_to_update: |
| 428 | + ProjectSubmission.objects.bulk_update( |
| 429 | + project_submissions_to_update, |
| 430 | + ['project_learning_in_public_score', 'peer_review_learning_in_public_score', 'total_score'] |
| 431 | + ) |
| 432 | + |
| 433 | + messages.success( |
| 434 | + request, |
| 435 | + f"Learning in public disabled for {enrollment.student.username}. All scores zeroed out." |
| 436 | + ) |
| 437 | + else: |
| 438 | + messages.success( |
| 439 | + request, |
| 440 | + f"Learning in public re-enabled for {enrollment.student.username}. You may need to re-score homework and projects." |
| 441 | + ) |
| 442 | + |
| 443 | + # Recalculate the leaderboard for the course |
| 444 | + update_leaderboard(course) |
| 445 | + |
| 446 | + return redirect("cadmin_enrollment_edit", course_slug=course_slug, enrollment_id=enrollment_id) |
| 447 | + |
| 448 | + # Get some stats about this enrollment |
| 449 | + homework_submissions = Submission.objects.filter(enrollment=enrollment) |
| 450 | + project_submissions = ProjectSubmission.objects.filter(enrollment=enrollment) |
| 451 | + |
| 452 | + total_homework_lip_score = sum(s.learning_in_public_score for s in homework_submissions) |
| 453 | + total_project_lip_score = sum( |
| 454 | + s.project_learning_in_public_score + s.peer_review_learning_in_public_score |
| 455 | + for s in project_submissions |
| 456 | + ) |
| 457 | + |
| 458 | + context = { |
| 459 | + "course": course, |
| 460 | + "enrollment": enrollment, |
| 461 | + "homework_submissions_count": homework_submissions.count(), |
| 462 | + "project_submissions_count": project_submissions.count(), |
| 463 | + "total_homework_lip_score": total_homework_lip_score, |
| 464 | + "total_project_lip_score": total_project_lip_score, |
| 465 | + } |
| 466 | + |
| 467 | + return render(request, "cadmin/enrollment_edit.html", context) |
| 468 | + |
| 469 | + |
0 commit comments