Files
Assemblr-Backend/routes/sipro.py

170 lines
5.8 KiB
Python

import datetime
from enum import StrEnum
from flask import Blueprint, request, jsonify
from sqlalchemy import func, cast, String, Numeric, Float
import auxiliary
import database
import database.enums
sipro_blueprint = Blueprint('sipro', __name__)
class ExpandParam(StrEnum):
USER = 'user'
@sipro_blueprint.before_request
def auth():
API_KEY = '5D809ED08080B5F204443B31374BD6A5'
if request.headers.get('Authorization') != API_KEY:
return {'error': 'Unauthorized'}, 401
@sipro_blueprint.post('/assemblyInfo')
def assembly_info():
params: dict = request.json
expand_param = params.get('expand')
order_ids = params.get('orderIds')
expand_list = expand_param if expand_param else []
datetime_format = 'YYYY.MM.DD, HH24:MI'
entity_list = [
database.Assembly.id.label('id'),
database.Assembly.order_id.label('order_id'),
func.to_char(database.Assembly.created_at, datetime_format).label('created_at'),
func.to_char(database.Assembly.ended_at, datetime_format).label('ended_at'),
database.Assembly.is_active.label('is_active'),
database.Assembly.state.label('state')
]
query = database.Assembly.query
for expand in expand_list:
match expand:
case ExpandParam.USER:
query = query.join(database.User)
entity_list.extend([
database.User.id.label('user.id'),
database.User.login.label('user.login'),
])
if order_ids:
query = query.filter(database.Assembly.order_id.in_(order_ids))
query = query.with_entities(*entity_list)
result = query.all()
json_result = [auxiliary.to_nested_dict(row) for row in result]
return json_result
@sipro_blueprint.post('/tableAssemblyStats')
def table_assembly_stats():
filters = request.json
date_from = filters.get('from')
date_to = filters.get('to')
dated_query = (
database.Assembly.query
.join(database.User)
.filter(
database.User.is_admin == False
)
.group_by(database.User.login, database.Assembly.user_id)
.with_entities(
database.User.login.label('user_login'),
func.count(database.Assembly.user_id).label('assembled'),
func.string_agg(func.cast(database.Assembly.order_id, database.db.String), ',').label('order_ids')
)
)
if len(date_from) > 0 and len(date_to) > 0:
dated_query = dated_query.filter(
database.Assembly.ended_at >= date_from,
database.Assembly.ended_at <= date_to
)
json_result = []
for row in dated_query.all():
json_result.append({
'user_login': row.user_login,
'assembled': row.assembled,
'order_ids': row.order_ids
})
return jsonify(json_result)
@sipro_blueprint.get('/dailyAssemblyData')
def daily_assembly_stats():
query = (
database.Assembly.query
.join(database.User)
.filter(
database.Assembly.ended_at >= func.current_date()
)
.group_by(database.User.login, database.Assembly.user_id)
.with_entities(
database.User.login.label('user_login'),
func.count(database.Assembly.user_id).label('assembled'),
func.string_agg(func.cast(database.Assembly.order_id, database.db.String), ',').label('order_ids')
)
)
json_result = []
for row in query.all():
json_result.append({
'user_login': row.user_login,
'assembled': row.assembled,
'order_ids': row.order_ids
})
return json_result
@sipro_blueprint.get('/users')
def get_users():
query = (database.User.query.
with_entities(database.User.id,
database.User.login)
.all())
response = [{'id': user.id, 'login': user.login} for user in query]
return jsonify(response)
@sipro_blueprint.get('/statistics')
def get_users_statistics():
data: dict = request.args
user_id = int(data['userId'])
date_from = datetime.datetime.fromisoformat(data['dateFrom'])
date_to = datetime.datetime.fromisoformat(data['dateTo']) + datetime.timedelta(hours=24, minutes=59, seconds=59)
query = (database.BalanceTransaction.query
.filter(database.BalanceTransaction.user_id == user_id,
database.BalanceTransaction.created_at.between(date_from, date_to))
.order_by(func.date_trunc('day', database.BalanceTransaction.created_at))
.group_by(func.date_trunc('day', database.BalanceTransaction.created_at))
.with_entities(func.date_trunc('day', database.BalanceTransaction.created_at).label('date'),
func.cast(func.round(func.cast(func.sum(database.BalanceTransaction.amount), Numeric), 2),
Float).label(
'value'),
func.string_agg(cast(database.BalanceTransaction.json_data['order_id'], String), ',').label(
'order_ids'))
.all())
result = [{'date': row.date.isoformat(), 'value': row.value, 'order_ids': row.order_ids} for row in query]
return jsonify(result)
@sipro_blueprint.get('/get-orders-by-date')
def get_orders_by_date():
data: dict = request.args
date = datetime.date.fromisoformat(data['date'])
query = (
database.Assembly.query
.filter(
func.date_trunc('day', database.Assembly.ended_at) == func.date_trunc('day', date),
)
.with_entities(
func.string_agg(func.cast(database.Assembly.order_id, database.db.String), ',').label('order_ids')
)
.scalar()
)
if not query:
return jsonify({'order_ids': []})
return jsonify({'order_ids': list(map(int, query.split(',')))})