Commit 3b3ae5eb authored by Robin Sonnabend's avatar Robin Sonnabend
Browse files

Implemented reminders, although they don't get send yet.

parent 29f92eef
"""empty message
Revision ID: 162da8aeeb71
Revises: a3d9d1b87ba0
Create Date: 2017-02-22 16:52:08.142214
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = '162da8aeeb71'
down_revision = 'a3d9d1b87ba0'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('meetingreminders', sa.Column('days_before', sa.Integer(), nullable=True))
op.drop_column('meetingreminders', 'time_before')
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('meetingreminders', sa.Column('time_before', postgresql.INTERVAL(), autoincrement=False, nullable=True))
op.drop_column('meetingreminders', 'days_before')
# ### end Alembic commands ###
......@@ -25,7 +25,7 @@ class ProtocolType(db.Model):
protocols = relationship("Protocol", backref=backref("protocoltype"), cascade="all, delete-orphan", order_by="Protocol.id")
default_tops = relationship("DefaultTOP", backref=backref("protocoltype"), cascade="all, delete-orphan", order_by="DefaultTOP.number")
reminders = relationship("MeetingReminder", backref=backref("protocoltype"), cascade="all, delete-orphan", order_by="MeetingReminder.time_before")
reminders = relationship("MeetingReminder", backref=backref("protocoltype"), cascade="all, delete-orphan", order_by="MeetingReminder.days_before")
def __init__(self, name, short_name, organization,
is_public, private_group, public_group, private_mail, public_mail):
......@@ -207,19 +207,19 @@ class MeetingReminder(db.Model):
__tablename__ = "meetingreminders"
id = db.Column(db.Integer, primary_key=True)
protocoltype_id = db.Column(db.Integer, db.ForeignKey("protocoltypes.id"))
time_before = db.Column(db.Interval)
days_before = db.Column(db.Integer)
send_public = db.Column(db.Boolean)
send_private = db.Column(db.Boolean)
def __init__(self, protocoltype_id, time_before, send_public, send_private):
def __init__(self, protocoltype_id, days_before, send_public, send_private):
self.protocoltype_id = protocoltype_id
self.time_before = time_before
self.days_before = days_before
self.send_public = send_public
self.send_private = send_private
def __repr__(self):
return "<MeetingReminder(id={}, protocoltype_id={}, time_before={}, send_public={}, send_private={})>".format(
self.id, self.protocoltype_id, self.time_before, self.send_public, self.send_private)
return "<MeetingReminder(id={}, protocoltype_id={}, days_before={}, send_public={}, send_private={})>".format(
self.id, self.protocoltype_id, self.days_before, self.send_public, self.send_private)
class Error(db.Model):
__tablename__ = "errors"
......
......@@ -13,8 +13,8 @@ import config
from shared import db, date_filter, datetime_filter, ldap_manager, security_manager
from utils import is_past, mail_manager, url_manager
from models.database import ProtocolType, Protocol, DefaultTOP, TOP, Document, Todo, Decision, MeetingReminder, Error
from views.forms import LoginForm, ProtocolTypeForm, DefaultTopForm
from views.tables import ProtocolsTable, ProtocolTypesTable, ProtocolTypeTable, DefaultTOPsTable
from views.forms import LoginForm, ProtocolTypeForm, DefaultTopForm, MeetingReminderForm
from views.tables import ProtocolsTable, ProtocolTypesTable, ProtocolTypeTable, DefaultTOPsTable, MeetingRemindersTable
app = Flask(__name__)
app.config.from_object(config)
......@@ -147,7 +147,69 @@ def show_type(type_id):
return redirect(request.args.get("next") or url_for("index"))
protocoltype_table = ProtocolTypeTable(protocoltype)
default_tops_table = DefaultTOPsTable(protocoltype.default_tops, protocoltype)
return render_template("type-show.html", protocoltype=protocoltype, protocoltype_table=protocoltype_table, default_tops_table=default_tops_table)
reminders_table = MeetingRemindersTable(protocoltype.reminders, protocoltype)
return render_template("type-show.html", protocoltype=protocoltype, protocoltype_table=protocoltype_table, default_tops_table=default_tops_table, reminders_table=reminders_table)
@app.route("/type/reminders/new/<int:type_id>", methods=["GET", "POST"])
@login_required
def new_reminder(type_id):
protocoltype = ProtocolType.query.filter_by(id=type_id).first()
if protocoltype is None:
flash("Dieser Protokolltyp existiert nicht.", "alert-error")
return redirect(request.args.get("next") or url_for("index"))
user = current_user()
if not protocoltype.has_modify_right(user):
flash("Dir fehlen die nötigen Zugriffsrechte.", "alert-error")
return redirect(request.args.get("next") or url_for("index"))
form = MeetingReminderForm()
if form.validate_on_submit():
reminder = MeetingReminder(protocoltype.id, form.days_before.data, form.send_public.data, form.send_private.data)
db.session.add(reminder)
db.session.commit()
return redirect(request.args.get("next") or url_for("show_type", type_id=protocoltype.id))
return render_template("reminder-new.html", form=form, protocoltype=protocoltype)
@app.route("/type/reminder/edit/<int:type_id>/<int:reminder_id>", methods=["GET", "POST"])
@login_required
def edit_reminder(type_id, reminder_id):
protocoltype = ProtocolType.query.filter_by(id=type_id).first()
if protocoltype is None:
flash("Dieser Protokolltyp existiert nicht.", "alert-error")
return redirect(request.args.get("next") or url_for("index"))
user = current_user()
if not protocoltype.has_modify_right(user):
flash("Dir fehlen die nötigen Zugriffsrechte.", "alert-error")
return redirect(request.args.get("next") or url_for("index"))
reminder = MeetingReminder.query.filter_by(id=reminder_id).first()
if reminder is None or reminder.protocoltype != protocoltype:
flash("Invalide Erinnerung.", "alert-error")
return redirect(request.args.get("next") or url_for("index"))
form = MeetingReminderForm(obj=reminder)
if form.validate_on_submit():
form.populate_obj(reminder)
db.session.commit()
return redirect(request.args.get("next") or url_for("show_type", type_id=protocoltype.id))
return render_template("reminder-edit.html", form=form, protocoltype=protocoltype, reminder=reminder)
@app.route("/type/reminder/delete/<int:type_id>/<int:reminder_id>")
@login_required
def delete_reminder(type_id, reminder_id):
protocoltype = ProtocolType.query.filter_by(id=type_id).first()
if protocoltype is None:
flash("Dieser Protokolltyp existiert nicht.", "alert-error")
return redirect(request.args.get("next") or url_for("index"))
user = current_user()
if not protocoltype.has_modify_right(user):
flash("Dir fehlen die nötigen Zugriffsrechte.", "alert-error")
return redirect(request.args.get("next") or url_for("index"))
reminder = MeetingReminder.query.filter_by(id=reminder_id).first()
if reminder is None or reminder.protocoltype != protocoltype:
flash("Invalide Erinnerung.", "alert-error")
return redirect(request.args.get("next") or url_for("index"))
db.session.delete(reminder)
db.session.commit()
return redirect(request.args.get("next") or url_for("show_type", type_id=protocoltype.id))
@app.route("/type/tops/new/<int:type_id>", methods=["GET", "POST"])
@login_required
......@@ -183,7 +245,7 @@ def edit_default_top(type_id, top_id):
default_top = DefaultTOP.query.filter_by(id=top_id).first()
if default_top is None or default_top.protocoltype != protocoltype:
flash("Invalider Standard-TOP.", "alert-error")
return redirect(request.args.get("nexT") or url_for("index"))
return redirect(request.args.get("next") or url_for("index"))
form = DefaultTopForm(obj=default_top)
if form.validate_on_submit():
form.populate_obj(default_top)
......
{% extends "layout.html" %}
{% from "macros.html" import render_form %}
{% block title %}Einladung ändern{% endblock %}
{% block content %}
<div class="container">
{{render_form(form, action_url=url_for("edit_reminder", type_id=protocoltype.id, reminder_id=reminder.id, next=url_for("show_type", type_id=protocoltype.id)), action_text="Ändern")}}
</div>
{% endblock %}
{% extends "layout.html" %}
{% from "macros.html" import render_form %}
{% block title %}Einladung hinzufügen{% endblock %}
{% block content %}
<div class="container">
{{render_form(form, action_url=url_for("new_reminder", type_id=protocoltype.id, next=url_for("show_type", type_id=protocoltype.id)), action_text="Anlegen")}}
</div>
{% endblock %}
......@@ -7,5 +7,6 @@
{{render_single_table(protocoltype_table)}}
{{render_table(default_tops_table)}}
Standard-TOPs mit negativer Sortierung werden vor und die mit positiver Sortierung nach den TOPs eingefügt.
{{render_table(reminders_table)}}
</div>
{% endblock %}
......@@ -19,3 +19,8 @@ class ProtocolTypeForm(FlaskForm):
class DefaultTopForm(FlaskForm):
name = StringField("Name", validators=[InputRequired("Du musst einen Namen angeben.")])
number = IntegerField("Nummer", validators=[InputRequired("Du musst eine Nummer angeben.")])
class MeetingReminderForm(FlaskForm):
days_before = IntegerField("Tage vor Sitzung", validators=[InputRequired("Du musst eine Dauer angeben.")])
send_public = BooleanField("Öffentlich einladen")
send_private = BooleanField("Intern einladen")
......@@ -116,3 +116,29 @@ class DefaultTOPsTable(Table):
Table.link(url_for("delete_default_top", type_id=self.protocoltype.id, top_id=top.id), "Löschen", confirm="Bist du dir sicher, dass du den Standard-TOP {} löschen willst?".format(top.name))
])
]
class MeetingRemindersTable(Table):
def __init__(self, reminders, protocoltype=None):
super().__init__("Einladungsmails", reminders, newlink=url_for("new_reminder", type_id=protocoltype.id) if protocoltype is not None else None)
self.protocoltype = protocoltype
def headers(self):
return ["Zeit", "Einladen", ""]
def row(self, reminder):
return [
"{} Tage".format(reminder.days_before),
self.get_send_summary(reminder),
Table.concat([
Table.link(url_for("edit_reminder", type_id=self.protocoltype.id, reminder_id=reminder.id), "Ändern"),
Table.link(url_for("delete_reminder", type_id=self.protocoltype.id, reminder_id=reminder.id), "Löschen", confirm="Bist du dir sicher, dass du die Einladungsmail {} Tage vor der Sitzung löschen willst?".format(reminder.days_before))
])
]
def get_send_summary(self, reminder):
parts = []
if reminder.send_public:
parts.append("Öffentlich")
if reminder.send_private:
parts.append("Intern")
return " und ".join(parts)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment