Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updating the Certification Page for course based trainings #2223

Merged
33 changes: 20 additions & 13 deletions physionet-django/training/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,24 @@ def get_course_and_module_progress(user, course, module_order):
This function takes a user, course, and module order as input parameters,
and returns the course progress and module progress objects associated with the user, course, and module order.
"""
course_progress, _ = CourseProgress.objects.get_or_create(user=user, course=course)
# get the course progress of the user for the course
course_progress = CourseProgress.objects.filter(user=user, course=course).first()
if not course_progress:
course_progress = CourseProgress.objects.create(user=user, course=course)
# Initiate the training and set the status to review
slug = get_random_string(20)
while Training.objects.filter(slug=slug).exists():
slug = get_random_string(20)
Training.objects.create(
slug=slug,
training_type=course.training_type,
user=user,
course=course,
process_datetime=timezone.now(),
status=TrainingStatus.IN_PROGRESS
)


module = get_object_or_404(course.modules, order=module_order)
module_progress, _ = ModuleProgress.objects.get_or_create(course_progress=course_progress, module=module)
return course_progress, module_progress
Expand Down Expand Up @@ -88,16 +105,7 @@ def handle_course_completion(course, course_progress):
with transaction.atomic():
course_progress.status = CourseProgress.Status.COMPLETED
course_progress.save()
training = Training()
slug = get_random_string(20)
while Training.objects.filter(slug=slug).exists():
slug = get_random_string(20)

training.slug = slug
training.training_type = course_progress.course.training_type
training.course = course_progress.course
training.user = course_progress.user
training.process_datetime = timezone.now()
training = Training.objects.filter(course=course, user=course_progress.user).first()
training.status = TrainingStatus.ACCEPTED
training.save()

Expand Down Expand Up @@ -275,8 +283,7 @@ def take_training(request, training_slug):
if course is None:
raise Http404()
modules = Module.objects.filter(course=course).order_by('order')
# get the progress of the user for the modules, updated_date
course_progress, _ = CourseProgress.objects.get_or_create(user=request.user, course=course)
course_progress, _ = get_course_and_module_progress(request.user, course, modules.first().order)

for module in modules:
module_progress = course_progress.module_progresses.filter(module_id=module.id).last()
Expand Down
1 change: 1 addition & 0 deletions physionet-django/user/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class TrainingStatus(IntEnum):
WITHDRAWN = 1
REJECTED = 2
ACCEPTED = 3
IN_PROGRESS = 4

@classmethod
def choices(cls):
Expand Down
55 changes: 47 additions & 8 deletions physionet-django/user/managers.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,71 @@
from django.db.models import DateTimeField, ExpressionWrapper, QuerySet, F, Q
from django.db.models import (DateTimeField, ExpressionWrapper, QuerySet, F, Q,
OuterRef, Subquery, Case, When)
from django.utils import timezone

from user.enums import TrainingStatus

from user.enums import TrainingStatus, RequiredField
from training.models import Course

class TrainingQuerySet(QuerySet):
def get_review(self):
return self.filter(status=TrainingStatus.REVIEW)
"""
Rutvikrj26 marked this conversation as resolved.
Show resolved Hide resolved
Get the document-based or URL-based training objects for the user, that are in the status REVIEW.
"""
return self.filter(
Q(status=TrainingStatus.REVIEW),
Q(training_type__required_field=RequiredField.DOCUMENT)
| Q(training_type__required_field=RequiredField.URL)
)

def get_in_progress(self):
"""
Get the on-platform training objects for the user, that are in the status REVIEW.
"""
Rutvikrj26 marked this conversation as resolved.
Show resolved Hide resolved
return self.filter(
Q(status=TrainingStatus.IN_PROGRESS),
Rutvikrj26 marked this conversation as resolved.
Show resolved Hide resolved
Q(training_type__required_field=RequiredField.PLATFORM)
)

def get_valid(self):
"""
Get all the training objects that are in the status ACCEPTED and have not expired.
"""
return self.filter(
Q(status=TrainingStatus.ACCEPTED),
Q(training_type__valid_duration__isnull=True)
| Q(process_datetime__gte=timezone.now() - F('training_type__valid_duration')),
| Q(process_datetime__gte=timezone.now() - Case(
When(training_type__required_field=RequiredField.PLATFORM, then=F('course__valid_duration')),
default=F('training_type__valid_duration')
)),
).annotate(
valid_datetime=ExpressionWrapper(
F('process_datetime') + F('training_type__valid_duration'), output_field=DateTimeField()
F('process_datetime') + Case(
When(training_type__required_field=RequiredField.PLATFORM, then=F('course__valid_duration')),
default=F('training_type__valid_duration')
), output_field=DateTimeField()
)
)

def get_expired(self):
"""
Get all the training objects that are in the status ACCEPTED and have expired
"""
return self.filter(
status=TrainingStatus.ACCEPTED, process_datetime__lt=timezone.now() - F('training_type__valid_duration')
Q(status=TrainingStatus.ACCEPTED),
Q(process_datetime__lt=timezone.now() - Case(
When(training_type__required_field=RequiredField.PLATFORM, then=F('course__valid_duration')),
default=F('training_type__valid_duration')
)),
).annotate(
valid_datetime=ExpressionWrapper(
F('process_datetime') + F('training_type__valid_duration'), output_field=DateTimeField()
F('process_datetime') + Case(
When(training_type__required_field=RequiredField.PLATFORM, then=F('course__valid_duration')),
default=F('training_type__valid_duration')
), output_field=DateTimeField()
)
)

def get_rejected(self):
"""
Get all the training objects that are in the status REJECTED.
"""
return self.filter(status=TrainingStatus.REJECTED)
28 changes: 28 additions & 0 deletions physionet-django/user/migrations/0063_alter_training_status.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Generated by Django 4.2.14 on 2024-11-15 00:47

from django.db import migrations, models
import user.enums


class Migration(migrations.Migration):

dependencies = [
("user", "0062_training_course"),
]

operations = [
migrations.AlterField(
model_name="training",
name="status",
field=models.PositiveSmallIntegerField(
choices=[
(0, "REVIEW"),
(1, "WITHDRAWN"),
(2, "REJECTED"),
(3, "ACCEPTED"),
(4, "IN_PROGRESS"),
],
default=user.enums.TrainingStatus["REVIEW"],
),
),
]
3 changes: 3 additions & 0 deletions physionet-django/user/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -824,11 +824,14 @@ def edit_certification(request):
)
training_by_status = {
"under review": training.get_review(),
"in progress": training.get_in_progress(),
"active": training.get_valid(),
"expired": training.get_expired(),
"rejected": training.get_rejected(),
}

print(training_by_status)
Rutvikrj26 marked this conversation as resolved.
Show resolved Hide resolved

return render(
request,
"user/edit_certification.html",
Expand Down
Loading