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 sqlalchemy.sql import desc from project import app, db from project.access import ( can_request_event_reference, get_admin_unit_for_manage_or_404, get_admin_unit_members_with_permission, ) from project.forms.reference_request import CreateEventReferenceRequestForm from project.models import ( Event, EventReferenceRequest, EventReferenceRequestReviewStatus, ) 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, ) from project.views.utils import ( flash_errors, get_pagination_urls, handleSqlError, send_mails_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) requests = ( get_reference_requests_incoming_query(admin_unit) .order_by(desc(EventReferenceRequest.created_at)) .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) requests = ( EventReferenceRequest.query.join(Event) .filter(Event.admin_unit_id == admin_unit.id) .order_by(desc(EventReferenceRequest.created_at)) .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(): request = EventReferenceRequest() form.populate_obj(request) request.event = event try: db.session.add(request) msg = handle_request_according_to_relation(request, event) db.session.commit() 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 = get_admin_unit_by_id(request.admin_unit_id) relation = get_admin_unit_relation(request.admin_unit_id, event.admin_unit_id) auto_verify = relation and relation.auto_verify_event_reference_requests if auto_verify: request.review_status = EventReferenceRequestReviewStatus.verified reference = create_event_reference_for_request(request) send_auto_reference_inbox_mails(reference) msg = gettext( "%(organization)s accepted your reference request", organization=admin_unit.name, ) else: request.review_status = EventReferenceRequestReviewStatus.inbox send_reference_request_inbox_mails(request) 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 msg def send_member_reference_request_verify_mails( admin_unit_id, subject, template, **context ): # Benachrichtige alle Mitglieder der AdminUnit, die Requests verifizieren können members = get_admin_unit_members_with_permission( admin_unit_id, "reference_request:verify" ) emails = list(map(lambda member: member.user.email, members)) send_mails_async(emails, subject, template, **context) def send_reference_request_inbox_mails(request): send_member_reference_request_verify_mails( request.admin_unit_id, gettext("New reference request"), "reference_request_notice", request=request, ) def send_auto_reference_inbox_mails(reference): send_member_reference_request_verify_mails( reference.admin_unit_id, gettext("New reference automatically verified"), "reference_auto_verified_notice", reference=reference, )