mirror of
https://github.com/lucaspalomodevelop/eventcally.git
synced 2026-03-13 00:07:22 +00:00
Für ein Event kann man eine andere Organisation fragen, ob sie dieses Event referenzieren/empfehlen möchten.
This commit is contained in:
parent
ac818fae9c
commit
0c7f6a4dc8
5
app.py
5
app.py
@ -2,7 +2,6 @@ import os
|
||||
from base64 import b64decode
|
||||
from flask import jsonify, Flask, render_template, request, url_for, redirect, abort, flash, current_app
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
from sqlalchemy.orm import joinedload
|
||||
from sqlalchemy.sql import asc, func
|
||||
from sqlalchemy import and_, or_, not_
|
||||
@ -13,7 +12,6 @@ from flask_principal import Permission
|
||||
from flask_cors import CORS
|
||||
import pytz
|
||||
import json
|
||||
from urllib.parse import quote_plus
|
||||
from flask_qrcode import QRcode
|
||||
from flask_mail import Mail, Message
|
||||
|
||||
@ -40,8 +38,6 @@ app.config['BABEL_DEFAULT_LOCALE'] = 'de'
|
||||
app.config['BABEL_DEFAULT_TIMEZONE'] = 'Europe/Berlin'
|
||||
babel = Babel(app)
|
||||
|
||||
app.jinja_env.filters['quote_plus'] = lambda u: quote_plus(u)
|
||||
|
||||
# cors
|
||||
cors = CORS(app, resources={r"/api/*": {"origins": "*"}})
|
||||
|
||||
@ -100,6 +96,7 @@ from views import (
|
||||
organizer,
|
||||
reference,
|
||||
reference_request,
|
||||
reference_request_review,
|
||||
root,
|
||||
user,
|
||||
widget
|
||||
|
||||
@ -3,6 +3,7 @@ from flask_wtf import FlaskForm
|
||||
from wtforms import SelectField, StringField, SubmitField
|
||||
from wtforms.validators import DataRequired
|
||||
from .common import event_rating_choices
|
||||
from models import EventReferenceRequestRejectionReason, EventReferenceRequestReviewStatus
|
||||
|
||||
class CreateEventReferenceRequestForm(FlaskForm):
|
||||
admin_unit_id = SelectField(lazy_gettext('Admin unit'), validators=[DataRequired()], coerce=int)
|
||||
@ -10,4 +11,20 @@ class CreateEventReferenceRequestForm(FlaskForm):
|
||||
|
||||
class DeleteReferenceRequestForm(FlaskForm):
|
||||
submit = SubmitField(lazy_gettext("Delete request"))
|
||||
name = StringField(lazy_gettext('Name'), validators=[DataRequired()])
|
||||
name = StringField(lazy_gettext('Name'), validators=[DataRequired()])
|
||||
|
||||
class ReferenceRequestReviewForm(FlaskForm):
|
||||
review_status = SelectField(lazy_gettext('Review status'), coerce=int, choices=[
|
||||
(int(EventReferenceRequestReviewStatus.inbox), lazy_gettext('EventReferenceRequestReviewStatus.inbox')),
|
||||
(int(EventReferenceRequestReviewStatus.verified), lazy_gettext('EventReferenceRequestReviewStatus.verified')),
|
||||
(int(EventReferenceRequestReviewStatus.rejected), lazy_gettext('EventReferenceRequestReviewStatus.rejected'))])
|
||||
|
||||
rejection_reason = SelectField(lazy_gettext('Rejection reason'), coerce=int, choices=[
|
||||
(0, ''),
|
||||
(int(EventReferenceRequestRejectionReason.duplicate), lazy_gettext('EventReferenceRequestRejectionReason.duplicate')),
|
||||
(int(EventReferenceRequestRejectionReason.untrustworthy), lazy_gettext('EventReferenceRequestRejectionReason.untrustworthy')),
|
||||
(int(EventReferenceRequestRejectionReason.irrelevant), lazy_gettext('EventReferenceRequestRejectionReason.irrelevant')),
|
||||
(int(EventReferenceRequestRejectionReason.illegal), lazy_gettext('EventReferenceRequestRejectionReason.illegal'))])
|
||||
|
||||
rating = SelectField(lazy_gettext('Rating'), default=50, coerce=int, choices=event_rating_choices)
|
||||
submit = SubmitField(lazy_gettext("Save review"))
|
||||
@ -1,5 +1,6 @@
|
||||
from app import app
|
||||
from utils import get_event_category_name, get_localized_enum_name
|
||||
from urllib.parse import quote_plus
|
||||
import os
|
||||
|
||||
def env_override(value, key):
|
||||
@ -7,4 +8,5 @@ def env_override(value, key):
|
||||
|
||||
app.jinja_env.filters['event_category_name'] = lambda u: get_event_category_name(u)
|
||||
app.jinja_env.filters['loc_enum'] = lambda u: get_localized_enum_name(u)
|
||||
app.jinja_env.filters['env_override'] = env_override
|
||||
app.jinja_env.filters['env_override'] = env_override
|
||||
app.jinja_env.filters['quote_plus'] = lambda u: quote_plus(u)
|
||||
14
services/reference.py
Normal file
14
services/reference.py
Normal file
@ -0,0 +1,14 @@
|
||||
from app import db
|
||||
from models import EventReference, EventReferenceRequest
|
||||
from sqlalchemy import and_, or_, not_
|
||||
|
||||
def create_event_reference_for_request(request):
|
||||
result = EventReference.query.filter(and_(EventReference.event_id == request.event_id,
|
||||
EventReference.admin_unit_id == request.admin_unit_id)).first()
|
||||
|
||||
if result is None:
|
||||
result = EventReference(event_id = request.event_id,
|
||||
admin_unit_id = request.admin_unit_id)
|
||||
db.session.add(result)
|
||||
|
||||
return result
|
||||
@ -218,9 +218,9 @@
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_reference_review_status_pill(reference) %}
|
||||
{% if reference.review_status and reference.review_status != 2 %}
|
||||
<span class="badge badge-pill {% if reference.review_status == 1 %}badge-info{% else %}badge-danger{% endif %}">{{ reference.review_status | loc_enum }}</span>
|
||||
{% macro render_reference_request_review_status_pill(reference_request) %}
|
||||
{% if reference_request.review_status %}
|
||||
<span class="badge badge-pill {% if reference_request.review_status == 1 %}badge-info{% elif reference_request.review_status == 2 %}badge-success{% else %}badge-danger{% endif %}">{{ reference_request.review_status | loc_enum }}</span>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
@ -265,6 +265,11 @@
|
||||
{{ render_enum_prop(event.rejection_resaon, 'fa-search-minus', 'Rejection reason') }}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_reference_request_review_status(reference_request) %}
|
||||
{{ render_enum_prop(reference_request.review_status, 'fa-certificate', 'Review status') }}
|
||||
{{ render_enum_prop(reference_request.rejection_reason, 'fa-search-minus', 'Rejection reason') }}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_event_props(event, start, end, dates = None, show_rating = False) %}
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
@ -476,8 +481,10 @@
|
||||
<ul class="nav nav-pills">
|
||||
{{ render_tab('reviews', _('Reviews'), url_for('manage_admin_unit_event_reviews', id=admin_unit.id), active_id) }}
|
||||
{{ render_tab('events', _('Events'), url_for('manage_admin_unit_events', id=admin_unit.id), active_id) }}
|
||||
{{ render_tab('references', _('References'), url_for('manage_admin_unit_references', id=admin_unit.id), active_id) }}
|
||||
{{ render_tab('reference_requests', _('Reference requests'), url_for('manage_admin_unit_reference_requests', id=admin_unit.id), active_id) }}
|
||||
{{ render_tab('references_incoming', _('Incoming references'), url_for('manage_admin_unit_references_incoming', id=admin_unit.id), active_id) }}
|
||||
{{ render_tab('references_outgoing', _('Outgoing references'), url_for('manage_admin_unit_references_outgoing', id=admin_unit.id), active_id) }}
|
||||
{{ render_tab('reference_requests_incoming', _('Incoming reference requests'), url_for('manage_admin_unit_reference_requests_incoming', id=admin_unit.id), active_id) }}
|
||||
{{ render_tab('reference_requests_outgoing', _('Outgoing reference requests'), url_for('manage_admin_unit_reference_requests_outgoing', id=admin_unit.id), active_id) }}
|
||||
{{ render_tab('organizers', _('Organizers'), url_for('manage_admin_unit_organizers', id=admin_unit.id), active_id) }}
|
||||
{{ render_tab('places', _('Places'), url_for('manage_admin_unit_event_places', id=admin_unit.id), active_id) }}
|
||||
{{ render_tab('members', _('Members'), url_for('manage_admin_unit_members', id=admin_unit.id), active_id) }}
|
||||
|
||||
6
templates/email/reference_request_notice.html
Normal file
6
templates/email/reference_request_notice.html
Normal file
@ -0,0 +1,6 @@
|
||||
{% extends "email/layout.html" %}
|
||||
{% from "_macros.html" import render_email_button %}
|
||||
{% block content %}
|
||||
<p>{{ _('There is a new event reference request that needs to be reviewed.') }}</p>
|
||||
{{ render_email_button(url_for('event_reference_request_review', id=request.id, _external=True), _('Click here to review the request')) }}
|
||||
{% endblock %}
|
||||
3
templates/email/reference_request_notice.txt
Normal file
3
templates/email/reference_request_notice.txt
Normal file
@ -0,0 +1,3 @@
|
||||
{{ _('There is a new event reference request that needs to be reviewed.') }}
|
||||
{{ _('Click the link below to review the request') }}
|
||||
{{ url_for('event_reference_request_review', id=request.id, _external=True) }}
|
||||
@ -0,0 +1,6 @@
|
||||
{% extends "email/layout.html" %}
|
||||
{% from "_macros.html" import render_email_button %}
|
||||
{% block content %}
|
||||
<p>{{ _('The review status of your event reference request has been updated.') }}</p>
|
||||
{{ render_email_button(url_for('event_review_status', event_id=event.id, _external=True), _('Click here to view the status')) }}
|
||||
{% endblock %}
|
||||
@ -0,0 +1,3 @@
|
||||
{{ _('The review status of your event reference request has been updated.') }}
|
||||
{{ _('Click the link below to view the status') }}
|
||||
{{ url_for('event_review_status', event_id=event.id, _external=True) }}
|
||||
@ -18,7 +18,7 @@
|
||||
<a class="btn btn-outline-primary my-1" href="{{ url_for('event_reference', event_id=event.id) }}" role="button"><i class="fa fa-link"></i> {{ _('Reference event') }}</a>
|
||||
{% endif %}
|
||||
{% if user_can_create_reference_request %}
|
||||
<a class="btn btn-outline-primary my-1" href="{{ url_for('event_reference_request', event_id=event.id) }}" role="button"><i class="fa fa-link"></i> {{ _('Empfehlung anfragen') }}</a>
|
||||
<a class="btn btn-outline-primary my-1" href="{{ url_for('event_reference_request_create', event_id=event.id) }}" role="button"><i class="fa fa-link"></i> {{ _('Empfehlung anfragen') }}</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
{% extends "layout.html" %}
|
||||
{% from "_macros.html" import render_request_review_status_pill, render_event_status_pill, render_event_date, render_pagination, render_event_organizer, render_manage_menu %}
|
||||
{% from "_macros.html" import render_reference_request_review_status_pill, render_event_status_pill, render_event_date, render_pagination, render_event_organizer, render_manage_menu %}
|
||||
{% block title %}
|
||||
{{ _('Reference requests') }}
|
||||
{% endblock %}
|
||||
@ -7,7 +7,7 @@
|
||||
|
||||
<h1>{{ admin_unit.name }}</h1>
|
||||
|
||||
{{ render_manage_menu(admin_unit, 'reference_requests') }}
|
||||
{{ render_manage_menu(admin_unit, 'reference_requests_incoming') }}
|
||||
|
||||
<ul class="list-group mt-4">
|
||||
{% for request in requests %}
|
||||
@ -16,10 +16,10 @@
|
||||
<div class="dropdown d-inline-block">
|
||||
<button class="btn btn-link dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{{ request.event.name }}</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="url_for('event_reference_request_review', event_id=event.id)">{{ _('Review request') }}...</a>
|
||||
<a class="dropdown-item" href="{{ url_for('event_reference_request_review', id=request.id) }}">{{ _('Review request') }}...</a>
|
||||
</div>
|
||||
</div>
|
||||
{{ render_event_status_pill(request.event) }}
|
||||
{{ render_reference_request_review_status_pill(request) }}
|
||||
<small>{{ request.event.admin_unit.name }}</small>
|
||||
</li>
|
||||
{% endfor %}
|
||||
30
templates/manage/reference_requests_outgoing.html
Normal file
30
templates/manage/reference_requests_outgoing.html
Normal file
@ -0,0 +1,30 @@
|
||||
{% extends "layout.html" %}
|
||||
{% from "_macros.html" import render_reference_request_review_status_pill, render_event_status_pill, render_event_date, render_pagination, render_event_organizer, render_manage_menu %}
|
||||
{% block title %}
|
||||
{{ _('Reference requests') }}
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
<h1>{{ admin_unit.name }}</h1>
|
||||
|
||||
{{ render_manage_menu(admin_unit, 'reference_requests_outgoing') }}
|
||||
|
||||
<ul class="list-group mt-4">
|
||||
{% for request in requests %}
|
||||
<li class="list-group-item">
|
||||
{{ render_event_date(request.event) }}
|
||||
<div class="dropdown d-inline-block">
|
||||
<button class="btn btn-link dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{{ request.event.name }}</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="{{ url_for('event_reference_request_review_status', id=request.id) }}">{{ _('Show review status') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
{{ render_reference_request_review_status_pill(request) }}
|
||||
<small>{{ request.admin_unit.name }}</small>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<div class="my-4">{{ render_pagination(pagination) }}</div>
|
||||
|
||||
{% endblock %}
|
||||
@ -1,5 +1,5 @@
|
||||
{% extends "layout.html" %}
|
||||
{% from "_macros.html" import render_reference_review_status_pill, render_event_status_pill, render_event_date, render_pagination, render_event_organizer, render_manage_menu %}
|
||||
{% from "_macros.html" import render_event_status_pill, render_event_date, render_pagination, render_event_organizer, render_manage_menu %}
|
||||
{% block title %}
|
||||
{{ _('References') }}
|
||||
{% endblock %}
|
||||
@ -7,7 +7,7 @@
|
||||
|
||||
<h1>{{ admin_unit.name }}</h1>
|
||||
|
||||
{{ render_manage_menu(admin_unit, 'references') }}
|
||||
{{ render_manage_menu(admin_unit, 'references_incoming') }}
|
||||
|
||||
<ul class="list-group mt-4">
|
||||
{% for reference in references %}
|
||||
30
templates/manage/references_outgoing.html
Normal file
30
templates/manage/references_outgoing.html
Normal file
@ -0,0 +1,30 @@
|
||||
{% extends "layout.html" %}
|
||||
{% from "_macros.html" import render_event_status_pill, render_event_date, render_pagination, render_event_organizer, render_manage_menu %}
|
||||
{% block title %}
|
||||
{{ _('References') }}
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
<h1>{{ admin_unit.name }}</h1>
|
||||
|
||||
{{ render_manage_menu(admin_unit, 'references_outgoing') }}
|
||||
|
||||
<ul class="list-group mt-4">
|
||||
{% for reference in references %}
|
||||
<li class="list-group-item">
|
||||
{{ render_event_date(reference.event) }}
|
||||
<div class="dropdown d-inline-block">
|
||||
<button class="btn btn-link dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{{ reference.event.name }}</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="{{ url_for('event', event_id=reference.event.id) }}">{{ _('View') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
{{ render_event_status_pill(reference.event) }}
|
||||
<small>{{ reference.admin_unit.name }}</small>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<div class="my-4">{{ render_pagination(pagination) }}</div>
|
||||
|
||||
{% endblock %}
|
||||
42
templates/reference_request/review.html
Normal file
42
templates/reference_request/review.html
Normal file
@ -0,0 +1,42 @@
|
||||
{% extends "layout.html" %}
|
||||
{% from "_macros.html" import render_radio_buttons, render_phone_prop, render_email_prop, render_string_prop, render_field_with_errors, render_field, render_event_props, render_image_with_link, render_place, render_link_prop %}
|
||||
{% block title %}
|
||||
{{ event.name }}
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
<h1>{{ _('Review event reference request') }}</h1>
|
||||
|
||||
<form action="" method="POST">
|
||||
{{ form.hidden_tag() }}
|
||||
|
||||
{{ render_field_with_errors(form.review_status) }}
|
||||
{{ render_field_with_errors(form.rejection_reason) }}
|
||||
|
||||
{% if form.rating.choices|length > 1 %}
|
||||
{{ render_field_with_errors(form.rating) }}
|
||||
{% endif %}
|
||||
|
||||
{{ render_field(form.submit) }}
|
||||
</form>
|
||||
|
||||
<div class="mt-3" style="max-width: 768px;">
|
||||
|
||||
{{ render_event_props(event, event.start, event.end, dates) }}
|
||||
|
||||
{% if dates|length > 0 %}
|
||||
<div class="card mt-4">
|
||||
<div class="card-header">
|
||||
<a name="event-dates">{{ _('Event Dates') }}</a>
|
||||
</div>
|
||||
<div class="list-group list-group-flush">
|
||||
{% for date in dates %}
|
||||
<a href="#" class="list-group-item">{{ date.start | datetimeformat('short') }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
22
templates/reference_request/review_status.html
Normal file
22
templates/reference_request/review_status.html
Normal file
@ -0,0 +1,22 @@
|
||||
{% extends "layout.html" %}
|
||||
{% from "_macros.html" import render_reference_request_review_status, render_event_props, render_image_with_link, render_place, render_link_prop %}
|
||||
{% block title %}
|
||||
{{ event.name }}
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
<h1>{{ event.name }}</h1>
|
||||
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
{{ _('Review status') }}
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{{ render_reference_request_review_status(reference_request) }}
|
||||
{% if event.verified %}
|
||||
<a href="{{ url_for('event', event_id=event.id) }}">{{ _('View event') }}</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -2,6 +2,7 @@ from app import app
|
||||
from flask import url_for, render_template, request, redirect
|
||||
from flask_security import auth_required
|
||||
from models import AdminUnitMemberInvitation
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
|
||||
def update_admin_unit_with_form(admin_unit, form):
|
||||
form.populate_obj(admin_unit)
|
||||
|
||||
@ -7,6 +7,7 @@ from forms.admin_unit_member import DeleteAdminUnitMemberForm, UpdateAdminUnitMe
|
||||
from .utils import permission_missing, send_mail, handleSqlError, flash_errors
|
||||
from access import get_admin_unit_for_manage_or_404, has_access
|
||||
from services.admin_unit import add_roles_to_admin_unit_member
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
|
||||
@app.route('/manage/member/<int:id>/update', methods=('GET', 'POST'))
|
||||
@auth_required()
|
||||
|
||||
@ -7,6 +7,7 @@ from forms.admin_unit_member import NegotiateAdminUnitMemberInvitationForm, Invi
|
||||
from .utils import permission_missing, send_mail, handleSqlError, flash_errors
|
||||
from access import get_admin_unit_for_manage_or_404, has_access
|
||||
from services.admin_unit import add_user_to_admin_unit_with_roles
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
|
||||
@app.route('/invitations/<int:id>', methods=('GET', 'POST'))
|
||||
@auth_required()
|
||||
|
||||
@ -12,6 +12,7 @@ from utils import get_event_category_name
|
||||
from services.event import upsert_event_category, update_event_dates_with_recurrence_rule
|
||||
from services.organizer import get_event_places
|
||||
from sqlalchemy.sql import asc, func
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
|
||||
@app.route('/event/<int:event_id>')
|
||||
def event(event_id):
|
||||
|
||||
@ -7,6 +7,7 @@ from access import has_access, access_or_401, get_admin_unit_for_manage_or_404
|
||||
from forms.event_place import UpdateEventPlaceForm, CreateEventPlaceForm
|
||||
from .utils import flash_errors, upsert_image_with_data, send_mail
|
||||
from sqlalchemy.sql import asc, func
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
|
||||
@app.route('/manage/organizer/<int:id>/places/create', methods=('GET', 'POST'))
|
||||
@auth_required()
|
||||
|
||||
@ -7,6 +7,7 @@ from access import has_access, access_or_401, can_reference_event
|
||||
from dateutils import today
|
||||
from forms.event import ReviewEventForm
|
||||
from .utils import flash_errors, send_mail
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
|
||||
@app.route('/event/<int:event_id>/review', methods=('GET', 'POST'))
|
||||
def event_review(event_id):
|
||||
|
||||
@ -7,6 +7,7 @@ from access import has_access, access_or_401, get_admin_unit_for_manage_or_404
|
||||
from forms.organizer import CreateOrganizerForm, UpdateOrganizerForm, DeleteOrganizerForm
|
||||
from .utils import flash_errors, upsert_image_with_data, send_mail
|
||||
from sqlalchemy.sql import asc, func
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
|
||||
@app.route('/manage/admin_unit/<int:id>/organizers/create', methods=('GET', 'POST'))
|
||||
@auth_required()
|
||||
|
||||
@ -7,6 +7,8 @@ from flask_babelex import gettext
|
||||
from flask_security import auth_required
|
||||
from models import EventReference, Event
|
||||
from access import access_or_401, can_reference_event
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
from sqlalchemy.sql import desc
|
||||
|
||||
@app.route('/event/<int:event_id>/reference', methods=('GET', 'POST'))
|
||||
def event_reference(event_id):
|
||||
@ -52,7 +54,7 @@ def event_reference_update(id):
|
||||
try:
|
||||
db.session.commit()
|
||||
flash(gettext('Reference successfully updated'), 'success')
|
||||
return redirect(url_for('manage_admin_unit_references', id=reference.admin_unit_id))
|
||||
return redirect(url_for('manage_admin_unit_references_incoming', id=reference.admin_unit_id))
|
||||
except SQLAlchemyError as e:
|
||||
db.session.rollback()
|
||||
flash(handleSqlError(e), 'danger')
|
||||
@ -63,13 +65,24 @@ def event_reference_update(id):
|
||||
form=form,
|
||||
reference=reference)
|
||||
|
||||
@app.route('/manage/admin_unit/<int:id>/references')
|
||||
@app.route('/manage/admin_unit/<int:id>/references/incoming')
|
||||
@auth_required()
|
||||
def manage_admin_unit_references(id):
|
||||
def manage_admin_unit_references_incoming(id):
|
||||
admin_unit = get_admin_unit_for_manage_or_404(id)
|
||||
references = EventReference.query.filter(EventReference.admin_unit_id == admin_unit.id).order_by(EventReference.created_at).paginate()
|
||||
references = EventReference.query.filter(EventReference.admin_unit_id == admin_unit.id).order_by(desc(EventReference.created_at)).paginate()
|
||||
|
||||
return render_template('manage/references.html',
|
||||
return render_template('manage/references_incoming.html',
|
||||
admin_unit=admin_unit,
|
||||
references=references.items,
|
||||
pagination=get_pagination_urls(references, id=id))
|
||||
|
||||
@app.route('/manage/admin_unit/<int:id>/references/outgoing')
|
||||
@auth_required()
|
||||
def manage_admin_unit_references_outgoing(id):
|
||||
admin_unit = get_admin_unit_for_manage_or_404(id)
|
||||
references = EventReference.query.join(Event).filter(Event.admin_unit_id == admin_unit.id).order_by(desc(EventReference.created_at)).paginate()
|
||||
|
||||
return render_template('manage/references_outgoing.html',
|
||||
admin_unit=admin_unit,
|
||||
references=references.items,
|
||||
pagination=get_pagination_urls(references, id=id))
|
||||
@ -89,7 +102,7 @@ def reference_delete(id):
|
||||
db.session.delete(reference)
|
||||
db.session.commit()
|
||||
flash(gettext('Reference successfully deleted'), 'success')
|
||||
return redirect(url_for('manage_admin_unit_references', id=reference.admin_unit_id))
|
||||
return redirect(url_for('manage_admin_unit_references_incoming', id=reference.admin_unit_id))
|
||||
except SQLAlchemyError as e:
|
||||
db.session.rollback()
|
||||
flash(handleSqlError(e), 'danger')
|
||||
|
||||
@ -1,14 +1,39 @@
|
||||
from app import app, db
|
||||
from .utils import get_pagination_urls, flash_errors, handleSqlError
|
||||
from .utils import get_pagination_urls, flash_errors, handleSqlError, send_mail
|
||||
from forms.reference_request import CreateEventReferenceRequestForm, DeleteReferenceRequestForm
|
||||
from flask import render_template, flash, redirect, url_for
|
||||
from flask_babelex import gettext
|
||||
from flask_security import auth_required
|
||||
from models import EventReferenceRequest, Event, AdminUnit
|
||||
from access import access_or_401, get_admin_unit_for_manage_or_404
|
||||
from models import EventReferenceRequest, Event, AdminUnit, AdminUnitMember, User, EventReferenceRequestReviewStatus
|
||||
from access import access_or_401, get_admin_unit_for_manage_or_404, has_admin_unit_member_permission
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
from sqlalchemy import and_, or_, not_
|
||||
from sqlalchemy.sql import desc
|
||||
|
||||
@app.route('/event/<int:event_id>/reference_request', methods=('GET', 'POST'))
|
||||
def event_reference_request(event_id):
|
||||
@app.route('/manage/admin_unit/<int:id>/reference_requests/incoming')
|
||||
@auth_required()
|
||||
def manage_admin_unit_reference_requests_incoming(id):
|
||||
admin_unit = get_admin_unit_for_manage_or_404(id)
|
||||
requests = EventReferenceRequest.query.filter(and_(EventReferenceRequest.review_status != EventReferenceRequestReviewStatus.verified, EventReferenceRequest.admin_unit_id == admin_unit.id)).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/<int:id>/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/<int:event_id>/reference_request/create', methods=('GET', 'POST'))
|
||||
def event_reference_request_create(event_id):
|
||||
event = Event.query.get_or_404(event_id)
|
||||
access_or_401(event.admin_unit, 'reference_request:create')
|
||||
|
||||
@ -17,12 +42,14 @@ def event_reference_request(event_id):
|
||||
|
||||
if form.validate_on_submit():
|
||||
request = EventReferenceRequest()
|
||||
request.review_status = EventReferenceRequestReviewStatus.inbox
|
||||
form.populate_obj(request)
|
||||
request.event = event
|
||||
|
||||
try:
|
||||
db.session.add(request)
|
||||
db.session.commit()
|
||||
send_reference_request_inbox_mails(request)
|
||||
flash(gettext('Request successfully created'), 'success')
|
||||
return redirect(url_for('event', event_id=event.id))
|
||||
except SQLAlchemyError as e:
|
||||
@ -35,78 +62,13 @@ def event_reference_request(event_id):
|
||||
form=form,
|
||||
event=event)
|
||||
|
||||
@app.route('/manage/admin_unit/<int:id>/reference_requests')
|
||||
@auth_required()
|
||||
def manage_admin_unit_reference_requests(id):
|
||||
admin_unit = get_admin_unit_for_manage_or_404(id)
|
||||
requests = EventReferenceRequest.query.filter(EventReferenceRequest.admin_unit_id == admin_unit.id).order_by(EventReferenceRequest.created_at).paginate()
|
||||
def send_reference_request_inbox_mails(request):
|
||||
# Benachrichtige alle Mitglieder der AdminUnit, die diesen Request verifizieren können
|
||||
members = AdminUnitMember.query.join(User).filter(AdminUnitMember.admin_unit_id == request.admin_unit_id).all()
|
||||
|
||||
return render_template('manage/reference_requests.html',
|
||||
admin_unit=admin_unit,
|
||||
requests=requests.items,
|
||||
pagination=get_pagination_urls(requests, id=id))
|
||||
|
||||
# @app.route('/reference_request/<int:id>/review', methods=('GET', 'POST'))
|
||||
# def event_reference_request_review(id):
|
||||
# request = EventReferenceRequest.query.get_or_404(id)
|
||||
# event = Event.query.get_or_404(request.event_id)
|
||||
# dates = EventDate.query.with_parent(event).filter(EventDate.start >= today).order_by(EventDate.start).all()
|
||||
# user_can_verify_event = can_verify_event(event)
|
||||
|
||||
# if not user_can_verify_event:
|
||||
# abort(401)
|
||||
|
||||
# form = ReviewEventForm(obj=event)
|
||||
|
||||
# if form.validate_on_submit():
|
||||
# form.populate_obj(event)
|
||||
|
||||
# if event.review_status != EventReviewStatus.rejected:
|
||||
# event.rejection_resaon = None
|
||||
|
||||
# if event.rejection_resaon == 0:
|
||||
# event.rejection_resaon = None
|
||||
|
||||
# try:
|
||||
# db.session.commit()
|
||||
# send_event_review_status_mail(event)
|
||||
# flash(gettext('Event successfully updated'), 'success')
|
||||
# return redirect(url_for('manage_admin_unit_event_reviews', id=event.admin_unit_id))
|
||||
# except SQLAlchemyError as e:
|
||||
# db.session.rollback()
|
||||
# flash(handleSqlError(e), 'danger')
|
||||
# else:
|
||||
# flash_errors(form)
|
||||
|
||||
# return render_template('event/review.html',
|
||||
# form=form,
|
||||
# dates=dates,
|
||||
# event=event)
|
||||
|
||||
# @app.route('/reference/<int:id>/delete', methods=('GET', 'POST'))
|
||||
# def reference_delete(id):
|
||||
# reference = EventReference.query.get_or_404(id)
|
||||
|
||||
# if not can_delete_reference(reference):
|
||||
# abort(401)
|
||||
|
||||
# form = DeleteReferenceForm()
|
||||
|
||||
# if form.validate_on_submit():
|
||||
# if form.name.data != reference.event.name:
|
||||
# flash(gettext('Entered name does not match event name'), 'danger')
|
||||
# else:
|
||||
# try:
|
||||
# db.session.delete(reference)
|
||||
# db.session.commit()
|
||||
# flash(gettext('Reference successfully deleted'), 'success')
|
||||
# return redirect(url_for('manage_admin_unit_references', id=reference.admin_unit_id))
|
||||
# except SQLAlchemyError as e:
|
||||
# db.session.rollback()
|
||||
# flash(handleSqlError(e), 'danger')
|
||||
# else:
|
||||
# flash_errors(form)
|
||||
|
||||
# return render_template('reference/delete.html',
|
||||
# form=form,
|
||||
# reference=reference)
|
||||
for member in members:
|
||||
if has_admin_unit_member_permission(member, 'reference_request:verify'):
|
||||
send_mail(member.user.email,
|
||||
gettext('New reference request'),
|
||||
'reference_request_notice',
|
||||
request=request)
|
||||
|
||||
78
views/reference_request_review.py
Normal file
78
views/reference_request_review.py
Normal file
@ -0,0 +1,78 @@
|
||||
from app import app, db
|
||||
from models import Event, EventDate, EventReferenceRequest, EventReferenceRequestReviewStatus, AdminUnitMember, User
|
||||
from flask import render_template, flash, url_for, redirect
|
||||
from flask_babelex import gettext
|
||||
from flask_security import auth_required
|
||||
from access import has_access, access_or_401, can_reference_event
|
||||
from dateutils import today
|
||||
from forms.reference_request import ReferenceRequestReviewForm
|
||||
from .utils import flash_errors, send_mail
|
||||
from services.reference import create_event_reference_for_request
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
|
||||
@app.route('/reference_request/<int:id>/review', methods=('GET', 'POST'))
|
||||
def event_reference_request_review(id):
|
||||
request = EventReferenceRequest.query.get_or_404(id)
|
||||
access_or_401(request.admin_unit, 'reference_request:verify')
|
||||
|
||||
if request.review_status == EventReferenceRequestReviewStatus.verified:
|
||||
flash(gettext('Request already verified'), 'danger')
|
||||
return redirect(url_for('manage_admin_unit_reference_requests_incoming', id=request.admin_unit_id))
|
||||
|
||||
form = ReferenceRequestReviewForm(obj=request)
|
||||
|
||||
if form.validate_on_submit():
|
||||
form.populate_obj(request)
|
||||
|
||||
if request.review_status != EventReferenceRequestReviewStatus.rejected:
|
||||
request.rejection_reason = None
|
||||
|
||||
if request.rejection_reason == 0:
|
||||
request.rejection_reason = None
|
||||
|
||||
try:
|
||||
if request.review_status == EventReferenceRequestReviewStatus.verified:
|
||||
reference = create_event_reference_for_request(request)
|
||||
reference.rating = form.rating.data
|
||||
msg = gettext('Request successfully updated')
|
||||
else:
|
||||
msg = gettext('Reference successfully created')
|
||||
|
||||
db.session.commit()
|
||||
send_reference_request_review_status_mails(request)
|
||||
flash(msg, 'success')
|
||||
return redirect(url_for('manage_admin_unit_reference_requests_incoming', id=request.admin_unit_id))
|
||||
except SQLAlchemyError as e:
|
||||
db.session.rollback()
|
||||
flash(handleSqlError(e), 'danger')
|
||||
else:
|
||||
flash_errors(form)
|
||||
|
||||
dates = EventDate.query.with_parent(request.event).filter(EventDate.start >= today).order_by(EventDate.start).all()
|
||||
return render_template('reference_request/review.html',
|
||||
form=form,
|
||||
dates=dates,
|
||||
request=request,
|
||||
event=request.event)
|
||||
|
||||
@app.route('/reference_request/<int:id>/review_status')
|
||||
def event_reference_request_review_status(id):
|
||||
request = EventReferenceRequest.query.get_or_404(id)
|
||||
|
||||
if not has_access(request.admin_unit, 'reference_request:verify') and not has_access(request.event.admin_unit, 'reference_request:create'):
|
||||
abort(401)
|
||||
|
||||
return render_template('reference_request/review_status.html',
|
||||
reference_request=request,
|
||||
event=request.event)
|
||||
|
||||
def send_reference_request_review_status_mails(request):
|
||||
# Benachrichtige alle Mitglieder der AdminUnit, die diesen Request erstellt hatte
|
||||
members = AdminUnitMember.query.join(User).filter(AdminUnitMember.admin_unit_id == request.event.admin_unit_id).all()
|
||||
|
||||
for member in members:
|
||||
if has_admin_unit_member_permission(member, 'reference_request:create'):
|
||||
send_mail(member.user.email,
|
||||
gettext('Event review status updated'),
|
||||
'reference_request_review_status_notice',
|
||||
request=request)
|
||||
@ -67,4 +67,10 @@ def send_mails(recipients, subject, template, **context):
|
||||
msg.recipients = recipients
|
||||
msg.body = render_template("email/%s.txt" % template, **context)
|
||||
msg.html = render_template("email/%s.html" % template, **context)
|
||||
|
||||
if not mail.default_sender:
|
||||
print(msg.subject)
|
||||
print(msg.body)
|
||||
return
|
||||
|
||||
mail.send(msg)
|
||||
Loading…
x
Reference in New Issue
Block a user