[Plugin] schedule: Fixed models
This commit is contained in:
parent
63660743bd
commit
b4234c43b8
|
@ -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:
|
||||||
|
|
|
@ -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")
|
||||||
|
|
Loading…
Reference in New Issue