diff --git a/project/access.py b/project/access.py index 6e7fb67..62d5d13 100644 --- a/project/access.py +++ b/project/access.py @@ -4,9 +4,9 @@ from flask_login import login_user from flask_principal import Permission, RoleNeed from flask_security import current_user from flask_security.utils import FsPermNeed -from sqlalchemy import and_ +from sqlalchemy import and_, exists -from project import app +from project import app, db from project.models import AdminUnit, AdminUnitMember, Event, PublicStatus, User from project.models.admin_unit import AdminUnitMemberRole from project.services.admin_unit import get_member_for_admin_unit_by_user_id @@ -145,16 +145,16 @@ def can_request_event_reference(event): if event.public_status != PublicStatus.published: return False - return len(get_admin_units_for_event_reference_request(event)) > 0 - - -def get_admin_units_for_event_reference_request(event): - return AdminUnit.query.filter( - and_( - AdminUnit.id != event.admin_unit_id, - AdminUnit.incoming_reference_requests_allowed, + return db.session.scalar( + exists() + .where( + and_( + AdminUnit.id != event.admin_unit_id, + AdminUnit.incoming_reference_requests_allowed, + ) ) - ).all() + .select() + ) def admin_units_the_current_user_is_member_of(): diff --git a/project/api/organization/resources.py b/project/api/organization/resources.py index ef94690..83ce142 100644 --- a/project/api/organization/resources.py +++ b/project/api/organization/resources.py @@ -93,7 +93,7 @@ from project.services.reference import ( get_reference_outgoing_query, get_relation_outgoing_query, ) -from project.views.utils import send_mail +from project.views.utils import get_current_admin_unit_for_api, send_mail class OrganizationResource(BaseResource): @@ -224,8 +224,19 @@ class OrganizationListResource(BaseResource): login_api_user() include_unverified = can_verify_admin_unit() + reference_request_for_admin_unit_id = None - pagination = get_admin_unit_query(keyword, include_unverified).paginate() + if "for_reference_request" in request.args: + admin_unit = get_current_admin_unit_for_api() + + if admin_unit: + reference_request_for_admin_unit_id = admin_unit.id + + pagination = get_admin_unit_query( + keyword, + include_unverified, + reference_request_for_admin_unit_id=reference_request_for_admin_unit_id, + ).paginate() return pagination diff --git a/project/services/admin_unit.py b/project/services/admin_unit.py index a506ea4..4079778 100644 --- a/project/services/admin_unit.py +++ b/project/services/admin_unit.py @@ -20,6 +20,10 @@ from project.models import ( ) from project.services.image import upsert_image_with_data from project.services.location import assign_location_values +from project.services.reference import ( + get_newest_reference_requests, + get_newest_references, +) def insert_admin_unit_for_user(admin_unit, user, invitation=None): @@ -175,6 +179,7 @@ def get_admin_unit_query( keyword=None, include_unverified=False, only_verifier=False, + reference_request_for_admin_unit_id=None, ): query = AdminUnit.query @@ -187,6 +192,13 @@ def get_admin_unit_query( ) query = query.filter(only_verifier_filter) + if reference_request_for_admin_unit_id: + request_filter = and_( + AdminUnit.id != reference_request_for_admin_unit_id, + AdminUnit.incoming_reference_requests_allowed, + ) + query = query.filter(request_filter) + if keyword: like_keyword = "%" + keyword + "%" order_keyword = keyword + "%" @@ -384,3 +396,49 @@ def get_admin_units_with_due_delete_request(): def delete_admin_unit(admin_unit: AdminUnit): db.session.delete(admin_unit) db.session.commit() + + +def get_admin_unit_suggestions_for_reference_requests(admin_unit, max_choices=5): + admin_unit_ids = [] + admin_unit_choices = [] + selected_ids = [] + + def add_admin_units(admin_units, selected=True): + for admin_unit in admin_units: + if admin_unit.id in admin_unit_ids: + continue + + admin_unit_ids.append(admin_unit.id) + admin_unit_choices.append(admin_unit) + + if selected: + selected_ids.append(admin_unit.id) + + # Neuste ausgehende Empfehlungsanfragen + limit = max_choices - len(admin_unit_ids) + reference_requests = get_newest_reference_requests(admin_unit.id, limit) + add_admin_units([r.admin_unit for r in reference_requests]) + + # Neuste ausgehende Empfehlungen + limit = max_choices - len(admin_unit_ids) + if limit > 0: + references = get_newest_references(admin_unit.id, limit) + add_admin_units([r.admin_unit for r in references]) + + # Eingehende Beziehungen, die Organisation oder Events automatisch verifizieren + limit = max_choices - len(admin_unit_ids) + if limit > 0: + relations = get_admin_unit_relations_for_reference_requests( + admin_unit.id, limit + ) + add_admin_units([r.source_admin_unit for r in relations]) + + # Organisationen, die eingehende Empfehlungsanfragen erlauben + limit = max_choices - len(admin_unit_ids) + if limit > 0: + admin_units_for_reference = get_admin_units_for_reference_requests( + admin_unit.id, limit + ) + add_admin_units(admin_units_for_reference, False) + + return (admin_unit_choices, selected_ids) diff --git a/project/templates/event/reference_request.html b/project/templates/event/reference_request.html index 75c000d..ce5bd0a 100644 --- a/project/templates/event/reference_request.html +++ b/project/templates/event/reference_request.html @@ -1,8 +1,57 @@ {% extends "layout.html" %} -{% from "_macros.html" import render_field_with_errors, render_field %} +{% from "_macros.html" import render_field_with_errors, render_field, render_form_styles, render_form_scripts %} + {%- block title -%} {{ event.name }} {%- endblock -%} + +{% block styles %} +{{ render_form_styles() }} +{% endblock %} + +{% block header_before_site_js %} +{{ render_form_scripts() }} +{%- endblock -%} + +{% block header %} + +{% endblock %} + {% block content %}