diff --git a/server/config/urls.py b/server/config/urls.py index 95e99b31..2635d1d5 100644 --- a/server/config/urls.py +++ b/server/config/urls.py @@ -7,6 +7,9 @@ from django.urls import include, path, re_path from django.views import defaults as default_views from grapple import urls as grapple_urls from ratelimit.exceptions import Ratelimited +from wagtail import urls as wagtail_urls +from wagtail.admin import urls as wagtailadmin_urls +from wagtail.documents import urls as wagtaildocs_urls from vbv_lernwelt.core.middleware.auth import django_view_authentication_exempt from vbv_lernwelt.core.views import ( @@ -24,12 +27,10 @@ from vbv_lernwelt.course.views import ( course_page_api_view, get_course_session_users, get_course_sessions, - mark_course_completion, + mark_course_completion_view, request_course_completion, + request_course_completion_for_user, ) -from wagtail import urls as wagtail_urls -from wagtail.admin import urls as wagtailadmin_urls -from wagtail.documents import urls as wagtaildocs_urls def raise_example_error(request): @@ -67,10 +68,13 @@ urlpatterns = [ name="get_course_session_users"), path(r"api/course/page//", course_page_api_view, name="course_page_api_view"), - path(r"api/course/completion/mark/", mark_course_completion, + path(r"api/course/completion/mark/", mark_course_completion_view, name="mark_course_completion"), path(r"api/course/completion//", request_course_completion, name="request_course_completion"), + path(r"api/course/completion///", + request_course_completion_for_user, + name="request_course_completion_for_user"), # testing and debug path('server/raise_error/', diff --git a/server/vbv_lernwelt/course/management/commands/create_default_courses.py b/server/vbv_lernwelt/course/management/commands/create_default_courses.py index 0d7a770d..488fcb0c 100644 --- a/server/vbv_lernwelt/course/management/commands/create_default_courses.py +++ b/server/vbv_lernwelt/course/management/commands/create_default_courses.py @@ -1,4 +1,5 @@ import djclick as click +from wagtail.models import Page from vbv_lernwelt.competence.create_default_competence_profile import ( create_default_competence_profile, @@ -15,6 +16,7 @@ from vbv_lernwelt.course.creators.versicherungsvermittlerin import ( create_versicherungsvermittlerin_with_categories, ) from vbv_lernwelt.course.models import CourseSession, CourseSessionUser +from vbv_lernwelt.course.services import mark_course_completion from vbv_lernwelt.learnpath.create_default_learning_path import ( create_default_learning_path, ) @@ -114,7 +116,7 @@ def command(): # user=User.objects.get(username="student-uk1-bern@eiger-versicherungen.ch"), # ) - # figma demo users + # figma demo users and data csu = CourseSessionUser.objects.create( course_session=cs, user=User.objects.get(username="patrizia.huggel@eiger-versicherung.ch"), @@ -127,6 +129,24 @@ def command(): course_session=cs, user=User.objects.get(username="michael.meier@example.com"), ) + for slug in [ + "überbetriebliche-kurse-lp-circle-einstieg-lc-verschaff-dir-einen-überblick", + "überbetriebliche-kurse-lp-circle-einstieg-lc-mediathek", + "überbetriebliche-kurse-lp-circle-einstieg-lc-patrizia-marco-sichern-sich-ab", + "überbetriebliche-kurse-lp-circle-einstieg-lc-fachcheck-einkommenssicherung", + "überbetriebliche-kurse-competence-crit-a21-einkommenssicherung", + "überbetriebliche-kurse-competence-crit-a22-einkommenssicherung", + "überbetriebliche-kurse-competence-crit-a23-einkommenssicherung", + "überbetriebliche-kurse-competence-crit-a24-einkommenssicherung", + "überbetriebliche-kurse-competence-crit-a25-einkommenssicherung", + "überbetriebliche-kurse-competence-crit-b11-einkommenssicherung", + "überbetriebliche-kurse-competence-crit-b12-einkommenssicherung", + "überbetriebliche-kurse-competence-crit-b23-einkommenssicherung", + "überbetriebliche-kurse-lp-circle-einstieg-lc-rafael-fasel-wechselt-sein-auto", + "überbetriebliche-kurse-lp-circle-einstieg-lc-der-erste-eindruck-zählt", + ]: + mark_course_completion(Page.objects.get(slug=slug).translation_key, csu.user) + csu = CourseSessionUser.objects.create( course_session=cs, user=User.objects.get(username="lina.egger@example.com"), diff --git a/server/vbv_lernwelt/course/services.py b/server/vbv_lernwelt/course/services.py new file mode 100644 index 00000000..d8ef5370 --- /dev/null +++ b/server/vbv_lernwelt/course/services.py @@ -0,0 +1,20 @@ +from wagtail.models import Page + +from vbv_lernwelt.course.models import CourseCompletion +from vbv_lernwelt.learnpath.utils import get_wagtail_type + + +def mark_course_completion(page_key, user, completion_status="success"): + page = Page.objects.get(translation_key=page_key, locale__language_code="de-CH") + page_type = get_wagtail_type(page.specific) + course = page.specific.get_course() + cc, created = CourseCompletion.objects.get_or_create( + user=user, + page_key=page_key, + course_id=course.id, + ) + cc.page_slug = page.slug + cc.page_type = page_type + cc.completion_status = completion_status + cc.save() + return cc diff --git a/server/vbv_lernwelt/course/views.py b/server/vbv_lernwelt/course/views.py index 0b12650d..0428318a 100644 --- a/server/vbv_lernwelt/course/views.py +++ b/server/vbv_lernwelt/course/views.py @@ -14,6 +14,7 @@ from vbv_lernwelt.course.serializers import ( CourseCompletionSerializer, CourseSessionSerializer, ) +from vbv_lernwelt.course.services import mark_course_completion from vbv_lernwelt.learnpath.utils import get_wagtail_type logger = structlog.get_logger(__name__) @@ -39,11 +40,10 @@ def course_page_api_view(request, slug): return Response({"error": str(e)}, status=404) -@api_view(["GET"]) -def request_course_completion(request, course_id): +def _request_course_completion(course_id, user_id): try: response_data = CourseCompletionSerializer( - CourseCompletion.objects.filter(user=request.user, course_id=course_id), + CourseCompletion.objects.filter(user_id=user_id, course_id=course_id), many=True, ).data @@ -55,28 +55,32 @@ def request_course_completion(request, course_id): return Response({"error": str(e)}, status=404) +@api_view(["GET"]) +def request_course_completion(request, course_id): + return _request_course_completion(course_id, request.user.id) + + +@api_view(["GET"]) +def request_course_completion_for_user(request, course_id, user_id): + # TODO: check permissions to access this users data + return _request_course_completion(course_id, user_id) + + @api_view(["POST"]) -def mark_course_completion(request): +def mark_course_completion_view(request): try: page_key = request.data.get("page_key") completion_status = request.data.get("completion_status", "success") - page = Page.objects.get(translation_key=page_key, locale__language_code="de-CH") + if not has_course_access_by_page_request(request, page): raise PermissionDenied() page_type = get_wagtail_type(page.specific) course = page.specific.get_course() - cc, created = CourseCompletion.objects.get_or_create( - user=request.user, - page_key=page_key, - course_id=course.id, - ) - cc.page_slug = page.slug - cc.page_type = page_type - cc.completion_status = completion_status - cc.save() + mark_course_completion(page_key, request.user, + completion_status=completion_status) response_data = CourseCompletionSerializer( CourseCompletion.objects.filter(user=request.user, course_id=course.id),