170 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			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(',')))})
 |