diff --git a/server/config/urls.py b/server/config/urls.py index 00ea7d18..71f35177 100644 --- a/server/config/urls.py +++ b/server/config/urls.py @@ -37,6 +37,7 @@ from vbv_lernwelt.course.views import ( request_course_completion, request_course_completion_for_user, ) +from vbv_lernwelt.edoniq_test.views import export_students from vbv_lernwelt.feedback.views import ( get_expert_feedbacks_for_course, get_feedback_for_circle, @@ -139,6 +140,9 @@ urlpatterns = [ path("server/graphql/", csrf_exempt(GraphQLView.as_view(graphiql=True, schema=schema))), + # edoniq test + path(r'api/core/edoniq-test/export-users/', export_students, name='edoniq_export_students'), + # testing and debug path('server/raise_error/', user_passes_test(lambda u: u.is_superuser, login_url='/login/')( diff --git a/server/vbv_lernwelt/course/creators/test_course.py b/server/vbv_lernwelt/course/creators/test_course.py index 0baf416c..0f486e3b 100644 --- a/server/vbv_lernwelt/course/creators/test_course.py +++ b/server/vbv_lernwelt/course/creators/test_course.py @@ -97,6 +97,7 @@ def create_test_course(include_uk=True, include_vv=True, with_sessions=False): cs_bern = CourseSession.objects.create( course_id=COURSE_TEST_ID, title="Test Bern 2022 a", + import_id="Test Bern 2022 a", id=TEST_COURSE_SESSION_BERN_ID, start_date=now, ) @@ -142,6 +143,7 @@ def create_test_course(include_uk=True, include_vv=True, with_sessions=False): cs_zurich = CourseSession.objects.create( course_id=COURSE_TEST_ID, title="Test Zürich 2022 a", + import_id="Test Zürich 2022 a", id=TEST_COURSE_SESSION_ZURICH_ID, start_date=now, ) diff --git a/server/vbv_lernwelt/edoniq_test/__init__.py b/server/vbv_lernwelt/edoniq_test/__init__.py new file mode 100644 index 00000000..c5fffec4 --- /dev/null +++ b/server/vbv_lernwelt/edoniq_test/__init__.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class LearnpathConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = "vbv_lernwelt.edoniq_test" diff --git a/server/vbv_lernwelt/edoniq_test/tests/__init__.py b/server/vbv_lernwelt/edoniq_test/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/server/vbv_lernwelt/edoniq_test/tests/test_edoniq_export.py b/server/vbv_lernwelt/edoniq_test/tests/test_edoniq_export.py new file mode 100644 index 00000000..735e34e8 --- /dev/null +++ b/server/vbv_lernwelt/edoniq_test/tests/test_edoniq_export.py @@ -0,0 +1,83 @@ +import csv + +from django.test import TestCase + +from vbv_lernwelt.core.admin import User +from vbv_lernwelt.core.create_default_users import create_default_users +from vbv_lernwelt.course.consts import COURSE_TEST_ID +from vbv_lernwelt.course.creators.test_course import create_test_course +from vbv_lernwelt.edoniq_test.views import ( + fetch_course_session_users, + generate_export_response, +) + + +class EdoniqUserExportTestCase(TestCase): + def setUp(self) -> None: + create_default_users() + create_test_course(with_sessions=True) + + user1 = User.objects.get(email="test-student1@example.com") + user1.additional_json_data = { + "Lehrvertragsnummer": "23456", + "Geburtsdatum": "01.01.1991", + } + user1.save() + + user2 = User.objects.get(email="test-student2@example.com") + user2.additional_json_data = { + "Firmenname": "Test AG", + "Lehrvertragsnummer": "12345", + "Geburtsdatum": "01.01.1990", + } + user2.save() + + def test_fetch_course_session_users(self): + users = fetch_course_session_users([COURSE_TEST_ID]) + self.assertEqual(len(users), 3) + + def test_response_csv(self): + users = fetch_course_session_users([COURSE_TEST_ID]) + response = generate_export_response(users) + + user_data = [ + [ + user.user.email, + user.user.first_name, + user.user.last_name, + "m", + user.user.language, + user.user.email, + user.user.additional_json_data.get("Geburtsdatum", ""), + "Lernender", + user.user.additional_json_data.get("Firmenname", ""), + user.user.additional_json_data.get("Lehrvertragsnummer", ""), + user.course_session.import_id, + "", + ] + for user in users + ] + + expected_response_data = [ + [ + "login", + "firstName", + "lastName", + "gender", + "preferredLanguage", + "emailBusiness", + "birthday", + "group", + "region", + "division", + "organisationUnit", + "superiorLogin", + ], + ] + user_data + + # Perform assertions on the response + self.assertEqual(response.status_code, 200) + csv_data = response.content.decode("utf-8") + reader = csv.reader(csv_data.splitlines()) + response_data = list(reader) + self.assertEqual(response_data, expected_response_data) diff --git a/server/vbv_lernwelt/edoniq_test/views.py b/server/vbv_lernwelt/edoniq_test/views.py new file mode 100644 index 00000000..e156b688 --- /dev/null +++ b/server/vbv_lernwelt/edoniq_test/views.py @@ -0,0 +1,70 @@ +import csv +from datetime import date +from typing import List + +from django.contrib.admin.views.decorators import staff_member_required +from django.http import HttpResponse + +from vbv_lernwelt.course.consts import COURSE_UK, COURSE_UK_FR, COURSE_UK_IT +from vbv_lernwelt.course.models import CourseSessionUser + +UK_COURSE_IDS = [COURSE_UK, COURSE_UK_FR, COURSE_UK_IT] + + +@staff_member_required +def export_students(request): + course_session_users = fetch_course_session_users(UK_COURSE_IDS) + return generate_export_response(course_session_users) + + +def fetch_course_session_users(courses: List[int]): + # if a user is in multiple courses, he should be exported multiple times + # todo: check if this is the case otherwise use .distinct("user") + return CourseSessionUser.objects.filter( + course_session__course__id__in=courses, role=CourseSessionUser.Role.MEMBER + ).order_by("user__email") + + +def generate_export_response(cs_users: List[CourseSessionUser]) -> HttpResponse: + response = HttpResponse(content_type="text/csv") + response[ + "Content-Disposition" + ] = f"attachment; filename=edoniq_user_export_{date.today().strftime('%Y%m%d')}.csv" + + writer = csv.writer(response) + writer.writerow( + [ + "login", + "firstName", + "lastName", + "gender", + "preferredLanguage", + "emailBusiness", + "birthday", + "group", + "region", + "division", + "organisationUnit", + "superiorLogin", + ] + ) + + for cs_user in cs_users: + writer.writerow( + [ + cs_user.user.email, + cs_user.user.first_name, + cs_user.user.last_name, + "m", + cs_user.user.language, + cs_user.user.email, + cs_user.user.additional_json_data.get("Geburtsdatum", ""), + "Lernender", + cs_user.user.additional_json_data.get("Firmenname", ""), + cs_user.user.additional_json_data.get("Lehrvertragsnummer", ""), + cs_user.course_session.import_id, + "", + ] + ) + + return response diff --git a/server/vbv_lernwelt/templates/admin/index.html b/server/vbv_lernwelt/templates/admin/index.html index af12e2f2..31584fb1 100644 --- a/server/vbv_lernwelt/templates/admin/index.html +++ b/server/vbv_lernwelt/templates/admin/index.html @@ -5,10 +5,16 @@ {% include "admin/app_list.html" with app_list=app_list show_changelinks=True %}