Add student export for edoniq

This commit is contained in:
Christian Cueni 2023-07-19 12:04:35 +02:00
parent 6e9d87797e
commit 65d527d894
7 changed files with 175 additions and 4 deletions

View File

@ -37,6 +37,7 @@ from vbv_lernwelt.course.views import (
request_course_completion, request_course_completion,
request_course_completion_for_user, request_course_completion_for_user,
) )
from vbv_lernwelt.edoniq_test.views import export_students
from vbv_lernwelt.feedback.views import ( from vbv_lernwelt.feedback.views import (
get_expert_feedbacks_for_course, get_expert_feedbacks_for_course,
get_feedback_for_circle, get_feedback_for_circle,
@ -139,6 +140,9 @@ urlpatterns = [
path("server/graphql/", path("server/graphql/",
csrf_exempt(GraphQLView.as_view(graphiql=True, schema=schema))), 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 # testing and debug
path('server/raise_error/', path('server/raise_error/',
user_passes_test(lambda u: u.is_superuser, login_url='/login/')( user_passes_test(lambda u: u.is_superuser, login_url='/login/')(

View File

@ -97,6 +97,7 @@ def create_test_course(include_uk=True, include_vv=True, with_sessions=False):
cs_bern = CourseSession.objects.create( cs_bern = CourseSession.objects.create(
course_id=COURSE_TEST_ID, course_id=COURSE_TEST_ID,
title="Test Bern 2022 a", title="Test Bern 2022 a",
import_id="Test Bern 2022 a",
id=TEST_COURSE_SESSION_BERN_ID, id=TEST_COURSE_SESSION_BERN_ID,
start_date=now, 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( cs_zurich = CourseSession.objects.create(
course_id=COURSE_TEST_ID, course_id=COURSE_TEST_ID,
title="Test Zürich 2022 a", title="Test Zürich 2022 a",
import_id="Test Zürich 2022 a",
id=TEST_COURSE_SESSION_ZURICH_ID, id=TEST_COURSE_SESSION_ZURICH_ID,
start_date=now, start_date=now,
) )

View File

@ -0,0 +1,6 @@
from django.apps import AppConfig
class LearnpathConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "vbv_lernwelt.edoniq_test"

View File

@ -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)

View File

@ -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

View File

@ -5,6 +5,12 @@
{% include "admin/app_list.html" with app_list=app_list show_changelinks=True %} {% include "admin/app_list.html" with app_list=app_list show_changelinks=True %}
<div class="content"> <div class="content">
<h1>Export üK</h1>
<h2>Edoniq Teilnehmer</h2>
<a href="{% url 'edoniq_export_students' %}" class="btn btn-primary">Teilnehmer exportieren</a>
<h2>Reset</h2>
<form action="/api/core/cypressreset/" method="post"> <form action="/api/core/cypressreset/" method="post">
{% csrf_token %} {% csrf_token %}
<button class="btn" name="">Testdaten zurück setzen</button> <button class="btn" name="">Testdaten zurück setzen</button>