diff --git a/messages.pot b/messages.pot index 144a7d0..58eaf01 100644 --- a/messages.pot +++ b/messages.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2021-10-14 14:32+0200\n" +"POT-Creation-Date: 2021-10-20 23:30+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -207,7 +207,7 @@ msgstr "" #: project/forms/admin.py:12 project/templates/_macros.html:1409 #: project/templates/layout.html:316 #: project/templates/widget/event_suggestion/create.html:204 -#: project/views/admin_unit.py:50 project/views/root.py:58 +#: project/views/admin_unit.py:73 project/views/root.py:58 msgid "Contact" msgstr "" @@ -277,37 +277,37 @@ msgstr "" msgid "Update organization" msgstr "" -#: project/forms/admin_unit.py:14 project/forms/event_place.py:12 +#: project/forms/admin_unit.py:15 project/forms/event_place.py:12 #: project/forms/organizer.py:12 msgid "Street" msgstr "" -#: project/forms/admin_unit.py:15 project/forms/event_place.py:13 +#: project/forms/admin_unit.py:16 project/forms/event_place.py:13 #: project/forms/organizer.py:13 msgid "Postal code" msgstr "" -#: project/forms/admin_unit.py:16 project/forms/event_place.py:14 +#: project/forms/admin_unit.py:17 project/forms/event_place.py:14 #: project/forms/organizer.py:14 msgid "City" msgstr "" -#: project/forms/admin_unit.py:17 project/forms/event_place.py:15 +#: project/forms/admin_unit.py:18 project/forms/event_place.py:15 #: project/forms/organizer.py:15 msgid "State" msgstr "" -#: project/forms/admin_unit.py:19 project/forms/event_place.py:17 +#: project/forms/admin_unit.py:20 project/forms/event_place.py:17 #: project/forms/organizer.py:17 msgid "Latitude" msgstr "" -#: project/forms/admin_unit.py:22 project/forms/event_place.py:20 +#: project/forms/admin_unit.py:23 project/forms/event_place.py:20 #: project/forms/organizer.py:20 msgid "Longitude" msgstr "" -#: project/forms/admin_unit.py:28 project/forms/event.py:36 +#: project/forms/admin_unit.py:29 project/forms/event.py:36 #: project/forms/event.py:65 project/forms/event.py:398 #: project/forms/event_place.py:25 project/forms/event_place.py:50 #: project/forms/event_suggestion.py:26 project/forms/oauth2_client.py:66 @@ -319,25 +319,25 @@ msgstr "" msgid "Name" msgstr "" -#: project/forms/admin_unit.py:31 +#: project/forms/admin_unit.py:32 msgid "Short name" msgstr "" -#: project/forms/admin_unit.py:32 +#: project/forms/admin_unit.py:33 msgid "The short name is used to create a unique identifier for your events" msgstr "" -#: project/forms/admin_unit.py:40 project/templates/_macros.html:1545 +#: project/forms/admin_unit.py:41 project/templates/_macros.html:1545 msgid "Short name must contain only letters numbers or underscore" msgstr "" -#: project/forms/admin_unit.py:46 project/forms/event.py:57 +#: project/forms/admin_unit.py:47 project/forms/event.py:57 #: project/forms/event.py:95 project/forms/event_place.py:26 #: project/forms/organizer.py:26 msgid "Link URL" msgstr "" -#: project/forms/admin_unit.py:47 project/forms/admin_unit_member.py:11 +#: project/forms/admin_unit.py:48 project/forms/admin_unit_member.py:11 #: project/forms/admin_unit_member.py:23 project/forms/admin_unit_member.py:28 #: project/forms/event.py:58 project/forms/event_suggestion.py:38 #: project/forms/organizer.py:27 project/templates/_macros.html:262 @@ -345,44 +345,62 @@ msgstr "" msgid "Email" msgstr "" -#: project/forms/admin_unit.py:48 project/forms/event.py:59 +#: project/forms/admin_unit.py:49 project/forms/event.py:59 #: project/forms/event_suggestion.py:31 project/forms/organizer.py:28 #: project/templates/_macros.html:315 msgid "Phone" msgstr "" -#: project/forms/admin_unit.py:49 project/forms/event.py:60 +#: project/forms/admin_unit.py:50 project/forms/event.py:60 #: project/forms/organizer.py:29 project/templates/_macros.html:323 msgid "Fax" msgstr "" -#: project/forms/admin_unit.py:50 project/forms/organizer.py:30 +#: project/forms/admin_unit.py:51 project/forms/organizer.py:30 msgid "Logo" msgstr "" -#: project/forms/admin_unit.py:63 project/templates/admin_unit/create.html:5 +#: project/forms/admin_unit.py:65 +msgid "Verify new organization" +msgstr "" + +#: project/forms/admin_unit.py:66 +msgid "If set, events of the new organization are publicly visible." +msgstr "" + +#: project/forms/admin_unit.py:72 project/forms/reference_request.py:86 +msgid "Verify reference requests automatically" +msgstr "" + +#: project/forms/admin_unit.py:73 +msgid "" +"If set, all upcoming reference requests of the new organization are " +"verified automatically." +msgstr "" + +#: project/forms/admin_unit.py:84 project/templates/admin_unit/create.html:5 #: project/templates/admin_unit/create.html:22 #: project/templates/manage/admin_units.html:27 msgid "Create organization" msgstr "" -#: project/forms/admin_unit.py:67 project/forms/admin_unit.py:90 +#: project/forms/admin_unit.py:92 project/forms/admin_unit.py:115 msgid "Update settings" msgstr "" -#: project/forms/admin_unit.py:71 +#: project/forms/admin_unit.py:96 msgid "Font" msgstr "" -#: project/forms/admin_unit.py:73 +#: project/forms/admin_unit.py:98 msgid "Background Color" msgstr "" -#: project/forms/admin_unit.py:79 +#: project/forms/admin_unit.py:104 msgid "Primary Color" msgstr "" -#: project/forms/admin_unit.py:85 +#: project/forms/admin_unit.py:110 msgid "Link Color" msgstr "" @@ -1099,10 +1117,6 @@ msgstr "" msgid "Choose why you rejected the request." msgstr "" -#: project/forms/reference_request.py:86 -msgid "Verify reference requests automatically" -msgstr "" - #: project/forms/reference_request.py:90 msgid "Save review" msgstr "" @@ -1499,6 +1513,11 @@ msgstr "" msgid "Additional information" msgstr "" +#: project/templates/admin_unit/create.html:71 +#, python-format +msgid "Relation to %(admin_unit_name)s" +msgstr "" + #: project/templates/admin_unit/invite_member.html:6 #: project/templates/manage/members.html:12 msgid "Invite user" @@ -1910,21 +1929,21 @@ msgstr "" msgid "User successfully updated" msgstr "" -#: project/views/admin_unit.py:46 +#: project/views/admin_unit.py:69 msgid "" "Organizations cannot currently be created. The project is in a closed " "test phase. If you are interested, you can contact us." msgstr "" -#: project/views/admin_unit.py:79 +#: project/views/admin_unit.py:115 msgid "Organization successfully created" msgstr "" -#: project/views/admin_unit.py:105 +#: project/views/admin_unit.py:145 msgid "AdminUnit successfully updated" msgstr "" -#: project/views/admin_unit.py:127 +#: project/views/admin_unit.py:167 msgid "Organization invitation accepted" msgstr "" @@ -2115,22 +2134,22 @@ msgid "" "verified automatically." msgstr "" -#: project/views/utils.py:54 +#: project/views/utils.py:76 msgid "" "An entry with the entered values ​​already exists. Duplicate entries are " "not allowed." msgstr "" -#: project/views/utils.py:105 +#: project/views/utils.py:127 #, python-format msgid "Error in the %s field - %s" msgstr "" -#: project/views/utils.py:112 +#: project/views/utils.py:134 msgid "Show" msgstr "" -#: project/views/utils.py:119 +#: project/views/utils.py:141 msgid "You do not have permission for this action" msgstr "" diff --git a/project/forms/admin_unit.py b/project/forms/admin_unit.py index be6af9b..7e91548 100644 --- a/project/forms/admin_unit.py +++ b/project/forms/admin_unit.py @@ -1,13 +1,14 @@ from flask_babelex import lazy_gettext from flask_wtf import FlaskForm from wtforms import DecimalField, FormField, StringField, SubmitField +from wtforms.fields.core import BooleanField from wtforms.fields.html5 import EmailField, TelField, URLField from wtforms.validators import DataRequired, Length, Optional, Regexp from wtforms.widgets.html5 import ColorInput from project.forms.common import Base64ImageForm from project.forms.widgets import HTML5StringField -from project.models import Image, Location +from project.models import AdminUnitRelation, Image, Location class AdminUnitLocationForm(FlaskForm): @@ -59,9 +60,33 @@ class BaseAdminUnitForm(FlaskForm): field.populate_obj(obj, name) +class AdminUnitRelationForm(FlaskForm): + verify = BooleanField( + lazy_gettext("Verify new organization"), + description=lazy_gettext( + "If set, events of the new organization are publicly visible." + ), + validators=[Optional()], + ) + auto_verify_event_reference_requests = BooleanField( + lazy_gettext("Verify reference requests automatically"), + description=lazy_gettext( + "If set, all upcoming reference requests of the new organization are verified automatically." + ), + validators=[Optional()], + ) + + class CreateAdminUnitForm(BaseAdminUnitForm): + embedded_relation = FormField( + AdminUnitRelationForm, default=lambda: AdminUnitRelation() + ) submit = SubmitField(lazy_gettext("Create organization")) + def populate_obj(self, obj): + super().populate_obj(obj) + delattr(obj, "embedded_relation") + class UpdateAdminUnitForm(BaseAdminUnitForm): submit = SubmitField(lazy_gettext("Update settings")) diff --git a/project/jinja_filters.py b/project/jinja_filters.py index 9a5729f..06c0bae 100644 --- a/project/jinja_filters.py +++ b/project/jinja_filters.py @@ -1,7 +1,7 @@ import os from urllib.parse import quote_plus -from flask import request, url_for +from flask import url_for from project import app from project.utils import ( @@ -60,6 +60,8 @@ app.jinja_env.globals.update( @app.context_processor def get_context_processors(): + from project.views.utils import get_current_admin_unit + def get_manage_menu_options(admin_unit): from project.access import has_access from project.services.event_suggestion import get_event_reviews_badge_query @@ -80,25 +82,6 @@ def get_context_processors(): "reference_requests_incoming_badge": reference_requests_incoming_badge, } - def get_current_admin_unit(): - from flask_security import current_user - - from project.access import get_admin_units_for_manage - from project.views.utils import get_manage_admin_unit_from_request - - admin_unit = None - - if current_user.is_authenticated: - admin_unit = get_manage_admin_unit_from_request(request) - - if not admin_unit: - admin_units = get_admin_units_for_manage() - - if len(admin_units) > 0: - admin_unit = admin_units[0] - - return admin_unit - return dict( current_admin_unit=get_current_admin_unit(), get_manage_menu_options=get_manage_menu_options, diff --git a/project/requests.py b/project/requests.py index 64ae4a5..f3b3c2f 100644 --- a/project/requests.py +++ b/project/requests.py @@ -8,9 +8,10 @@ from project import app @app.after_request def set_manage_admin_unit_cookie(response): - manage_admin_unit_id = getattr(g, "manage_admin_unit_id", 0) - if manage_admin_unit_id > 0: - encoded = encode_cookie(str(manage_admin_unit_id)) + admin_unit = getattr(g, "manage_admin_unit", None) + + if admin_unit: + encoded = encode_cookie(str(admin_unit.id)) response.set_cookie( "manage_admin_unit_id", value=encoded, diff --git a/project/templates/admin_unit/create.html b/project/templates/admin_unit/create.html index de2e844..d0e077e 100644 --- a/project/templates/admin_unit/create.html +++ b/project/templates/admin_unit/create.html @@ -65,6 +65,22 @@ + {% if embedded_relation_enabled %} +
+
+ {{ _('Relation to %(admin_unit_name)s', admin_unit_name=current_admin_unit.name) }} +
+
+ {% if current_admin_unit.can_verify_other %} + {{ render_field_with_errors(form.embedded_relation.verify, ri="switch") }} + {% endif %} + {% if current_admin_unit.incoming_reference_requests_allowed %} + {{ render_field_with_errors(form.embedded_relation.auto_verify_event_reference_requests, ri="switch") }} + {% endif %} +
+
+ {% endif %} + {{ render_field(form.submit) }} diff --git a/project/translations/de/LC_MESSAGES/messages.mo b/project/translations/de/LC_MESSAGES/messages.mo index 6f1881f..313ea3d 100644 Binary files a/project/translations/de/LC_MESSAGES/messages.mo and b/project/translations/de/LC_MESSAGES/messages.mo differ diff --git a/project/translations/de/LC_MESSAGES/messages.po b/project/translations/de/LC_MESSAGES/messages.po index 86b2f96..dd94600 100644 --- a/project/translations/de/LC_MESSAGES/messages.po +++ b/project/translations/de/LC_MESSAGES/messages.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2021-10-14 14:32+0200\n" +"POT-Creation-Date: 2021-10-20 23:30+0200\n" "PO-Revision-Date: 2020-06-07 18:51+0200\n" "Last-Translator: FULL NAME \n" "Language: de\n" @@ -208,7 +208,7 @@ msgstr "Impressum" #: project/forms/admin.py:12 project/templates/_macros.html:1409 #: project/templates/layout.html:316 #: project/templates/widget/event_suggestion/create.html:204 -#: project/views/admin_unit.py:50 project/views/root.py:58 +#: project/views/admin_unit.py:73 project/views/root.py:58 msgid "Contact" msgstr "Kontakt" @@ -286,37 +286,37 @@ msgstr "" msgid "Update organization" msgstr "Organisation aktualisieren" -#: project/forms/admin_unit.py:14 project/forms/event_place.py:12 +#: project/forms/admin_unit.py:15 project/forms/event_place.py:12 #: project/forms/organizer.py:12 msgid "Street" msgstr "Straße" -#: project/forms/admin_unit.py:15 project/forms/event_place.py:13 +#: project/forms/admin_unit.py:16 project/forms/event_place.py:13 #: project/forms/organizer.py:13 msgid "Postal code" msgstr "Postleitzahl" -#: project/forms/admin_unit.py:16 project/forms/event_place.py:14 +#: project/forms/admin_unit.py:17 project/forms/event_place.py:14 #: project/forms/organizer.py:14 msgid "City" msgstr "Stadt/Ort" -#: project/forms/admin_unit.py:17 project/forms/event_place.py:15 +#: project/forms/admin_unit.py:18 project/forms/event_place.py:15 #: project/forms/organizer.py:15 msgid "State" msgstr "Bundesland" -#: project/forms/admin_unit.py:19 project/forms/event_place.py:17 +#: project/forms/admin_unit.py:20 project/forms/event_place.py:17 #: project/forms/organizer.py:17 msgid "Latitude" msgstr "Breitengrad" -#: project/forms/admin_unit.py:22 project/forms/event_place.py:20 +#: project/forms/admin_unit.py:23 project/forms/event_place.py:20 #: project/forms/organizer.py:20 msgid "Longitude" msgstr "Längengrad" -#: project/forms/admin_unit.py:28 project/forms/event.py:36 +#: project/forms/admin_unit.py:29 project/forms/event.py:36 #: project/forms/event.py:65 project/forms/event.py:398 #: project/forms/event_place.py:25 project/forms/event_place.py:50 #: project/forms/event_suggestion.py:26 project/forms/oauth2_client.py:66 @@ -328,28 +328,28 @@ msgstr "Längengrad" msgid "Name" msgstr "Name" -#: project/forms/admin_unit.py:31 +#: project/forms/admin_unit.py:32 msgid "Short name" msgstr "Kurzname" -#: project/forms/admin_unit.py:32 +#: project/forms/admin_unit.py:33 msgid "The short name is used to create a unique identifier for your events" msgstr "" "Der Kurzname wird verwendet, um die Veranstaltungen der Organisation " "eindeutig zu identifizieren. Der Kurzname darf nur Buchstaben, Nummern " "und Unterstriche enthalten." -#: project/forms/admin_unit.py:40 project/templates/_macros.html:1545 +#: project/forms/admin_unit.py:41 project/templates/_macros.html:1545 msgid "Short name must contain only letters numbers or underscore" msgstr "Der Kurzname darf nur Buchstaben, Nummern und Unterstriche enthalten" -#: project/forms/admin_unit.py:46 project/forms/event.py:57 +#: project/forms/admin_unit.py:47 project/forms/event.py:57 #: project/forms/event.py:95 project/forms/event_place.py:26 #: project/forms/organizer.py:26 msgid "Link URL" msgstr "Link URL" -#: project/forms/admin_unit.py:47 project/forms/admin_unit_member.py:11 +#: project/forms/admin_unit.py:48 project/forms/admin_unit_member.py:11 #: project/forms/admin_unit_member.py:23 project/forms/admin_unit_member.py:28 #: project/forms/event.py:58 project/forms/event_suggestion.py:38 #: project/forms/organizer.py:27 project/templates/_macros.html:262 @@ -357,44 +357,62 @@ msgstr "Link URL" msgid "Email" msgstr "Email" -#: project/forms/admin_unit.py:48 project/forms/event.py:59 +#: project/forms/admin_unit.py:49 project/forms/event.py:59 #: project/forms/event_suggestion.py:31 project/forms/organizer.py:28 #: project/templates/_macros.html:315 msgid "Phone" msgstr "Telefon" -#: project/forms/admin_unit.py:49 project/forms/event.py:60 +#: project/forms/admin_unit.py:50 project/forms/event.py:60 #: project/forms/organizer.py:29 project/templates/_macros.html:323 msgid "Fax" msgstr "Fax" -#: project/forms/admin_unit.py:50 project/forms/organizer.py:30 +#: project/forms/admin_unit.py:51 project/forms/organizer.py:30 msgid "Logo" msgstr "Logo" -#: project/forms/admin_unit.py:63 project/templates/admin_unit/create.html:5 +#: project/forms/admin_unit.py:65 +msgid "Verify new organization" +msgstr "Neue Organisation verifizieren" + +#: project/forms/admin_unit.py:66 +msgid "If set, events of the new organization are publicly visible." +msgstr "Wenn gesetzt, sind Veranstaltungen der neuen Organisation öffentlich sichtbar." + +#: project/forms/admin_unit.py:72 project/forms/reference_request.py:86 +msgid "Verify reference requests automatically" +msgstr "Empfehlungsanfragen automatisch verifizieren" + +#: project/forms/admin_unit.py:73 +msgid "" +"If set, all upcoming reference requests of the new organization are " +"verified automatically." +msgstr "Wenn gesetzt, werden alle zukünftigen Empfehlungsanfragen der neuen Organisation automatisch verifiziert." + +#: project/forms/admin_unit.py:84 project/templates/admin_unit/create.html:5 #: project/templates/admin_unit/create.html:22 #: project/templates/manage/admin_units.html:27 msgid "Create organization" msgstr "Organisation erstellen" -#: project/forms/admin_unit.py:67 project/forms/admin_unit.py:90 +#: project/forms/admin_unit.py:92 project/forms/admin_unit.py:115 msgid "Update settings" msgstr "Einstellungen speichern" -#: project/forms/admin_unit.py:71 +#: project/forms/admin_unit.py:96 msgid "Font" msgstr "Schriftart" -#: project/forms/admin_unit.py:73 +#: project/forms/admin_unit.py:98 msgid "Background Color" msgstr "Hintergrundfarbe" -#: project/forms/admin_unit.py:79 +#: project/forms/admin_unit.py:104 msgid "Primary Color" msgstr "Hauptfarbe" -#: project/forms/admin_unit.py:85 +#: project/forms/admin_unit.py:110 msgid "Link Color" msgstr "Linkfarbe" @@ -1141,10 +1159,6 @@ msgstr "Unzulässig" msgid "Choose why you rejected the request." msgstr "Wähle aus, warum du die Anfrage abgelehnt hast." -#: project/forms/reference_request.py:86 -msgid "Verify reference requests automatically" -msgstr "Empfehlungsanfragen automatisch verifizieren" - #: project/forms/reference_request.py:90 msgid "Save review" msgstr "Prüfung speichern" @@ -1543,6 +1557,11 @@ msgstr "Bearbeiten" msgid "Additional information" msgstr "Zusätzliche Informationen" +#: project/templates/admin_unit/create.html:71 +#, python-format +msgid "Relation to %(admin_unit_name)s" +msgstr "Beziehung zu %(admin_unit_name)s" + #: project/templates/admin_unit/invite_member.html:6 #: project/templates/manage/members.html:12 msgid "Invite user" @@ -1960,7 +1979,7 @@ msgstr "Einstellungen erfolgreich aktualisiert" msgid "User successfully updated" msgstr "Nutzer erfolgreich aktualisiert" -#: project/views/admin_unit.py:46 +#: project/views/admin_unit.py:69 msgid "" "Organizations cannot currently be created. The project is in a closed " "test phase. If you are interested, you can contact us." @@ -1969,15 +1988,15 @@ msgstr "" " sich in einer geschlossenen Test-Phase. Bei Interesse kannst du uns " "kontaktieren." -#: project/views/admin_unit.py:79 +#: project/views/admin_unit.py:115 msgid "Organization successfully created" msgstr "Organisation erfolgreich erstellt" -#: project/views/admin_unit.py:105 +#: project/views/admin_unit.py:145 msgid "AdminUnit successfully updated" msgstr "Organisation erfolgreich aktualisiert" -#: project/views/admin_unit.py:127 +#: project/views/admin_unit.py:167 msgid "Organization invitation accepted" msgstr "Organisationseinladung akzeptiert" @@ -2172,7 +2191,7 @@ msgstr "" "Ob alle zukünftigen Empfehlungsanfragen von %(admin_unit_name)s " "automatisch verifiziert werden sollen." -#: project/views/utils.py:54 +#: project/views/utils.py:76 msgid "" "An entry with the entered values ​​already exists. Duplicate entries are " "not allowed." @@ -2180,16 +2199,16 @@ msgstr "" "Ein Eintrag mit den eingegebenen Werten existiert bereits. Doppelte " "Einträge sind nicht erlaubt." -#: project/views/utils.py:105 +#: project/views/utils.py:127 #, python-format msgid "Error in the %s field - %s" msgstr "Fehler im Feld %s: %s" -#: project/views/utils.py:112 +#: project/views/utils.py:134 msgid "Show" msgstr "Anzeigen" -#: project/views/utils.py:119 +#: project/views/utils.py:141 msgid "You do not have permission for this action" msgstr "Du hast keine Berechtigung für diese Aktion" diff --git a/project/translations/en/LC_MESSAGES/messages.mo b/project/translations/en/LC_MESSAGES/messages.mo index 8b55c32..c83b0a5 100644 Binary files a/project/translations/en/LC_MESSAGES/messages.mo and b/project/translations/en/LC_MESSAGES/messages.mo differ diff --git a/project/translations/en/LC_MESSAGES/messages.po b/project/translations/en/LC_MESSAGES/messages.po index ee54eaf..dcf6dc1 100644 --- a/project/translations/en/LC_MESSAGES/messages.po +++ b/project/translations/en/LC_MESSAGES/messages.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2021-10-14 14:32+0200\n" +"POT-Creation-Date: 2021-10-20 23:30+0200\n" "PO-Revision-Date: 2021-04-30 15:04+0200\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -208,7 +208,7 @@ msgstr "" #: project/forms/admin.py:12 project/templates/_macros.html:1409 #: project/templates/layout.html:316 #: project/templates/widget/event_suggestion/create.html:204 -#: project/views/admin_unit.py:50 project/views/root.py:58 +#: project/views/admin_unit.py:73 project/views/root.py:58 msgid "Contact" msgstr "" @@ -278,37 +278,37 @@ msgstr "" msgid "Update organization" msgstr "" -#: project/forms/admin_unit.py:14 project/forms/event_place.py:12 +#: project/forms/admin_unit.py:15 project/forms/event_place.py:12 #: project/forms/organizer.py:12 msgid "Street" msgstr "" -#: project/forms/admin_unit.py:15 project/forms/event_place.py:13 +#: project/forms/admin_unit.py:16 project/forms/event_place.py:13 #: project/forms/organizer.py:13 msgid "Postal code" msgstr "" -#: project/forms/admin_unit.py:16 project/forms/event_place.py:14 +#: project/forms/admin_unit.py:17 project/forms/event_place.py:14 #: project/forms/organizer.py:14 msgid "City" msgstr "" -#: project/forms/admin_unit.py:17 project/forms/event_place.py:15 +#: project/forms/admin_unit.py:18 project/forms/event_place.py:15 #: project/forms/organizer.py:15 msgid "State" msgstr "" -#: project/forms/admin_unit.py:19 project/forms/event_place.py:17 +#: project/forms/admin_unit.py:20 project/forms/event_place.py:17 #: project/forms/organizer.py:17 msgid "Latitude" msgstr "" -#: project/forms/admin_unit.py:22 project/forms/event_place.py:20 +#: project/forms/admin_unit.py:23 project/forms/event_place.py:20 #: project/forms/organizer.py:20 msgid "Longitude" msgstr "" -#: project/forms/admin_unit.py:28 project/forms/event.py:36 +#: project/forms/admin_unit.py:29 project/forms/event.py:36 #: project/forms/event.py:65 project/forms/event.py:398 #: project/forms/event_place.py:25 project/forms/event_place.py:50 #: project/forms/event_suggestion.py:26 project/forms/oauth2_client.py:66 @@ -320,25 +320,25 @@ msgstr "" msgid "Name" msgstr "" -#: project/forms/admin_unit.py:31 +#: project/forms/admin_unit.py:32 msgid "Short name" msgstr "" -#: project/forms/admin_unit.py:32 +#: project/forms/admin_unit.py:33 msgid "The short name is used to create a unique identifier for your events" msgstr "" -#: project/forms/admin_unit.py:40 project/templates/_macros.html:1545 +#: project/forms/admin_unit.py:41 project/templates/_macros.html:1545 msgid "Short name must contain only letters numbers or underscore" msgstr "" -#: project/forms/admin_unit.py:46 project/forms/event.py:57 +#: project/forms/admin_unit.py:47 project/forms/event.py:57 #: project/forms/event.py:95 project/forms/event_place.py:26 #: project/forms/organizer.py:26 msgid "Link URL" msgstr "" -#: project/forms/admin_unit.py:47 project/forms/admin_unit_member.py:11 +#: project/forms/admin_unit.py:48 project/forms/admin_unit_member.py:11 #: project/forms/admin_unit_member.py:23 project/forms/admin_unit_member.py:28 #: project/forms/event.py:58 project/forms/event_suggestion.py:38 #: project/forms/organizer.py:27 project/templates/_macros.html:262 @@ -346,44 +346,62 @@ msgstr "" msgid "Email" msgstr "" -#: project/forms/admin_unit.py:48 project/forms/event.py:59 +#: project/forms/admin_unit.py:49 project/forms/event.py:59 #: project/forms/event_suggestion.py:31 project/forms/organizer.py:28 #: project/templates/_macros.html:315 msgid "Phone" msgstr "" -#: project/forms/admin_unit.py:49 project/forms/event.py:60 +#: project/forms/admin_unit.py:50 project/forms/event.py:60 #: project/forms/organizer.py:29 project/templates/_macros.html:323 msgid "Fax" msgstr "" -#: project/forms/admin_unit.py:50 project/forms/organizer.py:30 +#: project/forms/admin_unit.py:51 project/forms/organizer.py:30 msgid "Logo" msgstr "" -#: project/forms/admin_unit.py:63 project/templates/admin_unit/create.html:5 +#: project/forms/admin_unit.py:65 +msgid "Verify new organization" +msgstr "" + +#: project/forms/admin_unit.py:66 +msgid "If set, events of the new organization are publicly visible." +msgstr "" + +#: project/forms/admin_unit.py:72 project/forms/reference_request.py:86 +msgid "Verify reference requests automatically" +msgstr "" + +#: project/forms/admin_unit.py:73 +msgid "" +"If set, all upcoming reference requests of the new organization are " +"verified automatically." +msgstr "" + +#: project/forms/admin_unit.py:84 project/templates/admin_unit/create.html:5 #: project/templates/admin_unit/create.html:22 #: project/templates/manage/admin_units.html:27 msgid "Create organization" msgstr "" -#: project/forms/admin_unit.py:67 project/forms/admin_unit.py:90 +#: project/forms/admin_unit.py:92 project/forms/admin_unit.py:115 msgid "Update settings" msgstr "" -#: project/forms/admin_unit.py:71 +#: project/forms/admin_unit.py:96 msgid "Font" msgstr "" -#: project/forms/admin_unit.py:73 +#: project/forms/admin_unit.py:98 msgid "Background Color" msgstr "" -#: project/forms/admin_unit.py:79 +#: project/forms/admin_unit.py:104 msgid "Primary Color" msgstr "" -#: project/forms/admin_unit.py:85 +#: project/forms/admin_unit.py:110 msgid "Link Color" msgstr "" @@ -1100,10 +1118,6 @@ msgstr "Illegal" msgid "Choose why you rejected the request." msgstr "" -#: project/forms/reference_request.py:86 -msgid "Verify reference requests automatically" -msgstr "" - #: project/forms/reference_request.py:90 msgid "Save review" msgstr "" @@ -1500,6 +1514,11 @@ msgstr "" msgid "Additional information" msgstr "" +#: project/templates/admin_unit/create.html:71 +#, python-format +msgid "Relation to %(admin_unit_name)s" +msgstr "" + #: project/templates/admin_unit/invite_member.html:6 #: project/templates/manage/members.html:12 msgid "Invite user" @@ -1911,21 +1930,21 @@ msgstr "" msgid "User successfully updated" msgstr "" -#: project/views/admin_unit.py:46 +#: project/views/admin_unit.py:69 msgid "" "Organizations cannot currently be created. The project is in a closed " "test phase. If you are interested, you can contact us." msgstr "" -#: project/views/admin_unit.py:79 +#: project/views/admin_unit.py:115 msgid "Organization successfully created" msgstr "" -#: project/views/admin_unit.py:105 +#: project/views/admin_unit.py:145 msgid "AdminUnit successfully updated" msgstr "" -#: project/views/admin_unit.py:127 +#: project/views/admin_unit.py:167 msgid "Organization invitation accepted" msgstr "" @@ -2116,22 +2135,22 @@ msgid "" "verified automatically." msgstr "" -#: project/views/utils.py:54 +#: project/views/utils.py:76 msgid "" "An entry with the entered values ​​already exists. Duplicate entries are " "not allowed." msgstr "" -#: project/views/utils.py:105 +#: project/views/utils.py:127 #, python-format msgid "Error in the %s field - %s" msgstr "" -#: project/views/utils.py:112 +#: project/views/utils.py:134 msgid "Show" msgstr "" -#: project/views/utils.py:119 +#: project/views/utils.py:141 msgid "You do not have permission for this action" msgstr "" diff --git a/project/views/admin_unit.py b/project/views/admin_unit.py index a1a1a12..57e5763 100644 --- a/project/views/admin_unit.py +++ b/project/views/admin_unit.py @@ -12,21 +12,44 @@ from project.access import ( ) from project.forms.admin_unit import CreateAdminUnitForm, UpdateAdminUnitForm from project.models import AdminUnit, AdminUnitInvitation, AdminUnitRelation, Location -from project.services.admin_unit import insert_admin_unit_for_user +from project.services.admin_unit import ( + insert_admin_unit_for_user, + upsert_admin_unit_relation, +) from project.utils import strings_are_equal_ignoring_case from project.views.utils import ( flash_errors, flash_message, + get_current_admin_unit, handleSqlError, permission_missing, send_mails, ) -def update_admin_unit_with_form(admin_unit, form): +def update_admin_unit_with_form(admin_unit, form, embedded_relation_enabled=False): form.populate_obj(admin_unit) +def add_relation(admin_unit, form, current_admin_unit): + embedded_relation = form.embedded_relation.object_data + + verify = embedded_relation.verify and current_admin_unit.can_verify_other + auto_verify_event_reference_requests = ( + embedded_relation.auto_verify_event_reference_requests + and current_admin_unit.incoming_reference_requests_allowed + ) + + if not verify and not auto_verify_event_reference_requests: + return + + relation = upsert_admin_unit_relation(current_admin_unit.id, admin_unit.id) + relation.verify = verify + relation.auto_verify_event_reference_requests = auto_verify_event_reference_requests + + db.session.commit() + + @app.route("/admin_unit/create", methods=("GET", "POST")) @auth_required() def admin_unit_create(): @@ -57,6 +80,20 @@ def admin_unit_create(): if invitation and not form.is_submitted(): form.name.data = invitation.admin_unit_name + current_admin_unit = get_current_admin_unit() + embedded_relation_enabled = ( + not invitation + and current_admin_unit + and has_access(current_admin_unit, "admin_unit:update") + and ( + current_admin_unit.can_verify_other + or current_admin_unit.incoming_reference_requests_allowed + ) + ) + + if embedded_relation_enabled and not form.is_submitted(): + form.embedded_relation.verify.data = True + if form.validate_on_submit(): admin_unit = AdminUnit() admin_unit.location = Location() @@ -67,7 +104,10 @@ def admin_unit_create(): admin_unit, current_user, invitation ) - if relation: + if embedded_relation_enabled: + add_relation(admin_unit, form, current_admin_unit) + + if invitation and relation: send_admin_unit_invitation_accepted_mails( invitation, relation, admin_unit ) @@ -84,7 +124,11 @@ def admin_unit_create(): else: flash_errors(form) - return render_template("admin_unit/create.html", form=form) + return render_template( + "admin_unit/create.html", + form=form, + embedded_relation_enabled=embedded_relation_enabled, + ) @app.route("/admin_unit//update", methods=("GET", "POST")) diff --git a/project/views/manage.py b/project/views/manage.py index 45fcb9b..6fa9376 100644 --- a/project/views/manage.py +++ b/project/views/manage.py @@ -1,4 +1,4 @@ -from flask import flash, g, redirect, render_template, request, url_for +from flask import flash, redirect, render_template, request, url_for from flask_babelex import gettext from flask_security import auth_required, current_user from sqlalchemy.exc import SQLAlchemyError @@ -32,10 +32,11 @@ from project.services.event_suggestion import get_event_reviews_query from project.views.event import get_event_category_choices from project.views.utils import ( flash_errors, - get_manage_admin_unit_from_request, + get_current_admin_unit, get_pagination_urls, handleSqlError, permission_missing, + set_current_admin_unit, ) @@ -48,7 +49,7 @@ def manage_after_login(): @app.route("/manage") @auth_required() def manage(): - admin_unit = get_manage_admin_unit_from_request(request) + admin_unit = get_current_admin_unit(False) if admin_unit: return redirect(url_for("manage_admin_unit", id=admin_unit.id)) @@ -115,7 +116,7 @@ def manage_admin_units(): @auth_required() def manage_admin_unit(id): admin_unit = get_admin_unit_for_manage_or_404(id) - g.manage_admin_unit_id = id + set_current_admin_unit(admin_unit) return redirect(url_for("manage_admin_unit_events", id=admin_unit.id)) @@ -123,7 +124,7 @@ def manage_admin_unit(id): @auth_required() def manage_admin_unit_event_reviews(id): admin_unit = get_admin_unit_for_manage_or_404(id) - g.manage_admin_unit_id = id + set_current_admin_unit(admin_unit) admin_unit_suggestions_enabled_or_404(admin_unit) event_suggestions_paginate = ( @@ -145,7 +146,7 @@ def manage_admin_unit_event_reviews(id): @auth_required() def manage_admin_unit_events(id): admin_unit = get_admin_unit_for_manage_or_404(id) - g.manage_admin_unit_id = id + set_current_admin_unit(admin_unit) params = EventSearchParams() @@ -180,7 +181,7 @@ def manage_admin_unit_events(id): @auth_required() def manage_admin_unit_organizers(id): admin_unit = get_admin_unit_for_manage_or_404(id) - g.manage_admin_unit_id = id + set_current_admin_unit(admin_unit) organizers = ( EventOrganizer.query.filter(EventOrganizer.admin_unit_id == admin_unit.id) @@ -200,7 +201,7 @@ def manage_admin_unit_organizers(id): @auth_required() def manage_admin_unit_event_places(id): admin_unit = get_admin_unit_for_manage_or_404(id) - g.manage_admin_unit_id = id + set_current_admin_unit(admin_unit) form = FindEventPlaceForm(**request.args) @@ -222,7 +223,7 @@ def manage_admin_unit_event_places(id): @auth_required() def manage_admin_unit_members(id): admin_unit = get_admin_unit_for_manage_or_404(id) - g.manage_admin_unit_id = id + set_current_admin_unit(admin_unit) if not has_access(admin_unit, "admin_unit.members:read"): return permission_missing(url_for("manage_admin_unit", id=id)) @@ -256,7 +257,7 @@ def manage_admin_unit_members(id): @auth_required() def manage_admin_unit_relations(id, path=None): admin_unit = get_admin_unit_for_manage_or_404(id) - g.manage_admin_unit_id = id + set_current_admin_unit(admin_unit) return render_template( "manage/relations.html", @@ -269,7 +270,7 @@ def manage_admin_unit_relations(id, path=None): @auth_required() def manage_admin_unit_organization_invitations(id, path=None): admin_unit = get_admin_unit_for_manage_or_404(id) - g.manage_admin_unit_id = id + set_current_admin_unit(admin_unit) return render_template( "manage/organization_invitations.html", @@ -281,7 +282,7 @@ def manage_admin_unit_organization_invitations(id, path=None): @auth_required() def manage_admin_unit_widgets(id): admin_unit = get_admin_unit_for_manage_or_404(id) - g.manage_admin_unit_id = id + set_current_admin_unit(admin_unit) default_background_color = "#ffffff" default_primary_color = "#007bff" diff --git a/project/views/utils.py b/project/views/utils.py index ab3ff33..83f78e6 100644 --- a/project/views/utils.py +++ b/project/views/utils.py @@ -4,22 +4,45 @@ from flask import Markup, flash, g, redirect, render_template, request, url_for from flask_babelex import gettext from flask_login.utils import decode_cookie from flask_mail import Message +from flask_security import current_user from psycopg2.errorcodes import UNIQUE_VIOLATION from sqlalchemy.exc import SQLAlchemyError from wtforms import FormField from project import app, db, mail -from project.access import get_admin_unit_for_manage +from project.access import get_admin_unit_for_manage, get_admin_units_for_manage from project.dateutils import berlin_tz, round_to_next_day from project.models import Analytics, EventAttendanceMode, EventDate from project.utils import get_place_str -def get_manage_admin_unit_from_request(request): - manage_admin_unit_id = getattr(g, "manage_admin_unit_id", 0) - if manage_admin_unit_id > 0: - return get_admin_unit_for_manage(manage_admin_unit_id) +def set_current_admin_unit(admin_unit): + if admin_unit: + setattr(g, "manage_admin_unit", admin_unit) + +def get_current_admin_unit(fallback=True): + admin_unit = getattr(g, "manage_admin_unit", None) + + if admin_unit: + return admin_unit + + if current_user.is_authenticated: + admin_unit = get_current_admin_unit_from_cookies() + + if not admin_unit and fallback: + admin_units = get_admin_units_for_manage() + + if len(admin_units) > 0: + admin_unit = admin_units[0] + + if admin_unit: + set_current_admin_unit(admin_unit) + + return admin_unit + + +def get_current_admin_unit_from_cookies(): try: if "manage_admin_unit_id" in request.cookies: encoded = request.cookies.get("manage_admin_unit_id") diff --git a/tests/conftest.py b/tests/conftest.py index 24c1d09..140639d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -26,6 +26,7 @@ def app(): app.config["SERVER_NAME"] = None app.config["TESTING"] = True + app.config["ADMIN_UNIT_CREATE_REQUIRES_ADMIN"] = False app.testing = True return app diff --git a/tests/views/test_admin_unit.py b/tests/views/test_admin_unit.py index 8e58107..18ee349 100644 --- a/tests/views/test_admin_unit.py +++ b/tests/views/test_admin_unit.py @@ -205,6 +205,38 @@ def test_create_from_invitation_currentUserDoesNotMatchInvitationEmail( utils.assert_response_redirect(response, "manage_admin_units") +def test_create_with_relation(client, app, utils, seeder): + user_id = seeder.create_user(admin=False) + utils.login() + admin_unit_id = seeder.create_admin_unit(user_id, can_verify_other=True) + + url = utils.get_url("admin_unit_create") + response = utils.get_ok(url) + + response = utils.post_form( + url, + response, + { + "name": "Other Crew", + "short_name": "other_crew", + "location-postalCode": "38640", + "location-city": "Goslar", + }, + ) + assert response.status_code == 302 + + with app.app_context(): + from project.services.admin_unit import get_admin_unit_by_name + + admin_unit = get_admin_unit_by_name("Other Crew") + assert admin_unit is not None + + relation = admin_unit.incoming_relations[0] + assert relation.source_admin_unit_id == admin_unit_id + assert relation.auto_verify_event_reference_requests is False + assert relation.verify + + def test_update(client, app, utils, seeder): seeder.create_user() user_id = utils.login()