from flask import abort, flash, redirect, render_template, url_for from flask_babel import gettext from flask_security import auth_required from sqlalchemy.exc import SQLAlchemyError from project import app, db from project.access import can_request_event_reference, get_admin_unit_for_manage_or_404 from project.forms.reference_request import CreateEventReferenceRequestForm from project.models import ( Event, EventReferenceRequest, EventReferenceRequestReviewStatus, ) from project.models.event_reference import EventReference from project.services.admin_unit import ( get_admin_unit_by_id, get_admin_unit_relation, get_admin_unit_suggestions_for_reference_requests, ) from project.services.reference import ( create_event_reference_for_request, get_reference_requests_incoming_query, get_reference_requests_outgoing_query, ) from project.services.search_params import EventReferenceRequestSearchParams from project.views.utils import ( flash_errors, get_pagination_urls, handleSqlError, send_template_mails_to_admin_unit_members_async, ) @app.route("/manage/admin_unit//reference_requests/incoming") @auth_required() def manage_admin_unit_reference_requests_incoming(id): admin_unit = get_admin_unit_for_manage_or_404(id) params = EventReferenceRequestSearchParams() params.admin_unit_id = admin_unit.id requests = get_reference_requests_incoming_query(params).paginate() return render_template( "manage/reference_requests_incoming.html", admin_unit=admin_unit, requests=requests.items, pagination=get_pagination_urls(requests, id=id), ) @app.route("/manage/admin_unit//reference_requests/outgoing") @auth_required() def manage_admin_unit_reference_requests_outgoing(id): admin_unit = get_admin_unit_for_manage_or_404(id) params = EventReferenceRequestSearchParams() params.admin_unit_id = admin_unit.id requests = get_reference_requests_outgoing_query(params).paginate() return render_template( "manage/reference_requests_outgoing.html", admin_unit=admin_unit, requests=requests.items, pagination=get_pagination_urls(requests, id=id), ) @app.route("/event//reference_request/create", methods=("GET", "POST")) @auth_required() def event_reference_request_create(event_id): event = Event.query.get_or_404(event_id) if not can_request_event_reference(event): abort(401) form = CreateEventReferenceRequestForm() if form.admin_unit_id.data and form.admin_unit_id.data > 0: admin_unit = get_admin_unit_by_id(form.admin_unit_id.data) if admin_unit: form.admin_unit_id.choices = [(admin_unit.id, admin_unit.name)] if not form.admin_unit_id.choices: ( admin_unit_choices, selected_ids, ) = get_admin_unit_suggestions_for_reference_requests( event.admin_unit, max_choices=1 ) form.admin_unit_id.choices = [(a.id, a.name) for a in admin_unit_choices] form.admin_unit_id.data = ( admin_unit_choices[0].id if len(admin_unit_choices) > 0 else None ) if form.validate_on_submit(): reference_request = EventReferenceRequest() form.populate_obj(reference_request) reference_request.event = event try: db.session.add(reference_request) reference, msg = handle_request_according_to_relation( reference_request, event ) db.session.commit() send_reference_request_mails(reference_request, reference) flash(msg, "success") return redirect( url_for( "manage_admin_unit_reference_requests_outgoing", id=event.admin_unit_id, ) ) except SQLAlchemyError as e: db.session.rollback() flash(handleSqlError(e), "danger") else: flash_errors(form) return render_template("event/reference_request.html", form=form, event=event) def handle_request_according_to_relation( request: EventReferenceRequest, event: Event ) -> str: admin_unit = ( request.admin_unit if request.admin_unit else get_admin_unit_by_id(request.admin_unit_id) ) relation = get_admin_unit_relation(admin_unit.id, event.admin_unit_id) auto_verify = relation and relation.auto_verify_event_reference_requests reference = None if auto_verify: request.review_status = EventReferenceRequestReviewStatus.verified reference = create_event_reference_for_request(request) msg = gettext( "%(organization)s accepted your reference request", organization=admin_unit.name, ) else: request.review_status = EventReferenceRequestReviewStatus.inbox msg = gettext( "Reference request to %(organization)s successfully created. You will be notified after the other organization reviews the event.", organization=admin_unit.name, ) return reference, msg def send_reference_request_mails( request: EventReferenceRequest, reference: EventReference ): if reference: _send_auto_reference_mails(reference) else: _send_reference_request_inbox_mails(request) def _send_reference_request_inbox_mails(request): _send_member_reference_request_verify_mails( request.admin_unit_id, "reference_request_notice", request=request, ) def _send_auto_reference_mails(reference): _send_member_reference_request_verify_mails( reference.admin_unit_id, "reference_auto_verified_notice", reference=reference, ) def _send_member_reference_request_verify_mails(admin_unit_id, template, **context): # Benachrichtige alle Mitglieder der AdminUnit, die Requests verifizieren können send_template_mails_to_admin_unit_members_async( admin_unit_id, "reference_request:verify", template, **context )