[Plugin] schedule: Fixed models

This commit is contained in:
Ferdinand Thiessen 2020-11-01 19:31:51 +01:00
parent 63660743bd
commit b4234c43b8
2 changed files with 87 additions and 86 deletions

View File

@ -1,3 +1,7 @@
"""Schedule plugin
Provides duty schedule / duty roster functions
"""
from dateutil import parser from dateutil import parser
from datetime import datetime, timedelta from datetime import datetime, timedelta
from flask import Blueprint, request, jsonify from flask import Blueprint, request, jsonify
@ -7,8 +11,8 @@ from flaschengeist.database import db
from flaschengeist.plugins import Plugin from flaschengeist.plugins import Plugin
from flaschengeist.decorator import login_required from flaschengeist.decorator import login_required
from .models import EventKind
from . import event_controller, permissions from . import event_controller, permissions
from .models import EventType
schedule_bp = Blueprint("schedule", __name__, url_prefix="/schedule") schedule_bp = Blueprint("schedule", __name__, url_prefix="/schedule")
@ -21,32 +25,21 @@ class SchedulePlugin(Plugin):
) )
#################################################################################### @schedule_bp.route("/events/<int:event_id>", methods=["GET"])
# Routes #
# #
# /schedule/events POST: create new #
# GET: get all events this month #
# /schedule/events/<year>/<month> GET: get events by month / date #
# /<year>/<month>/<day> #
# /schedule/events/<id> GET: get event by ID #
# DELETE: delete specified event #
# PUT: modify specified event #
# /schedule/events/<id>/slots GET: get EventSlots of Event #
# POST: add new EventSlot to Event #
# /schedule/events/<id>/slots/<sid> PUT: modify EventSlot #
# GET: get specified EventSlot #
# /schedule/events/<id>/slots/<sid>/jobs POST: add User #
# /schedule/eventKinds
# /schedule/eventKinds/<id>
# PUT: modify user #
# DELETE: remove user #
####################################################################################
@schedule_bp.route("/events/<int:eid>", methods=["GET"])
@login_required() @login_required()
def __get_event(eid, **kwargs): def get_event(event_id, current_session):
event = event_controller.get_event(eid) """Get event by id
Route: ``/events/<event_id>`` | Method: ``GET``
Args:
event_id: ID identifying the event
current_session: Session sent with Authorization Header
Returns:
JSON encoded event object
"""
event = event_controller.get_event(event_id)
if not event: if not event:
raise NotFound raise NotFound
return jsonify(event) return jsonify(event)
@ -87,8 +80,8 @@ def __get_events(year=datetime.now().year, month=datetime.now().month, day=None,
raise BadRequest("Invalid date given") raise BadRequest("Invalid date given")
@schedule_bp.route("/eventKinds", methods=["POST"]) @schedule_bp.route("/event-types", methods=["POST"])
@login_required(permission=_permission_edit_type) @login_required(permission=permissions.EVENT_TYPE)
def __new_event_kind(**kwargs): def __new_event_kind(**kwargs):
data = request.get_json() data = request.get_json()
if "name" not in data: if "name" not in data:
@ -98,7 +91,7 @@ def __new_event_kind(**kwargs):
@schedule_bp.route("/slotKinds", methods=["POST"]) @schedule_bp.route("/slotKinds", methods=["POST"])
@login_required(permission=_permission_edit_type) @login_required(permission=permissions.EVENT_TYPE)
def __new_slot_kind(**kwargs): def __new_slot_kind(**kwargs):
data = request.get_json() data = request.get_json()
if not data or "name" not in data: if not data or "name" not in data:
@ -108,20 +101,20 @@ def __new_slot_kind(**kwargs):
@schedule_bp.route("/events", methods=["POST"]) @schedule_bp.route("/events", methods=["POST"])
@login_required(permission=_permission_create) @login_required(permission=permissions.CREATE)
def __new_event(**kwargs): def __new_event(**kwargs):
data = request.get_json() data = request.get_json()
event = event_controller.create_event( event = event_controller.create_event(
begin=parser.isoparse(data["begin"]), begin=parser.isoparse(data["begin"]),
end=parser.isoparse(data["end"]), end=parser.isoparse(data["end"]),
description=data["description"], description=data["description"],
kind=EventKind.query.get(data["kind"]), type=EventType.query.get(data["kind"]),
) )
return jsonify({"ok": "ok", "id": event.id}) return jsonify({"ok": "ok", "id": event.id})
@schedule_bp.route("/events/<int:event_id>", methods=["DELETE"]) @schedule_bp.route("/events/<int:event_id>", methods=["DELETE"])
@login_required(permission=_permission_delete) @login_required(permission=permissions.DELETE)
def __delete_event(event_id, **kwargs): def __delete_event(event_id, **kwargs):
if not event_controller.delete_event(event_id): if not event_controller.delete_event(event_id):
raise NotFound raise NotFound
@ -130,7 +123,7 @@ def __delete_event(event_id, **kwargs):
@schedule_bp.route("/eventKinds/<int:event_id>", methods=["PUT"]) @schedule_bp.route("/eventKinds/<int:event_id>", methods=["PUT"])
@login_required(permission=_permission_edit_type) @login_required(permission=permissions.EVENT_TYPE)
def __edit_event_kind(event_id, **kwargs): def __edit_event_kind(event_id, **kwargs):
data = request.get_json() data = request.get_json()
if not data or "name" not in data: if not data or "name" not in data:
@ -158,7 +151,7 @@ def __get_slot(event_id, slot_id, **kwargs):
@schedule_bp.route("/events/<int:event_id>/slots/<int:slot_id>", methods=["DELETE"]) @schedule_bp.route("/events/<int:event_id>/slots/<int:slot_id>", methods=["DELETE"])
@login_required(permission=_permission_delete) @login_required(permission=permissions.DELETE)
def __delete_slot(event_id, slot_id, **kwargs): def __delete_slot(event_id, slot_id, **kwargs):
if event_controller.delete_event_slot(slot_id, event_id): if event_controller.delete_event_slot(slot_id, event_id):
return jsonify({"ok": "ok"}) return jsonify({"ok": "ok"})
@ -166,7 +159,7 @@ def __delete_slot(event_id, slot_id, **kwargs):
@schedule_bp.route("/events/<int:event_id>/slots/<int:slot_id>", methods=["PUT"]) @schedule_bp.route("/events/<int:event_id>/slots/<int:slot_id>", methods=["PUT"])
@login_required(permission=_permission_edit) @login_required(permission=permissions.EDIT)
def __update_slot(event_id, slot_id, **kwargs): def __update_slot(event_id, slot_id, **kwargs):
data = request.get_json() data = request.get_json()
if not data: if not data:
@ -180,7 +173,7 @@ def __update_slot(event_id, slot_id, **kwargs):
@schedule_bp.route("/events/<int:event_id>/slots", methods=["POST"]) @schedule_bp.route("/events/<int:event_id>/slots", methods=["POST"])
@login_required(permission=_permission_edit) @login_required(permission=permissions.EDIT)
def __add_slot(event_id, **kwargs): def __add_slot(event_id, **kwargs):
event = event_controller.get_event(event_id) event = event_controller.get_event(event_id)
if not event: if not event:

View File

@ -5,74 +5,82 @@ from flaschengeist.models import ModelSerializeMixin
from flaschengeist.models.user import User from flaschengeist.models.user import User
from flaschengeist.database import db from flaschengeist.database import db
#########
class EventSlot(db.Model, ModelSerializeMixin): # Types #
"""Model for an EventSlot""" #########
__tablename__ = "event_slot"
id: int = db.Column(db.Integer, primary_key=True)
start: datetime = db.Column(db.DateTime)
end: Optional[datetime] = db.Column(db.DateTime)
slots: [any] = db.relationship("JobSlot", back_populates="_event_slot")
_event_id = db.Column("event_id", db.Integer, db.ForeignKey("event.id"), nullable=False)
_event = db.relationship("Event", back_populates="_slots")
class EventKind(db.Model, ModelSerializeMixin): class EventType(db.Model, ModelSerializeMixin):
"""Model for an EventKind""" __tablename__ = "event_type"
id_: int = db.Column("id", db.Integer, primary_key=True)
__tablename__ = "event_kind"
name: str = db.Column(db.String(30), nullable=False, unique=True) name: str = db.Column(db.String(30), nullable=False, unique=True)
_id: int = db.Column("id", db.Integer, primary_key=True)
class JobType(db.Model, ModelSerializeMixin):
__tablename__ = "job_type"
id_ = db.Column("id", db.Integer, primary_key=True)
name: str = db.Column(db.String(30), nullable=False, unique=True)
class Event(db.Model, ModelSerializeMixin): ########
"""Model for an Event""" # Jobs #
########
__tablename__ = "event"
id: int = db.Column(db.Integer, primary_key=True)
begin: datetime = db.Column(db.DateTime, nullable=False)
end: datetime = db.Column(db.DateTime)
description: str = db.Column(db.String(240))
kind: EventKind = db.relationship("EventKind")
# notices = db.relationship("EventNotice", back_populates="event")
_kind_id = db.Column("kind_id", db.Integer, db.ForeignKey("event_kind.id", ondelete="CASCADE"), nullable=False)
_slots: [EventSlot] = db.relationship("EventSlot", back_populates="_event", cascade="all, delete")
class Job(db.Model, ModelSerializeMixin): class Job(db.Model, ModelSerializeMixin):
__tablename__ = "job" __tablename__ = "job"
userid: str = None userid: str = None
value: float = db.Column(db.Numeric(precision=3, scale=2)) value: float = db.Column(db.Numeric(precision=3, scale=2), nullable=False)
_id = db.Column("id", db.Integer, primary_key=True) id_ = db.Column("id", db.Integer, primary_key=True)
_user_id = db.Column("user_id", db.Integer, db.ForeignKey("user.id")) _user_id = db.Column("user_id", db.Integer, db.ForeignKey("user.id"), nullable=False)
_user: User = db.relationship("User") _slot_id = db.Column("slot_id", db.Integer, db.ForeignKey("job_slot.id"), nullable=False)
_slot_id = db.Column("slot_id", db.Integer, db.ForeignKey("job_slot.id"))
_slot = db.relationship("JobSlot") user_: User = db.relationship("User")
slot_ = db.relationship("JobSlot")
@property @property
def userid(self): def userid(self):
return self._user.userid return self._user.userid
class JobKind(db.Model, ModelSerializeMixin):
__tablename__ = "job_kind"
name: str = db.Column(db.String(30), nullable=False, unique=True)
_id = db.Column("id", db.Integer, primary_key=True)
class JobSlot(db.Model, ModelSerializeMixin): class JobSlot(db.Model, ModelSerializeMixin):
__tablename__ = "job_slot" __tablename__ = "job_slot"
id: int = db.Column(db.Integer, primary_key=True)
needed_persons: float = db.Column(db.Numeric(precision=4, scale=2))
kind: JobKind = db.relationship("JobKind")
jobs: [Job] = db.relationship("Job", back_populates="_slot")
_event_slot_id = db.Column("event_slot_id", db.Integer, db.ForeignKey("event_slot.id"))
_event_slot = db.relationship("EventSlot", back_populates="slots")
_kind_id = db.Column("kind_id", db.Integer, db.ForeignKey("job_kind.id")) _kind_id = db.Column("kind_id", db.Integer, db.ForeignKey("job_kind.id"))
_event_slot_id = db.Column("event_slot_id", db.Integer, db.ForeignKey("event_slot.id"))
id: int = db.Column(db.Integer, primary_key=True)
type: JobType = db.relationship("JobKind")
users: [Job] = db.relationship("Job", back_populates="_slot")
required_jobs: float = db.Column(db.Numeric(precision=4, scale=2))
event_slot_ = db.relationship("EventSlot", back_populates="slots")
##########
# Events #
##########
class EventSlot(db.Model, ModelSerializeMixin):
"""Model for an EventSlot"""
__tablename__ = "event_slot"
_event_id = db.Column("event_id", db.Integer, db.ForeignKey("event.id"), nullable=False)
id: int = db.Column(db.Integer, primary_key=True)
start: datetime = db.Column(db.DateTime)
end: Optional[datetime] = db.Column(db.DateTime)
jobs: [JobSlot] = db.relationship("JobSlot", back_populates="_event_slot")
event_ = db.relationship("Event", back_populates="_slots")
class Event(db.Model, ModelSerializeMixin):
"""Model for an Event"""
__tablename__ = "event"
_kind_id = db.Column("kind_id", db.Integer, db.ForeignKey("event_kind.id", ondelete="CASCADE"), nullable=False)
id: int = db.Column(db.Integer, primary_key=True)
begin: datetime = db.Column(db.DateTime, nullable=False)
end: datetime = db.Column(db.DateTime)
description: str = db.Column(db.String(240))
type: EventType = db.relationship("EventKind")
slots: [EventSlot] = db.relationship("EventSlot", back_populates="_event", cascade="all, delete")