Skip to content

Commit

Permalink
add confirmation logging (#862)
Browse files Browse the repository at this point in the history
  • Loading branch information
Dmi4er4 authored Jul 31, 2024
1 parent 7b467f9 commit 42920aa
Show file tree
Hide file tree
Showing 16 changed files with 223 additions and 164 deletions.
12 changes: 12 additions & 0 deletions apps/admission/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,18 @@ class ConfirmationForm(forms.ModelForm):
'Условиями использования сервиса «LMS Школы анализа данных»</a>',
required=True
)
personal_data_confirmation = forms.BooleanField(
label='Даю согласие АНО ДПО "ОБРАЗОВАТЕЛЬНЫЕ ТЕХНОЛОГИИ ЯНДЕКСА" (ОГРН: 1147799006123), '
'ООО "ЯНДЕКС" (ОГРН: 1027700229193), АО "АЭРОКЛУБ" (ОГРН: 1027739037622), '
'ООО "АГЕНТСТВО АВИА ЦЕНТР" (ОГРН: 1077758118063), '
'а также транспортным компаниям, гостиницам и компаниям, осуществляющим визовое сопровождение, '
'на обработку указанных мной персональных данных в целях организации поездок, '
'а именно для покупки билетов, оформления бронирований, '
'организации получения разрешительной документации на посещение стран прибытия. '
'Мне известно о моем праве в любое время отозвать настоящее согласия путем направления письма '
'на электронный адрес: [email protected].',
required=True
)

class Meta:
model = User
Expand Down
44 changes: 21 additions & 23 deletions apps/admission/locale/ru/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,16 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-07-23 17:03+0000\n"
"POT-Creation-Date: 2024-07-30 16:03+0000\n"
"PO-Revision-Date: 2024-07-23 17:04+0000\n"
"Last-Translator: Дмитрий Чернушевич <[email protected]>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Translated-Using: django-rosetta 0.9.8\n"

#: apps/admission/admin.py:47 apps/admission/admin.py:119
Expand Down Expand Up @@ -297,11 +298,11 @@ msgstr "Фильтровать"
msgid "Interview Section"
msgstr "Секция"

#: apps/admission/filters.py:143 apps/admission/forms.py:514
#: apps/admission/filters.py:143 apps/admission/forms.py:526
msgid "Regular"
msgstr "Классический"

#: apps/admission/filters.py:144 apps/admission/forms.py:514
#: apps/admission/filters.py:144 apps/admission/forms.py:526
msgid "Alternative"
msgstr "Альтернативный"

Expand Down Expand Up @@ -413,15 +414,14 @@ msgid "Has no patronymic"
msgstr "Нет отчества"

#: apps/admission/forms.py:474
#| msgid "Admission"
msgid "Admission track"
msgstr "Трек поступления"

#: apps/admission/forms.py:537
#: apps/admission/forms.py:549
msgid "Authorization code is not valid"
msgstr "Неверный код авторизации"

#: apps/admission/forms.py:552
#: apps/admission/forms.py:564
msgid "Email verification code is not valid"
msgstr "Неверный проверочный код"

Expand All @@ -439,8 +439,7 @@ msgid "Current Admission"
msgstr "Текущий набор"

#: apps/admission/models.py:88
msgid ""
"You can mark campaign as current only after adding contests for testing"
msgid "You can mark campaign as current only after adding contests for testing"
msgstr ""
"Возможность сделать набор текущим появится после добавления контестов для "
"этапа тестирования."
Expand Down Expand Up @@ -472,8 +471,7 @@ msgstr "Проходной балл по экзамену"
#: apps/admission/models.py:103
msgid "Campaign|Exam_passing_score-help"
msgstr ""
"Все результаты >= указанного порога гарантированно пройдут на следующий "
"этап."
"Все результаты >= указанного порога гарантированно пройдут на следующий этап."

#: apps/admission/models.py:107
msgid "Application Starts on"
Expand Down Expand Up @@ -545,8 +543,8 @@ msgstr "Шаблон отзыва о собеседовании"

#: apps/admission/models.py:153
msgid ""
"Leave blank if there is no need to send a feedback email. Email will be sent"
" at the time of interview status change, but not earlier than 21:00 of the "
"Leave blank if there is no need to send a feedback email. Email will be sent "
"at the time of interview status change, but not earlier than 21:00 of the "
"day of the interview"
msgstr ""
"Оставьте значение пустым, если не нужно отправлять письмо после завершения "
Expand Down Expand Up @@ -1099,8 +1097,8 @@ msgid ""
"Template for confirmation email that the interview was scheduled. Leave "
"blank if there is no need to send confirmation email"
msgstr ""
"Оставьте пустым, если не требуется отправлять письмо с подтверждением того,"
" что собеседование было успешно создано."
"Оставьте пустым, если не требуется отправлять письмо с подтверждением того, "
"что собеседование было успешно создано."

#: apps/admission/models.py:1174
msgid "Reminder Template"
Expand Down Expand Up @@ -1229,8 +1227,8 @@ msgstr "С заданиями"
#: apps/admission/models.py:1418
msgid "Based on this flag, student should arrive 30 min before or not"
msgstr ""
"Если отмечено, то в уведомлении будет указано время собеседования на полчаса"
" раньше."
"Если отмечено, то в уведомлении будет указано время собеседования на полчаса "
"раньше."

#: apps/admission/models.py:1428
msgid "Maximum number of slots preffered by interviewer"
Expand All @@ -1246,8 +1244,8 @@ msgstr "Поток собеседований"

#: apps/admission/models.py:1482
msgid ""
"Interview format settings are not found. Create settings <a "
"href='{}'>here</a>."
"Interview format settings are not found. Create settings <a href='{}'>here</"
"a>."
msgstr ""
"Настройки формата собеседования для указанной кампании не найдены. Создать "
"настройки можно <a href='{}'>здесь</a>."
Expand Down Expand Up @@ -1442,15 +1440,15 @@ msgstr "Название формата"
#~ msgstr "Имя шаблона письма с напоминанием о предстоящем собеседовании"

#~ msgid ""
#~ "Make sure file does not include solutions due to it visible with direct url "
#~ "link"
#~ "Make sure file does not include solutions due to it visible with direct "
#~ "url link"
#~ msgstr ""
#~ "Файлы не должны включать в себя решения, т.к. доступны по прямой ссылке "
#~ "любому желающему."

#~ msgid ""
#~ "Subtract the specified value from the start time of the interview - this is "
#~ "the schedule time of the reminder."
#~ "Subtract the specified value from the start time of the interview - this "
#~ "is the schedule time of the reminder."
#~ msgstr ""
#~ "Указывается дельта времени, которая будет вычтена из времени начала "
#~ "собеседования."
Expand Down
74 changes: 52 additions & 22 deletions apps/admission/management/commands/create_delete_role_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@
class Command(BaseCommand):
help = """
Give or take back interviewer role from Users in csv
If --branch=all provided it converted to None. If used for creating role, no branch provided. If used for
deleting role, it will be deleted for all branches and with empty branch
Example of usage:
./manage.py create_delete_role_group --filename=interviewers.csv --branch=msk --role=INTERVIEWER
./manage.py create_delete_role_group --filename=emails.csv --branch=all --role=INTERVIEWER --take_back
"""

def add_arguments(self, parser):
Expand Down Expand Up @@ -55,44 +58,71 @@ def get_group_or_none(self, user, **kwargs):
except UserGroup.DoesNotExist:
return None

def take_role_back(self, user, *, role, branch):
if branch is not None:
if self.get_group_or_none(user, role=role, branch=branch, site_id=settings.SITE_ID) is None:
self.stdout.write(
self.style.WARNING(f'{user} does not has group with this role and branch'))
return
user.remove_group(role, branch=branch)
else:
found_role = False
for branch in self.available:
if self.get_group_or_none(user, role=role, branch=branch, site_id=settings.SITE_ID):
found_role = True
user.remove_group(role, branch=branch)

if self.get_group_or_none(user, role=role, branch__isnull=True, site_id=settings.SITE_ID):
found_role = True
user.remove_group(role, branch=branch)

if not found_role:
self.stdout.write(
self.style.WARNING(f'{user} does not has group with this role'))

def give_role(self, user, *, role, branch):
if branch is not None:
if self.get_group_or_none(user, role=role, branch__isnull=True, site_id=settings.SITE_ID):
self.stdout.write(
self.style.WARNING(f'{user} already has group with this role and with no branch'))
return

if self.get_group_or_none(user, role=role, branch=branch, site_id=settings.SITE_ID):
self.stdout.write(
self.style.WARNING(f'{user} already has group with this role and branch'))
return

user.add_group(role, branch=branch)
else:
if self.get_group_or_none(user, role=role, branch__isnull=True, site_id=settings.SITE_ID):
self.stdout.write(
self.style.WARNING(f'{user} already has group with this role and with no branch'))
return

user.add_group(role, branch=branch)

def handle(self, *args, **options):
delimiter = options["delimiter"]
filename = options["filename"]
take_back = options["take_back"]
branch = options["branch"]
role = getattr(Roles, options["role"])
available = Branch.objects.filter(
self.available = Branch.objects.filter(
active=True, site_id=settings.SITE_ID
)
cs = [c.code for c in available]
cs = [c.code for c in self.available]
cs.append("all")
if not branch or branch not in cs:
msg = f"Provide the code of the branch with --branch. Options: {cs}"
raise CommandError(msg)
branch = Branch.objects.get(code=branch)
branch = Branch.objects.get(code=branch) if branch != "all" else None
with open(filename) as csvfile:
reader = csv.reader(csvfile, delimiter=delimiter)
with transaction.atomic():
headers = next(reader)
for row in reader:
user: User = User.objects.get(email__iexact=row[0])

if take_back:
if self.get_group_or_none(user, role=role, branch=branch, site_id=settings.SITE_ID) is None:
self.stdout.write(
self.style.WARNING(f'{user} does not has group with this role and branch'))
continue

user.remove_group(role, branch=branch)
self.take_role_back(user, role=role, branch=branch)
else:
if self.get_group_or_none(user, role=role, branch__isnull=True, site_id=settings.SITE_ID):
self.stdout.write(
self.style.WARNING(f'{user} already has group with this role and with no branch'))
continue

if self.get_group_or_none(user, role=role, branch=branch, site_id=settings.SITE_ID):
self.stdout.write(
self.style.WARNING(f'{user} already has group with this role and branch'))
continue

user.add_group(role, branch=branch)

self.give_role(user, role=role, branch=branch)
1 change: 1 addition & 0 deletions apps/admission/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,7 @@ def create_student(
user.workplace = applicant.workplace or ""
user.patronymic = "" if account_data.has_no_patronymic else applicant.patronymic
user.photo = applicant.photo
user.gave_permission_at = user.date_joined
# dataclasses.asdict raises `cannot pickle '_io.BufferedRandom' object`
account_fields = {field.name for field in fields(AccountData)}
for name in account_fields:
Expand Down
3 changes: 2 additions & 1 deletion apps/admission/tests/test_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,15 @@ def test_confirmation_form_validation(settings, get_test_image):
"[email protected]", acceptance.applicant
)
assert not form.is_valid()
missing_fields = ["living_place", "gender", "phone", "telegram_username", "yandex_login", "offer_confirmation"]
missing_fields = ["living_place", "gender", "phone", "telegram_username", "yandex_login", "offer_confirmation", "personal_data_confirmation"]
assert all(field in form.errors for field in missing_fields)
form_data["living_place"] = "living_place"
form_data["gender"] = GenderTypes.MALE
form_data["phone"] = "+71234567"
form_data["telegram_username"] = "telegram_username"
form_data["yandex_login"] = "yandex_login"
form_data["offer_confirmation"] = True
form_data["personal_data_confirmation"] = True
form = ConfirmationForm(
acceptance=acceptance, data=form_data, prefix=False
)
Expand Down
7 changes: 4 additions & 3 deletions apps/admission/tests/test_services.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import dataclasses
import datetime
import io
import itertools
from typing import BinaryIO, cast

import pytest
import pytz
from rest_framework.exceptions import NotFound

from django.core.exceptions import ValidationError
from django.core.files.uploadedfile import SimpleUploadedFile
from django.db.models import Q
from django.utils import timezone

Expand Down Expand Up @@ -590,6 +587,8 @@ def test_create_student(settings):
assert user.patronymic == applicant.patronymic
assert user.workplace == applicant.workplace
assert user.photo == applicant.photo
assert user.gave_permission_at is not None
assert user.gave_permission_at == user.date_joined
for field in dataclasses.fields(ACCOUNT_DATA):
assert getattr(user, field.name) == getattr(ACCOUNT_DATA, field.name)
assert applicant.user == user
Expand Down Expand Up @@ -646,6 +645,8 @@ def test_create_student_with_existing_invited(settings):
assert user.patronymic == ""
assert user.workplace == applicant.workplace
assert user.photo == applicant.photo
assert user.gave_permission_at is not None
assert user.gave_permission_at == user.date_joined
for field in dataclasses.fields(ACCOUNT_DATA_WITHOUT_PATRONYMIC):
assert getattr(user, field.name) == getattr(ACCOUNT_DATA_WITHOUT_PATRONYMIC, field.name)
assert applicant.user == user
Expand Down
2 changes: 1 addition & 1 deletion apps/htmlpages/locale/ru/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ msgid ""
msgstr ""
"Project-Id-Version: django\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-07-23 17:03+0000\n"
"POT-Creation-Date: 2024-07-30 16:03+0000\n"
"PO-Revision-Date: 2015-03-18 08:34+0000\n"
"Last-Translator: Jannis Leidel <[email protected]>\n"
"Language-Team: Russian (http://www.transifex.com/projects/p/django/language/"
Expand Down
1 change: 1 addition & 0 deletions apps/learning/invitation/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ def test_invitation_register_view(client, assert_redirect, settings, mocker):
assert not new_user.is_active
assert new_user.last_name == 'Last Name'
assert Roles.INVITED in new_user.roles
assert new_user.gave_permission_at is None
student_profile = new_user.get_student_profile(site=invitation.branch.site)
assert student_profile
assert student_profile.year_of_admission == invitation.semester.academic_year
Expand Down
2 changes: 1 addition & 1 deletion apps/projects/locale/ru/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-07-23 17:03+0000\n"
"POT-Creation-Date: 2024-07-30 16:03+0000\n"
"PO-Revision-Date: 2022-02-21 15:24+0000\n"
"Last-Translator: Сергей Жеревчук <[email protected]>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
Expand Down
2 changes: 1 addition & 1 deletion apps/surveys/locale/ru/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-07-23 17:03+0000\n"
"POT-Creation-Date: 2024-07-30 16:03+0000\n"
"PO-Revision-Date: 2019-10-31 16:30+0000\n"
"Last-Translator: b' <[email protected]>'\n"
"Language-Team: LANGUAGE <[email protected]>\n"
Expand Down
4 changes: 2 additions & 2 deletions apps/users/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ class UserAdmin(_UserAdmin):
ordering = ['last_name', 'first_name']
inlines = [YandexUserDataInlineAdmin, OnlineCourseRecordAdmin, SHADCourseRecordInlineAdmin,
UserGroupInlineAdmin]
readonly_fields = ['last_login', 'date_joined']
readonly_fields = ['last_login', 'date_joined', 'gave_permission_at']
list_display = ['id', 'username', 'email', 'first_name', 'last_name',
'is_staff']
list_filter = ['is_active', 'branch', 'group__site', 'group__role',
Expand All @@ -138,7 +138,7 @@ class UserAdmin(_UserAdmin):
'yandex_login', 'stepic_id',
'github_login', 'anytask_url',
'codeforces_login']}),
(_('Important dates'), {'fields': ['last_login', 'date_joined']})]
(_('Important dates'), {'fields': ['last_login', 'date_joined', 'gave_permission_at']})]

def get_formsets_with_inlines(self, request, obj=None):
"""
Expand Down
7 changes: 7 additions & 0 deletions apps/users/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,13 @@ class User(TimezoneAwareMixin, LearningPermissionsMixin, StudentProfileAbstract,
_("Living Place"), max_length=255, null=True, blank=True
)

gave_permission_at = models.DateTimeField(
_("Permission time"),
null=True,
blank=True
)


objects = CustomUserManager()

class Meta:
Expand Down
2 changes: 1 addition & 1 deletion compscicenter_ru/locale/ru/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-07-23 17:03+0000\n"
"POT-Creation-Date: 2024-07-30 16:03+0000\n"
"PO-Revision-Date: 2020-02-03 16:52+0000\n"
"Last-Translator: b' <[email protected]>'\n"
"Language-Team: LANGUAGE <[email protected]>\n"
Expand Down
Loading

0 comments on commit 42920aa

Please sign in to comment.