Merge pull request #193 from ZeusWPI/feature/association-management

Integrate associations
This commit is contained in:
Charlotte Van Petegem 2022-05-30 18:29:05 +02:00 committed by GitHub
commit 28a6dc5422
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 68 additions and 10 deletions

View file

@ -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)

View file

@ -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

View file

@ -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)

View file

@ -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 ###

View file

@ -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

View file

@ -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")

View file

@ -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:

View file

@ -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') }}

View file

@ -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
) )

View file

@ -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():

View file

@ -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