diff --git a/mo/imports.py b/mo/imports.py index 73ec1a6f85476dc4e84cfea8260d50812aa3638f..927539ffa74edce5e1ab6211b7ef9a2fbd47214c 100644 --- a/mo/imports.py +++ b/mo/imports.py @@ -195,7 +195,7 @@ class Import: def find_or_create_user(self, email: str, krestni: Optional[str], prijmeni: Optional[str], is_org: bool) -> Optional[db.User]: try: - user, is_new = mo.users.find_or_create_user(email, krestni, prijmeni, is_org, reason='import') + user, is_new, is_change_user_to_org = mo.users.find_or_create_user(email, krestni, prijmeni, is_org, reason='import') except mo.CheckError as e: return self.error(str(e)) if is_new: diff --git a/mo/users.py b/mo/users.py index 17fc472e2b2f01fb05d8341c8e34fc169f6d1137..aae885accabad94e1cfbff7efffbb105acbe0c36 100644 --- a/mo/users.py +++ b/mo/users.py @@ -52,6 +52,11 @@ def validate_and_find_school(kod: str) -> db.Place: return place +class CheckErrorOrgIsUser(mo.CheckError): + """Při požadavku na orga nalezen uživatel nebo opačně.""" + pass + + def change_user_to_org(user, reason: str): if (db.get_session().query(db.Participation, db.Contest, db.Round) .select_from(db.Participation) @@ -70,10 +75,11 @@ def change_user_to_org(user, reason: str): ) -def find_or_create_user(email: str, krestni: Optional[str], prijmeni: Optional[str], is_org: bool, reason: str) -> Tuple[db.User, bool]: +def find_or_create_user(email: str, krestni: Optional[str], prijmeni: Optional[str], is_org: bool, reason: str, allow_change_user_to_org=False) -> Tuple[db.User, bool, bool]: sess = db.get_session() user = sess.query(db.User).filter_by(email=email).one_or_none() is_new = user is None + is_change_user_to_org = False if user is None: # HACK: Podmínku je nutné zapsat znovu místo užití is_new, jinak si s tím mypy neporadí if not krestni or not prijmeni: raise mo.CheckError('Osoba s daným emailem zatím neexistuje, je nutné uvést její jméno.') @@ -91,10 +97,14 @@ def find_or_create_user(email: str, krestni: Optional[str], prijmeni: Optional[s raise mo.CheckError(f'Osoba již registrována s odlišným jménem {user.full_name()}') if (user.is_admin or user.is_org) != is_org: if is_org: - raise mo.CheckError('Nelze předefinovat účastníka na organizátora') + if allow_change_user_to_org: + change_user_to_org(user, reason) + is_change_user_to_org = True + else: + raise CheckErrorOrgIsUser('Nelze předefinovat účastníka na organizátora.') else: - raise mo.CheckError('Nelze předefinovat organizátora na účastníka') - return user, is_new + raise CheckError('Nelze předefinovat organizátora na účastníka.') + return user, is_new, is_change_user_to_org def find_or_create_participant(user: db.User, year: int, school_id: Optional[int], birth_year: Optional[int], grade: Optional[str], reason: str) -> Tuple[db.Participant, bool]: diff --git a/mo/web/org_contest.py b/mo/web/org_contest.py index f2524acc0ac046ea583a0581111373d6e8f4ff80..65fb7a654649a81190b54f8d9f058888bdc94004 100644 --- a/mo/web/org_contest.py +++ b/mo/web/org_contest.py @@ -1634,7 +1634,7 @@ def org_contest_add_user(ct_id: int, site_id: Optional[int] = None): if form.validate_on_submit(): try: - user, is_new_user = mo.users.find_or_create_user(form.email.data, form.first_name.data, form.last_name.data, False, reason='web') + user, is_new_user, is_change_user_to_org = mo.users.find_or_create_user(form.email.data, form.first_name.data, form.last_name.data, False, reason='web') participant, is_new_participant = mo.users.find_or_create_participant(user, contest.round.year, form.school.get_place_id(), form.birth_year.data, form.grade.data, reason='web') participation, is_new_participation = mo.users.find_or_create_participation(user, contest, form.participation_place.get_place(), reason='web') except mo.CheckError as e: