Merge pull request #193 from ZeusWPI/feature/association-management
Integrate associations
This commit is contained in:
commit
28a6dc5422
11 changed files with 68 additions and 10 deletions
|
@ -10,5 +10,5 @@ def add() -> None:
|
||||||
"""Add users as admin."""
|
"""Add users as admin."""
|
||||||
for username in Configuration.HALDIS_ADMINS:
|
for username in Configuration.HALDIS_ADMINS:
|
||||||
user = User()
|
user = User()
|
||||||
user.configure(username, True, 0)
|
user.configure(username, True, 0, associations=["zeus"])
|
||||||
db.session.add(user)
|
db.session.add(user)
|
||||||
|
|
|
@ -28,11 +28,12 @@ class OrderAdminModel(ModelBaseView):
|
||||||
"Class for the model of a OrderAdmin"
|
"Class for the model of a OrderAdmin"
|
||||||
# pylint: disable=too-few-public-methods
|
# pylint: disable=too-few-public-methods
|
||||||
column_default_sort = ("starttime", True)
|
column_default_sort = ("starttime", True)
|
||||||
column_list = ["starttime", "stoptime", "location_name", "location_id", "courier"]
|
column_list = ["starttime", "stoptime", "location_name", "location_id", "courier", "association"]
|
||||||
column_labels = {
|
column_labels = {
|
||||||
"starttime": "Start Time",
|
"starttime": "Start Time",
|
||||||
"stoptime": "Closing Time",
|
"stoptime": "Closing Time",
|
||||||
"location_id": "HLDS Location ID",
|
"location_id": "HLDS Location ID",
|
||||||
|
"association": "Association",
|
||||||
}
|
}
|
||||||
form_excluded_columns = ["items", "courier_id"]
|
form_excluded_columns = ["items", "courier_id"]
|
||||||
can_delete = False
|
can_delete = False
|
||||||
|
|
|
@ -24,6 +24,7 @@ class OrderForm(Form):
|
||||||
"Starttime", default=datetime.now, format="%d-%m-%Y %H:%M"
|
"Starttime", default=datetime.now, format="%d-%m-%Y %H:%M"
|
||||||
)
|
)
|
||||||
stoptime = DateTimeField("Stoptime", format="%d-%m-%Y %H:%M")
|
stoptime = DateTimeField("Stoptime", format="%d-%m-%Y %H:%M")
|
||||||
|
association = SelectField("Association", coerce=str, validators=[validators.required()])
|
||||||
submit_button = SubmitField("Submit")
|
submit_button = SubmitField("Submit")
|
||||||
|
|
||||||
def populate(self) -> None:
|
def populate(self) -> None:
|
||||||
|
@ -38,6 +39,7 @@ class OrderForm(Form):
|
||||||
(current_user.id, current_user.username),
|
(current_user.id, current_user.username),
|
||||||
]
|
]
|
||||||
self.location_id.choices = [(l.id, l.name) for l in location_definitions]
|
self.location_id.choices = [(l.id, l.name) for l in location_definitions]
|
||||||
|
self.association.choices = current_user.association_list()
|
||||||
if self.stoptime.data is None:
|
if self.stoptime.data is None:
|
||||||
self.stoptime.data = datetime.now() + timedelta(hours=1)
|
self.stoptime.data = datetime.now() + timedelta(hours=1)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
"""Add user associations
|
||||||
|
|
||||||
|
Revision ID: f6a6004bf4b9
|
||||||
|
Revises: 55013fe95bea
|
||||||
|
Create Date: 2022-05-24 21:23:27.770365
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = 'f6a6004bf4b9'
|
||||||
|
down_revision = '55013fe95bea'
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.add_column('order', sa.Column('association', sa.String(length=120), server_default='', nullable=False))
|
||||||
|
op.add_column('user', sa.Column('associations', sa.String(), server_default='', nullable=False))
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_column('user', 'associations')
|
||||||
|
op.drop_column('order', 'association')
|
||||||
|
# ### end Alembic commands ###
|
|
@ -1,10 +1,14 @@
|
||||||
"AnonymouseUser for people who are not logged in the normal way"
|
"AnonymouseUser for people who are not logged in the normal way"
|
||||||
|
from typing import List
|
||||||
# pylint: disable=R0201,C0111
|
# pylint: disable=R0201,C0111
|
||||||
|
|
||||||
|
|
||||||
class AnonymouseUser:
|
class AnonymouseUser:
|
||||||
id = None
|
id = None
|
||||||
|
|
||||||
|
def association_list(self) -> List[str]:
|
||||||
|
return []
|
||||||
|
|
||||||
def is_active(self) -> bool:
|
def is_active(self) -> bool:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ class Order(db.Model):
|
||||||
stoptime = db.Column(db.DateTime)
|
stoptime = db.Column(db.DateTime)
|
||||||
public = db.Column(db.Boolean, default=True)
|
public = db.Column(db.Boolean, default=True)
|
||||||
slug = db.Column(db.String(7), default=generate_slug, unique=True)
|
slug = db.Column(db.String(7), default=generate_slug, unique=True)
|
||||||
|
association = db.Column(db.String(120), nullable=False, server_default="")
|
||||||
|
|
||||||
items = db.relationship("OrderItem", backref="order", lazy="dynamic")
|
items = db.relationship("OrderItem", backref="order", lazy="dynamic")
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
"Script for everything User related in the database"
|
"Script for everything User related in the database"
|
||||||
|
from typing import List, Optional
|
||||||
|
|
||||||
from models import db
|
from models import db
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,6 +10,10 @@ class User(db.Model):
|
||||||
username = db.Column(db.String(80), unique=True, nullable=False)
|
username = db.Column(db.String(80), unique=True, nullable=False)
|
||||||
admin = db.Column(db.Boolean)
|
admin = db.Column(db.Boolean)
|
||||||
bias = db.Column(db.Integer)
|
bias = db.Column(db.Integer)
|
||||||
|
# Assocation logic
|
||||||
|
associations = db.Column(db.String(), nullable=False, server_default="")
|
||||||
|
|
||||||
|
# Relations
|
||||||
runs = db.relation(
|
runs = db.relation(
|
||||||
"Order",
|
"Order",
|
||||||
backref="courier",
|
backref="courier",
|
||||||
|
@ -16,11 +22,17 @@ class User(db.Model):
|
||||||
)
|
)
|
||||||
orderItems = db.relationship("OrderItem", backref="user", lazy="dynamic")
|
orderItems = db.relationship("OrderItem", backref="user", lazy="dynamic")
|
||||||
|
|
||||||
def configure(self, username: str, admin: bool, bias: int) -> None:
|
def association_list(self) -> List[str]:
|
||||||
"Configure the User"
|
return self.associations.split(",")
|
||||||
|
|
||||||
|
def configure(self, username: str, admin: bool, bias: int, associations: Optional[List[str]] = None) -> None:
|
||||||
|
"""Configure the User"""
|
||||||
|
if associations is None:
|
||||||
|
associations = []
|
||||||
self.username = username
|
self.username = username
|
||||||
self.admin = admin
|
self.admin = admin
|
||||||
self.bias = bias
|
self.bias = bias
|
||||||
|
self.associations = ",".join(associations)
|
||||||
|
|
||||||
# pylint: disable=C0111, R0201
|
# pylint: disable=C0111, R0201
|
||||||
def is_authenticated(self) -> bool:
|
def is_authenticated(self) -> bool:
|
||||||
|
|
|
@ -38,6 +38,11 @@
|
||||||
{{ form.location_id(class='form-control select') }}
|
{{ form.location_id(class='form-control select') }}
|
||||||
{{ util.render_form_field_errors(form.location_id) }}
|
{{ util.render_form_field_errors(form.location_id) }}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group select2 {{ 'has-errors' if form.association.errors else ''}}{{ ' required' if form.association.flags.required }}">
|
||||||
|
{{ form.association.label(class='control-label') }}
|
||||||
|
{{ form.association(class='form-control select') }}
|
||||||
|
{{ util.render_form_field_errors(form.association) }}
|
||||||
|
</div>
|
||||||
{% if current_user.is_admin() %}
|
{% if current_user.is_admin() %}
|
||||||
<div class="form-group{{ ' has-error' if form.starttime.errors }}{{ ' required' if form.starttime.flags.required }}{{ ' hidden' if not current_user.is_admin() }}">
|
<div class="form-group{{ ' has-error' if form.starttime.errors }}{{ ' required' if form.starttime.flags.required }}{{ ' hidden' if not current_user.is_admin() }}">
|
||||||
{{ form.starttime.label(class='control-label') }}
|
{{ form.starttime.label(class='control-label') }}
|
||||||
|
|
|
@ -9,7 +9,7 @@ from flask import Blueprint, Flask, abort
|
||||||
from flask import current_app as app
|
from flask import current_app as app
|
||||||
from flask import (jsonify, make_response, render_template, request,
|
from flask import (jsonify, make_response, render_template, request,
|
||||||
send_from_directory, url_for)
|
send_from_directory, url_for)
|
||||||
from flask_login import login_required
|
from flask_login import current_user, login_required
|
||||||
from hlds.definitions import location_definitions
|
from hlds.definitions import location_definitions
|
||||||
from hlds.models import Location
|
from hlds.models import Location
|
||||||
from models import Order
|
from models import Order
|
||||||
|
@ -31,10 +31,12 @@ def home() -> str:
|
||||||
"Generate the home view"
|
"Generate the home view"
|
||||||
prev_day = datetime.now() - timedelta(days=1)
|
prev_day = datetime.now() - timedelta(days=1)
|
||||||
recently_closed = get_orders(
|
recently_closed = get_orders(
|
||||||
(Order.stoptime > prev_day) & (Order.stoptime < datetime.now())
|
(Order.stoptime > prev_day) & (Order.stoptime < datetime.now()) & Order.association.in_(current_user.association_list())
|
||||||
)
|
)
|
||||||
return render_template(
|
return render_template(
|
||||||
"home.html", orders=get_orders(), recently_closed=recently_closed
|
"home.html", orders=get_orders(
|
||||||
|
((datetime.now() > Order.starttime) & (Order.stoptime > datetime.now()) | (Order.stoptime == None)) & Order.association.in_(current_user.association_list())
|
||||||
|
), recently_closed=recently_closed
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,19 +21,22 @@ order_bp = Blueprint("order_bp", "order")
|
||||||
@order_bp.route("/")
|
@order_bp.route("/")
|
||||||
def orders(form: OrderForm = None) -> str:
|
def orders(form: OrderForm = None) -> str:
|
||||||
"""Generate general order view"""
|
"""Generate general order view"""
|
||||||
if form is None and not current_user.is_anonymous():
|
if form is None and current_user.association_list():
|
||||||
form = OrderForm()
|
form = OrderForm()
|
||||||
location_id = request.args.get("location_id")
|
location_id = request.args.get("location_id")
|
||||||
form.location_id.default = location_id
|
form.location_id.default = location_id
|
||||||
form.process()
|
form.process()
|
||||||
form.populate()
|
form.populate()
|
||||||
return render_template("orders.html", orders=get_orders(), form=form)
|
return render_template("orders.html", orders=get_orders(expression=Order.association.in_(current_user.association_list())), form=form)
|
||||||
|
|
||||||
|
|
||||||
@order_bp.route("/create", methods=["POST"])
|
@order_bp.route("/create", methods=["POST"])
|
||||||
@login_required
|
@login_required
|
||||||
def order_create() -> typing.Union[str, Response]:
|
def order_create() -> typing.Union[str, Response]:
|
||||||
"""Generate order create view"""
|
"""Generate order create view"""
|
||||||
|
if not current_user.association_list():
|
||||||
|
flash("Not allowed to create an order.", "info")
|
||||||
|
abort(401)
|
||||||
orderForm = OrderForm()
|
orderForm = OrderForm()
|
||||||
orderForm.populate()
|
orderForm.populate()
|
||||||
if orderForm.validate_on_submit():
|
if orderForm.validate_on_submit():
|
||||||
|
|
|
@ -77,7 +77,7 @@ def login_and_redirect_user(user) -> Response:
|
||||||
def create_user(username) -> User:
|
def create_user(username) -> User:
|
||||||
"Create a temporary user if it is needed"
|
"Create a temporary user if it is needed"
|
||||||
user = User()
|
user = User()
|
||||||
user.configure(username, False, 1)
|
user.configure(username, False, 1, associations=["zeus"])
|
||||||
db.session.add(user)
|
db.session.add(user)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return user
|
return user
|
||||||
|
|
Loading…
Reference in a new issue