Import trainer from excel file
This commit is contained in:
parent
2e7a069d0a
commit
f42aae19ee
|
|
@ -52,7 +52,10 @@ from vbv_lernwelt.course.models import (
|
||||||
)
|
)
|
||||||
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 import_course_sessions_from_excel
|
from vbv_lernwelt.importer.services import (
|
||||||
|
import_course_sessions_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 (
|
||||||
create_vv_new_learning_path,
|
create_vv_new_learning_path,
|
||||||
)
|
)
|
||||||
|
|
@ -453,6 +456,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_trainers_from_excel(
|
||||||
|
course,
|
||||||
|
f"{current_dir}/../../../importer/tests/Schulungen_Durchfuehrung_Trainer.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 = [
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
from typing import Dict, Any
|
from typing import Dict, Any
|
||||||
|
|
||||||
|
import structlog
|
||||||
from openpyxl.reader.excel import load_workbook
|
from openpyxl.reader.excel import load_workbook
|
||||||
|
|
||||||
from vbv_lernwelt.core.models import User
|
from vbv_lernwelt.core.models import User
|
||||||
|
|
@ -7,10 +8,20 @@ from vbv_lernwelt.course.models import Course, CourseSession, CourseSessionUser
|
||||||
from vbv_lernwelt.importer.utils import try_parse_datetime, parse_circle_group_string
|
from vbv_lernwelt.importer.utils import try_parse_datetime, parse_circle_group_string
|
||||||
from vbv_lernwelt.learnpath.models import LearningContentAttendanceCourse, Circle
|
from vbv_lernwelt.learnpath.models import LearningContentAttendanceCourse, Circle
|
||||||
|
|
||||||
|
logger = structlog.get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def create_or_update_user(
|
def create_or_update_user(
|
||||||
email: str, first_name: str = "", last_name: str = "", sso_id: str = None
|
email: str, first_name: str = "", last_name: str = "", sso_id: str = None
|
||||||
):
|
):
|
||||||
|
logger.debug(
|
||||||
|
"create_or_update_user",
|
||||||
|
email=email,
|
||||||
|
first_name=first_name,
|
||||||
|
last_name=last_name,
|
||||||
|
sso_id=sso_id,
|
||||||
|
label="import",
|
||||||
|
)
|
||||||
user = None
|
user = None
|
||||||
if sso_id:
|
if sso_id:
|
||||||
user_qs = User.objects.filter(sso_id=sso_id)
|
user_qs = User.objects.filter(sso_id=sso_id)
|
||||||
|
|
@ -56,6 +67,13 @@ def create_or_update_course_session(course: Course, data: Dict[str, Any], circle
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
logger.debug(
|
||||||
|
"create_or_update_course_session",
|
||||||
|
course=course.title,
|
||||||
|
data=data,
|
||||||
|
label="import",
|
||||||
|
)
|
||||||
|
|
||||||
if circles is None:
|
if circles is None:
|
||||||
circles = []
|
circles = []
|
||||||
|
|
||||||
|
|
@ -102,7 +120,25 @@ def create_or_update_course_session(course: Course, data: Dict[str, Any], circle
|
||||||
return cs
|
return cs
|
||||||
|
|
||||||
|
|
||||||
|
def import_trainers_from_excel(course: Course, filename: str):
|
||||||
|
workbook = load_workbook(filename=filename)
|
||||||
|
sheet = workbook["Schulungen Trainer"]
|
||||||
|
|
||||||
|
header = [cell.value for cell in sheet[1]]
|
||||||
|
|
||||||
|
for row in sheet.iter_rows(min_row=2, values_only=True):
|
||||||
|
row_with_header = list(zip(header, row))
|
||||||
|
create_or_update_trainer(course, dict(row_with_header))
|
||||||
|
|
||||||
|
|
||||||
def create_or_update_trainer(course: Course, data: Dict[str, Any]):
|
def create_or_update_trainer(course: Course, data: Dict[str, Any]):
|
||||||
|
logger.debug(
|
||||||
|
"create_or_update_trainer",
|
||||||
|
course=course.title,
|
||||||
|
data=data,
|
||||||
|
label="import",
|
||||||
|
)
|
||||||
|
|
||||||
user = create_or_update_user(
|
user = create_or_update_user(
|
||||||
email=data["Email"],
|
email=data["Email"],
|
||||||
first_name=data["Vorname"],
|
first_name=data["Vorname"],
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ class ImportTrainerTestCase(TestCase):
|
||||||
for row in sheet.iter_rows(min_row=2, values_only=True):
|
for row in sheet.iter_rows(min_row=2, values_only=True):
|
||||||
row_with_header = list(zip(header, row))
|
row_with_header = list(zip(header, row))
|
||||||
print(row_with_header)
|
print(row_with_header)
|
||||||
|
create_or_update_trainer(self.course, dict(row_with_header))
|
||||||
|
|
||||||
|
|
||||||
class CreateOrUpdateCourseSessionTestCase(TestCase):
|
class CreateOrUpdateCourseSessionTestCase(TestCase):
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import logging
|
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
import structlog
|
||||||
from notifications.signals import notify
|
from notifications.signals import notify
|
||||||
from sendgrid import Mail, SendGridAPIClient
|
from sendgrid import Mail, SendGridAPIClient
|
||||||
from storages.utils import setting
|
from storages.utils import setting
|
||||||
|
|
@ -8,7 +8,7 @@ from storages.utils import setting
|
||||||
from vbv_lernwelt.core.models import User
|
from vbv_lernwelt.core.models import User
|
||||||
from vbv_lernwelt.notify.models import Notification, NotificationType
|
from vbv_lernwelt.notify.models import Notification, NotificationType
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = structlog.get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class EmailService:
|
class EmailService:
|
||||||
|
|
@ -25,10 +25,14 @@ class EmailService:
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
cls._sendgrid_client.send(message)
|
cls._sendgrid_client.send(message)
|
||||||
logger.info(f"Successfully sent email to {recipient}")
|
logger.info(f"Successfully sent email to {recipient}", label="email")
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Failed to send email to {recipient}: {e}")
|
logger.error(
|
||||||
|
f"Failed to send email to {recipient}: {e}",
|
||||||
|
exc_info=True,
|
||||||
|
label="email",
|
||||||
|
)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
import base64
|
import base64
|
||||||
import json
|
import json
|
||||||
import logging
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
import structlog
|
||||||
|
|
||||||
|
logger = structlog.get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def decode_jwt(jwt: str):
|
def decode_jwt(jwt: str):
|
||||||
|
|
@ -11,7 +12,9 @@ def decode_jwt(jwt: str):
|
||||||
payload_bytes = base64.urlsafe_b64decode(_correct_padding(jwt_parts[1]))
|
payload_bytes = base64.urlsafe_b64decode(_correct_padding(jwt_parts[1]))
|
||||||
payload = json.loads(payload_bytes.decode("UTF-8"))
|
payload = json.loads(payload_bytes.decode("UTF-8"))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"OAuthToken error: Could not decode jwt: {e}")
|
logger.warning(
|
||||||
|
f"OAuthToken error: Could not decode jwt: {e}", exc_info=True, label="sso"
|
||||||
|
)
|
||||||
return None
|
return None
|
||||||
return payload
|
return payload
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue