Merged develop into feature/VBV-656-dj-feedback-export
This commit is contained in:
commit
19981c7d54
|
|
@ -25,6 +25,7 @@ from vbv_lernwelt.core.views import (
|
|||
check_rate_limit,
|
||||
cypress_reset_view,
|
||||
generate_web_component_icons,
|
||||
iterativ_test_coursesessions_reset_view,
|
||||
permission_denied_view,
|
||||
rate_limit_exceeded_view,
|
||||
vue_home,
|
||||
|
|
@ -209,6 +210,13 @@ urlpatterns = [
|
|||
name="t2l_sync",
|
||||
),
|
||||
|
||||
# iterativ Test course sessions
|
||||
path(
|
||||
r"api/core/resetiterativsessions/",
|
||||
iterativ_test_coursesessions_reset_view,
|
||||
name="iterativ_test_coursesessions_reset_view",
|
||||
),
|
||||
|
||||
path("server/graphql/",
|
||||
csrf_exempt(GraphQLView.as_view(graphiql=True, schema=schema))),
|
||||
# testing and debug
|
||||
|
|
|
|||
|
|
@ -0,0 +1,336 @@
|
|||
from datetime import datetime, time, timedelta
|
||||
|
||||
import djclick as click
|
||||
import structlog
|
||||
from django.utils import timezone
|
||||
|
||||
from vbv_lernwelt.assignment.models import Assignment, AssignmentCompletion
|
||||
from vbv_lernwelt.core.admin import User
|
||||
from vbv_lernwelt.course.consts import (
|
||||
COURSE_VERSICHERUNGSVERMITTLERIN_FR_ID,
|
||||
COURSE_VERSICHERUNGSVERMITTLERIN_ID,
|
||||
COURSE_VERSICHERUNGSVERMITTLERIN_IT_ID,
|
||||
)
|
||||
from vbv_lernwelt.course.models import (
|
||||
Course,
|
||||
CourseCompletion,
|
||||
CourseSession,
|
||||
CourseSessionUser,
|
||||
)
|
||||
from vbv_lernwelt.course_session.models import (
|
||||
CourseSessionAssignment,
|
||||
CourseSessionAttendanceCourse,
|
||||
CourseSessionEdoniqTest,
|
||||
)
|
||||
from vbv_lernwelt.course_session_group.models import CourseSessionGroup
|
||||
from vbv_lernwelt.feedback.models import FeedbackResponse
|
||||
from vbv_lernwelt.learning_mentor.models import LearningMentor
|
||||
from vbv_lernwelt.learnpath.models import Circle
|
||||
from vbv_lernwelt.notify.models import Notification
|
||||
|
||||
logger = structlog.get_logger(__name__)
|
||||
from vbv_lernwelt.importer.services import (
|
||||
create_or_update_course_session,
|
||||
get_uk_course,
|
||||
LP_DATA,
|
||||
TRANSLATIONS,
|
||||
)
|
||||
|
||||
IT_VV_TEST_COURSE = "Iterativ VV Testkurs"
|
||||
IT_UK_TEST_COURSE = "Iterativ üK Testkurs"
|
||||
IT_UK_TEST_REGION = "Iterativ Region"
|
||||
TIME_FORMAT = "%d.%m.%Y, %H:%M"
|
||||
PASSWORD = "KqaDm3-x8zhCKHLWDV_oiqFrYWHg"
|
||||
|
||||
logger = structlog.get_logger(__name__)
|
||||
|
||||
|
||||
@click.command()
|
||||
def command():
|
||||
create_or_update_uk()
|
||||
create_or_update_vv()
|
||||
|
||||
|
||||
def create_or_update_uk(language="de"):
|
||||
uk_course = get_uk_course(language)
|
||||
uk_circle_keys = [
|
||||
"Kickoff",
|
||||
"Basis",
|
||||
"Fahrzeug",
|
||||
"Haushalt Teil 1",
|
||||
"Haushalt Teil 2",
|
||||
]
|
||||
|
||||
data = create_uk_data(language)
|
||||
create_or_update_course_session(
|
||||
uk_course,
|
||||
data,
|
||||
language,
|
||||
circle_keys=uk_circle_keys,
|
||||
)
|
||||
cs = CourseSession.objects.get(import_id=data["ID"])
|
||||
|
||||
members, trainer, regionenleiter = get_or_create_users_uk()
|
||||
delete_cs_data(cs, members + [trainer, regionenleiter])
|
||||
|
||||
add_to_course_session(cs, members)
|
||||
add_trainers_to_course_session(cs, [trainer], uk_circle_keys, language)
|
||||
create_and_add_to_cs_group(cs.course, IT_UK_TEST_REGION, [cs], regionenleiter)
|
||||
|
||||
|
||||
def create_or_update_vv(language="de"):
|
||||
vv_course = get_vv_course(language)
|
||||
|
||||
cs, _created = CourseSession.objects.get_or_create(
|
||||
course=vv_course, import_id=IT_VV_TEST_COURSE
|
||||
)
|
||||
cs.title = IT_VV_TEST_COURSE
|
||||
cs.save()
|
||||
|
||||
create_or_update_assignment_course_session(cs)
|
||||
members, member_with_mentor, mentor = get_or_create_users_vv()
|
||||
delete_cs_data(cs, members + [member_with_mentor, mentor])
|
||||
|
||||
add_to_course_session(cs, members + [member_with_mentor])
|
||||
add_mentor_to_course_session(cs, [(mentor, member_with_mentor)])
|
||||
|
||||
|
||||
def delete_cs_data(cs: CourseSession, users: list[User]):
|
||||
if cs:
|
||||
CourseCompletion.objects.filter(course_session=cs).delete()
|
||||
Notification.objects.filter(course_session=cs).delete()
|
||||
AssignmentCompletion.objects.filter(course_session=cs).delete()
|
||||
CourseSessionAttendanceCourse.objects.filter(course_session=cs).update(
|
||||
attendance_user_list=[]
|
||||
)
|
||||
CourseSessionEdoniqTest.objects.filter(course_session=cs).delete()
|
||||
CourseSessionUser.objects.filter(course_session=cs).delete()
|
||||
learning_mentor_ids = (
|
||||
LearningMentor.objects.filter(participants__course_session=cs)
|
||||
.values_list("id", flat=True)
|
||||
.distinct()
|
||||
| LearningMentor.objects.filter(mentor__in=users)
|
||||
.values_list("id", flat=True)
|
||||
.distinct()
|
||||
)
|
||||
# cannot call delete on distinct objects
|
||||
LearningMentor.objects.filter(id__in=list(learning_mentor_ids)).delete()
|
||||
else:
|
||||
logger.info("no_course_session_found", import_id=cs.import_id)
|
||||
|
||||
FeedbackResponse.objects.filter(feedback_user__in=users).delete()
|
||||
|
||||
|
||||
def add_to_course_session(
|
||||
course_session: CourseSession,
|
||||
members: list[User],
|
||||
role=CourseSessionUser.Role.MEMBER,
|
||||
):
|
||||
if course_session:
|
||||
for user in members:
|
||||
csu, _created = CourseSessionUser.objects.get_or_create(
|
||||
course_session_id=course_session.id, user_id=user.id, role=role
|
||||
)
|
||||
csu.save()
|
||||
|
||||
|
||||
def add_mentor_to_course_session(
|
||||
course_session: CourseSession, mentor_mentee_pairs: list[tuple[User, User]]
|
||||
):
|
||||
for mentor, mentee in mentor_mentee_pairs:
|
||||
lm = LearningMentor.objects.create(
|
||||
course=course_session.course,
|
||||
mentor=mentor,
|
||||
)
|
||||
lm.participants.add(
|
||||
CourseSessionUser.objects.get(
|
||||
user__id=mentee.id,
|
||||
course_session=course_session,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def add_trainers_to_course_session(
|
||||
course_session: CourseSession,
|
||||
trainers: list[User],
|
||||
circle_keys: list[str],
|
||||
language,
|
||||
):
|
||||
add_to_course_session(course_session, trainers, CourseSessionUser.Role.EXPERT)
|
||||
for user in trainers:
|
||||
for circle_key in circle_keys:
|
||||
circle_name = LP_DATA[circle_key][language]["title"]
|
||||
circle = Circle.objects.filter(
|
||||
slug=f"{course_session.course.slug}-lp-circle-{circle_name.lower()}"
|
||||
).first()
|
||||
|
||||
if course_session and circle:
|
||||
csu = CourseSessionUser.objects.filter(
|
||||
course_session_id=course_session.id, user_id=user.id
|
||||
).first()
|
||||
if csu:
|
||||
csu.expert.add(circle)
|
||||
csu.save()
|
||||
|
||||
|
||||
def get_or_create_users_uk():
|
||||
members = [
|
||||
_create_or_update_user(
|
||||
f"teilnehmer{n}.uk@iterativ.ch", "Teilnehmer üK", "Iterativ", PASSWORD, "de"
|
||||
)
|
||||
for n in range(1, 10)
|
||||
]
|
||||
trainer = _create_or_update_user(
|
||||
"trainer1.uk@iterativ.ch", "Trainer üK", "Iterativ", PASSWORD, "de"
|
||||
)
|
||||
regionenleiter = _create_or_update_user(
|
||||
"regionenleiter1.uk@iterativ.ch",
|
||||
"Regionenleiter üK",
|
||||
"Iterativ",
|
||||
PASSWORD,
|
||||
"de",
|
||||
)
|
||||
return (
|
||||
members,
|
||||
trainer,
|
||||
regionenleiter,
|
||||
)
|
||||
|
||||
|
||||
def get_or_create_users_vv():
|
||||
members = [
|
||||
_create_or_update_user(
|
||||
f"teilnehmer{n}.vv@iterativ.ch", "Teilnehmer VV", "Iterativ", PASSWORD, "de"
|
||||
)
|
||||
for n in range(1, 10)
|
||||
]
|
||||
member_with_mentor = _create_or_update_user(
|
||||
"teilnehmer1.vv.lb@iterativ.ch",
|
||||
"Teilnehmer VV mit LB",
|
||||
"Iterativ",
|
||||
PASSWORD,
|
||||
"de",
|
||||
)
|
||||
mentor = _create_or_update_user(
|
||||
"lernbegleitung1.vv@iterativ.ch",
|
||||
"Lernbegleitung VV",
|
||||
"Iterativ",
|
||||
PASSWORD,
|
||||
"de",
|
||||
)
|
||||
return members, member_with_mentor, mentor
|
||||
|
||||
|
||||
def _create_or_update_user(email, first_name, last_name, password, language):
|
||||
try:
|
||||
user = User.objects.get(email=email)
|
||||
except User.DoesNotExist:
|
||||
user = User(
|
||||
email=email,
|
||||
username=email,
|
||||
)
|
||||
|
||||
user.email = email
|
||||
user.first_name = first_name or user.first_name
|
||||
user.last_name = last_name or user.last_name
|
||||
user.username = email
|
||||
user.language = language
|
||||
user.set_password(password)
|
||||
user.save()
|
||||
return user
|
||||
|
||||
|
||||
def create_uk_data(language):
|
||||
return {
|
||||
"Klasse": IT_UK_TEST_COURSE,
|
||||
"ID": IT_UK_TEST_COURSE,
|
||||
"Generation": 2024,
|
||||
"Region": "Bern",
|
||||
"Sprache": language,
|
||||
f"Kickoff {TRANSLATIONS[language]['start']}": timezone.make_aware(
|
||||
datetime.combine((timezone.now() + timedelta(weeks=2)).date(), time(9, 0))
|
||||
).strftime("%d.%m.%Y, %H:%M"),
|
||||
f"Kickoff {TRANSLATIONS[language]['ende']}": timezone.make_aware(
|
||||
datetime.combine((timezone.now() + timedelta(weeks=2)).date(), time(16, 0))
|
||||
).strftime("%d.%m.%Y, %H:%M"),
|
||||
f"Kickoff {TRANSLATIONS[language]['raum']}": "Raum 1",
|
||||
f"Kickoff {TRANSLATIONS[language]['standort']}": "Bern",
|
||||
f"Kickoff {TRANSLATIONS[language]['adresse']}": "Musterstrasse 1",
|
||||
f"Basis {TRANSLATIONS[language]['start']}": timezone.make_aware(
|
||||
datetime.combine((timezone.now() + timedelta(weeks=4)).date(), time(9, 0))
|
||||
).strftime("%d.%m.%Y, %H:%M"),
|
||||
f"Basis {TRANSLATIONS[language]['ende']}": timezone.make_aware(
|
||||
datetime.combine((timezone.now() + timedelta(weeks=4)).date(), time(16, 0))
|
||||
).strftime("%d.%m.%Y, %H:%M"),
|
||||
f"Basis {TRANSLATIONS[language]['raum']}": "Raum 1",
|
||||
f"Basis {TRANSLATIONS[language]['standort']}": "Bern",
|
||||
f"Basis {TRANSLATIONS[language]['adresse']}": "Musterstrasse 1",
|
||||
f"Fahrzeug {TRANSLATIONS[language]['start']}": timezone.make_aware(
|
||||
datetime.combine((timezone.now() + timedelta(weeks=6)).date(), time(9, 0))
|
||||
).strftime("%d.%m.%Y, %H:%M"),
|
||||
f"Fahrzeug {TRANSLATIONS[language]['ende']}": timezone.make_aware(
|
||||
datetime.combine((timezone.now() + timedelta(weeks=6)).date(), time(16, 0))
|
||||
).strftime("%d.%m.%Y, %H:%M"),
|
||||
f"Fahrzeug {TRANSLATIONS[language]['raum']}": "Raum 1",
|
||||
f"Fahrzeug {TRANSLATIONS[language]['standort']}": "Bern",
|
||||
f"Fahrzeug {TRANSLATIONS[language]['adresse']}": "Musterstrasse 1",
|
||||
f"Haushalt Teil 1 {TRANSLATIONS[language]['start']}": timezone.make_aware(
|
||||
datetime.combine((timezone.now() + timedelta(weeks=8)).date(), time(9, 0))
|
||||
).strftime("%d.%m.%Y, %H:%M"),
|
||||
f"Haushalt Teil 1 {TRANSLATIONS[language]['ende']}": timezone.make_aware(
|
||||
datetime.combine((timezone.now() + timedelta(weeks=8)).date(), time(16, 0))
|
||||
).strftime("%d.%m.%Y, %H:%M"),
|
||||
f"Haushalt Teil 1 {TRANSLATIONS[language]['raum']}": "Raum 1",
|
||||
f"Haushalt Teil 1 {TRANSLATIONS[language]['standort']}": "Bern",
|
||||
f"Haushalt Teil 1 {TRANSLATIONS[language]['adresse']}": "Musterstrasse 1",
|
||||
f"Haushalt Teil 2 {TRANSLATIONS[language]['start']}": timezone.make_aware(
|
||||
datetime.combine((timezone.now() + timedelta(weeks=10)).date(), time(9, 0))
|
||||
).strftime("%d.%m.%Y, %H:%M"),
|
||||
f"Haushalt Teil 2 {TRANSLATIONS[language]['ende']}": timezone.make_aware(
|
||||
datetime.combine((timezone.now() + timedelta(weeks=10)).date(), time(16, 0))
|
||||
).strftime("%d.%m.%Y, %H:%M"),
|
||||
f"Haushalt Teil 2 {TRANSLATIONS[language]['raum']}": "Raum 1",
|
||||
f"Haushalt Teil 2 {TRANSLATIONS[language]['standort']}": "Bern",
|
||||
f"Haushalt Teil 2 {TRANSLATIONS[language]['adresse']}": "Musterstrasse 1",
|
||||
}
|
||||
|
||||
|
||||
def create_and_add_to_cs_group(
|
||||
course: Course, name: str, course_sessions: list[CourseSession], supervisor: User
|
||||
):
|
||||
region, _ = CourseSessionGroup.objects.get_or_create(
|
||||
name=name,
|
||||
course=course,
|
||||
)
|
||||
|
||||
for cs in course_sessions:
|
||||
region.course_session.add(cs)
|
||||
|
||||
region.supervisor.add(supervisor)
|
||||
|
||||
|
||||
def get_vv_course(language: str) -> Course:
|
||||
if language == "fr":
|
||||
course_id = COURSE_VERSICHERUNGSVERMITTLERIN_FR_ID
|
||||
elif language == "it":
|
||||
course_id = COURSE_VERSICHERUNGSVERMITTLERIN_IT_ID
|
||||
else:
|
||||
course_id = COURSE_VERSICHERUNGSVERMITTLERIN_ID
|
||||
|
||||
return Course.objects.get(id=course_id)
|
||||
|
||||
|
||||
def create_or_update_assignment_course_session(cs: CourseSession):
|
||||
# not nice but works for now
|
||||
for assignment in Assignment.objects.all():
|
||||
if assignment.get_course().id == cs.course.id:
|
||||
logger.debug(
|
||||
"create_course_session_assigments",
|
||||
assignment=assignment,
|
||||
label="reset_test_courses",
|
||||
)
|
||||
for lca in assignment.learningcontentassignment_set.all():
|
||||
_csa, _created = CourseSessionAssignment.objects.get_or_create(
|
||||
course_session=cs,
|
||||
learning_content=lca,
|
||||
)
|
||||
|
|
@ -179,6 +179,17 @@ def cypress_reset_view(request):
|
|||
return HttpResponseRedirect("/server/admin/")
|
||||
|
||||
|
||||
@api_view(["POST"])
|
||||
@authentication_classes((authentication.SessionAuthentication,))
|
||||
@permission_classes((IsAdminUser,))
|
||||
def iterativ_test_coursesessions_reset_view(request):
|
||||
call_command(
|
||||
"reset_iterativ_test_sessions",
|
||||
)
|
||||
|
||||
return HttpResponseRedirect("/server/admin/")
|
||||
|
||||
|
||||
@django_view_authentication_exempt
|
||||
def generate_web_component_icons(request):
|
||||
svg_files = []
|
||||
|
|
|
|||
|
|
@ -43,6 +43,14 @@
|
|||
<a href="{% url 'edoniq_export_students_and_trainers' %}" class="btn btn-primary">Teilnehmer
|
||||
und Trainer exportieren</a>
|
||||
|
||||
<hr style="margin: 24px 0">
|
||||
|
||||
<form action="/api/core/resetiterativsessions/" method="post">
|
||||
{% csrf_token %}
|
||||
<p>Zurücksetzen der Iterativ Testdurchführungen (üK: "Iterativ üK Testkurs", VV: "Iterativ VV Testkurs")</p>
|
||||
<button class="btn">Iterativ Testdurchführungen zurücksetzen</button>
|
||||
</form>
|
||||
|
||||
<hr style="margin: 24px 0">
|
||||
|
||||
<form action="/api/core/cypressreset/" method="post">
|
||||
|
|
|
|||
Loading…
Reference in New Issue