Import students from excel

This commit is contained in:
Daniel Egger 2023-05-31 22:09:36 +02:00
parent d6df9b624b
commit 32233ec38e
10 changed files with 115 additions and 54 deletions

View File

@ -7,14 +7,14 @@ from django.db import migrations
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('core', '0001_initial'), ("core", "0001_initial"),
] ]
operations = [ operations = [
migrations.AlterModelManagers( migrations.AlterModelManagers(
name='user', name="user",
managers=[ managers=[
('objects', django.contrib.auth.models.UserManager()), ("objects", django.contrib.auth.models.UserManager()),
], ],
), ),
] ]

View File

@ -46,6 +46,7 @@ class CourseSessionUserAdmin(admin.ModelAdmin):
] ]
list_filter = [ list_filter = [
"course_session", "course_session",
"role",
] ]
fieldsets = [ fieldsets = [

View File

@ -45,15 +45,16 @@ from vbv_lernwelt.course.creators.versicherungsvermittlerin import (
create_versicherungsvermittlerin_with_categories, create_versicherungsvermittlerin_with_categories,
) )
from vbv_lernwelt.course.models import ( from vbv_lernwelt.course.models import (
Course,
CoursePage, CoursePage,
CourseSession, CourseSession,
CourseSessionUser, CourseSessionUser,
Course,
) )
from vbv_lernwelt.course.services import mark_course_completion from vbv_lernwelt.course.services import mark_course_completion
from vbv_lernwelt.feedback.creators.create_demo_feedback import create_feedback from vbv_lernwelt.feedback.creators.create_demo_feedback import create_feedback
from vbv_lernwelt.importer.services import ( from vbv_lernwelt.importer.services import (
import_course_sessions_from_excel, import_course_sessions_from_excel,
import_students_from_excel,
import_trainers_from_excel, import_trainers_from_excel,
) )
from vbv_lernwelt.learnpath.create_vv_new_learning_path import ( from vbv_lernwelt.learnpath.create_vv_new_learning_path import (
@ -460,6 +461,10 @@ def create_course_training_de():
course, course,
f"{current_dir}/../../../importer/tests/Schulungen_Durchfuehrung_Trainer.xlsx", f"{current_dir}/../../../importer/tests/Schulungen_Durchfuehrung_Trainer.xlsx",
) )
import_students_from_excel(
course,
f"{current_dir}/../../../importer/tests/Schulungen_Teilnehmende.xlsx",
)
for cs in CourseSession.objects.filter(course_id=COURSE_UK_TRAINING): for cs in CourseSession.objects.filter(course_id=COURSE_UK_TRAINING):
cs.assignment_details_list = [ cs.assignment_details_list = [

View File

@ -6,33 +6,33 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('course', '0003_rename_attendance_days_coursesession_attendance_courses'), ("course", "0003_rename_attendance_days_coursesession_attendance_courses"),
] ]
operations = [ operations = [
migrations.AddField( migrations.AddField(
model_name='coursesession', model_name="coursesession",
name='generation', name="generation",
field=models.TextField(blank=True, default=''), field=models.TextField(blank=True, default=""),
), ),
migrations.AddField( migrations.AddField(
model_name='coursesession', model_name="coursesession",
name='group', name="group",
field=models.TextField(blank=True, default=''), field=models.TextField(blank=True, default=""),
), ),
migrations.AddField( migrations.AddField(
model_name='coursesession', model_name="coursesession",
name='import_id', name="import_id",
field=models.TextField(blank=True, default=''), field=models.TextField(blank=True, default=""),
), ),
migrations.AddField( migrations.AddField(
model_name='coursesession', model_name="coursesession",
name='region', name="region",
field=models.TextField(blank=True, default=''), field=models.TextField(blank=True, default=""),
), ),
migrations.AlterField( migrations.AlterField(
model_name='coursesession', model_name="coursesession",
name='title', name="title",
field=models.TextField(unique=True), field=models.TextField(unique=True),
), ),
] ]

View File

@ -1,4 +1,4 @@
from typing import Dict, Any from typing import Any, Dict
import structlog import structlog
from openpyxl.reader.excel import load_workbook from openpyxl.reader.excel import load_workbook
@ -6,11 +6,11 @@ from openpyxl.reader.excel import load_workbook
from vbv_lernwelt.core.models import User from vbv_lernwelt.core.models import User
from vbv_lernwelt.course.models import Course, CourseSession, CourseSessionUser from vbv_lernwelt.course.models import Course, CourseSession, CourseSessionUser
from vbv_lernwelt.importer.utils import ( from vbv_lernwelt.importer.utils import (
try_parse_datetime,
parse_circle_group_string,
calc_header_tuple_list_from_pyxl_sheet, calc_header_tuple_list_from_pyxl_sheet,
parse_circle_group_string,
try_parse_datetime,
) )
from vbv_lernwelt.learnpath.models import LearningContentAttendanceCourse, Circle from vbv_lernwelt.learnpath.models import Circle, LearningContentAttendanceCourse
logger = structlog.get_logger(__name__) logger = structlog.get_logger(__name__)
@ -183,3 +183,41 @@ def create_or_update_trainer(course: Course, data: Dict[str, Any]):
if csu: if csu:
csu.expert.add(circle) csu.expert.add(circle)
csu.save() csu.save()
def import_students_from_excel(course: Course, filename: str):
workbook = load_workbook(filename=filename)
sheet = workbook.active
tuple_list = calc_header_tuple_list_from_pyxl_sheet(sheet)
for row in tuple_list:
create_or_update_student(course, dict(row))
def create_or_update_student(course: Course, data: Dict[str, Any]):
logger.debug(
"create_or_update_student",
course=course.title,
data=data,
label="import",
)
user = create_or_update_user(
email=data["Email"],
first_name=data["Vorname"],
last_name=data["Name"],
)
# TODO: handle language
# general expert handling
import_ids = [i.strip() for i in data["Durchführungen"].split(",")]
for import_id in import_ids:
course_session = CourseSession.objects.filter(
import_id=import_id, course=course
).first()
if course_session:
csu, _created = CourseSessionUser.objects.get_or_create(
course_session_id=course_session.id, user_id=user.id
)
csu.save()

View File

@ -6,7 +6,7 @@ from openpyxl.reader.excel import load_workbook
from vbv_lernwelt.course.creators.test_course import create_test_course from vbv_lernwelt.course.creators.test_course import create_test_course
from vbv_lernwelt.course.models import CourseSession, CourseSessionUser from vbv_lernwelt.course.models import CourseSession, CourseSessionUser
from vbv_lernwelt.importer.services import create_or_update_trainer from vbv_lernwelt.importer.services import create_or_update_student
from vbv_lernwelt.importer.utils import calc_header_tuple_list_from_pyxl_sheet from vbv_lernwelt.importer.utils import calc_header_tuple_list_from_pyxl_sheet
test_dir = os.path.dirname(os.path.abspath(__file__)) test_dir = os.path.dirname(os.path.abspath(__file__))
@ -15,6 +15,12 @@ test_dir = os.path.dirname(os.path.abspath(__file__))
class ImportStudentsTestCase(TestCase): class ImportStudentsTestCase(TestCase):
def setUp(self): def setUp(self):
self.course = create_test_course(include_vv=False) self.course = create_test_course(include_vv=False)
self.course_session_a = CourseSession.objects.create(
course=self.course,
title="Deutschschweiz 2023 A",
import_id="DE 2023 A",
group="A",
)
def test_import_excel_file(self): def test_import_excel_file(self):
workbook = load_workbook(filename=f"{test_dir}/Schulungen_Teilnehmende.xlsx") workbook = load_workbook(filename=f"{test_dir}/Schulungen_Teilnehmende.xlsx")
@ -23,51 +29,48 @@ class ImportStudentsTestCase(TestCase):
tuple_list = calc_header_tuple_list_from_pyxl_sheet(sheet) tuple_list = calc_header_tuple_list_from_pyxl_sheet(sheet)
for row in tuple_list: for row in tuple_list:
print(row) print(row)
create_or_update_student(self.course, dict(row))
self.assertEqual(CourseSessionUser.objects.count(), 26)
class CreateOrUpdateCourseSessionTestCase(TestCase): class CreateOrUpdateStudentTestCase(TestCase):
def setUp(self): def setUp(self):
self.course = create_test_course(include_vv=False) self.course = create_test_course(include_vv=False)
self.course_session_a = CourseSession.objects.create( self.course_session_a = CourseSession.objects.create(
course=self.course, course=self.course,
title="Deutschschweiz 2023 A", title="Deutschschweiz 2023 A",
import_id="DE 2023", import_id="DE 2023 A",
group="A", group="A",
) )
self.course_session_a = CourseSession.objects.create(
course=self.course,
title="Deutschschweiz 2023 B",
import_id="DE 2023",
group="B",
)
def test_create_course_session(self): def test_create_student(self):
row = [ row = [
("Name", "Hänni"), ("Name", "Rascher"),
("Vorname", "Fabienne"), ("Vorname", "Barbara"),
("Email", "fabienne.haenni@vbv-afa.ch"), ("Email", "barbara.rascher@vbv-afa.ch"),
("Sprache", "de"), ("Sprache", "de"),
("Generation", "DE 2023"), ("Durchführungen", "DE 2023 A"),
("Klasse", "A, B"), ("Datum", datetime(2023, 9, 6, 0, 0)),
("Circles", "Fahrzeug (A, B), Reisen (A), KMU (B)"), (None, "VBV"),
("Status Referenten", "ok"), (None, None),
(None, "Schulung D"), (None, None),
("Klasse foo", datetime(2023, 6, 6, 0, 0)), (None, None),
(None, None),
] ]
create_or_update_trainer(self.course, dict(row)) create_or_update_student(self.course, dict(row))
self.assertEqual( self.assertEqual(
CourseSessionUser.objects.filter( CourseSessionUser.objects.filter(
user__email="fabienne.haenni@vbv-afa.ch" user__email="barbara.rascher@vbv-afa.ch"
).count(), ).count(),
2, 1,
) )
csu = CourseSessionUser.objects.get( csu = CourseSessionUser.objects.get(
course_session=self.course_session_a, course_session=self.course_session_a,
) )
self.assertEqual(csu.role, CourseSessionUser.Role.EXPERT) self.assertEqual(csu.role, CourseSessionUser.Role.MEMBER)
self.assertEqual(csu.user.email, "fabienne.haenni@vbv-afa.ch") self.assertEqual(csu.user.email, "barbara.rascher@vbv-afa.ch")
self.assertEqual(csu.expert.all().first().title, "Fahrzeug")

View File

@ -14,6 +14,18 @@ test_dir = os.path.dirname(os.path.abspath(__file__))
class ImportTrainerTestCase(TestCase): class ImportTrainerTestCase(TestCase):
def setUp(self): def setUp(self):
self.course = create_test_course(include_vv=False) self.course = create_test_course(include_vv=False)
self.course_session_a = CourseSession.objects.create(
course=self.course,
title="Deutschschweiz 2023 A",
import_id="DE 2023 A",
group="A",
)
self.course_session_a = CourseSession.objects.create(
course=self.course,
title="Deutschschweiz 2023 B",
import_id="DE 2023 B",
group="B",
)
def test_import_excel_file(self): def test_import_excel_file(self):
workbook = load_workbook( workbook = load_workbook(
@ -26,8 +38,10 @@ class ImportTrainerTestCase(TestCase):
print(row) print(row)
create_or_update_trainer(self.course, dict(row)) create_or_update_trainer(self.course, dict(row))
self.assertEqual(CourseSessionUser.objects.count(), 4)
class CreateOrUpdateCourseSessionTestCase(TestCase):
class CreateOrUpdateTrainerTestCase(TestCase):
def setUp(self): def setUp(self):
self.course = create_test_course(include_vv=False) self.course = create_test_course(include_vv=False)
self.course_session_a = CourseSession.objects.create( self.course_session_a = CourseSession.objects.create(
@ -43,7 +57,7 @@ class CreateOrUpdateCourseSessionTestCase(TestCase):
group="B", group="B",
) )
def test_create_course_session(self): def test_create_trainer(self):
row = [ row = [
("Name", "Hänni"), ("Name", "Hänni"),
("Vorname", "Fabienne"), ("Vorname", "Fabienne"),

View File

@ -2,10 +2,10 @@ from datetime import date, datetime
from unittest import TestCase from unittest import TestCase
from vbv_lernwelt.importer.utils import ( from vbv_lernwelt.importer.utils import (
try_parse_date,
try_parse_int,
try_parse_datetime,
parse_circle_group_string, parse_circle_group_string,
try_parse_date,
try_parse_datetime,
try_parse_int,
) )

View File

@ -1,6 +1,6 @@
import datetime import datetime
import re import re
from typing import Any, Tuple, Union, Optional, List from typing import Any, List, Optional, Tuple, Union
from dateutil.parser import parse from dateutil.parser import parse
from six import string_types from six import string_types