This commit is contained in:
Vassili Minaev 2025-03-20 03:10:43 -06:00
parent a0c4eed5bf
commit dc556c60a9
5 changed files with 67 additions and 64 deletions

View file

@ -15,13 +15,6 @@ def datetime_format(postdata):
return formatted
def init_app(app):
async def db_query(query, params=()):
await app['dcur'].execute(query, params)
q = app['dcur'].mogrify(query, params)
r = await app['dcur'].fetchall()
result = [{k: (str(v) if isinstance(v, datetime.date) or isinstance(v, datetime.timedelta) else v) for k, v in row.items()} for row in r]
return (q, result)
routes = web.RouteTableDef()
@routes.get('')
@ -45,40 +38,44 @@ def init_app(app):
await aiohttp_security.check_permission(request, 'user')
querystring = "SELECT * FROM events WHERE deleted=false AND %s BETWEEN datefrom AND dateto;"
if request.match_info['day']:
query, response = await db_query(querystring, (request.match_info['day'],))
response = await request.config_dict["query"](querystring, (request.match_info['day'],))
else:
query, response = await db_query(querystring.replace("%s", "CURDATE()"))
return web.json_response(response)
response = await request.config_dict["query"](querystring.replace("%s", "CURDATE()"))
formatted = [[(str(v) if isinstance(v, datetime.date) or isinstance(v, datetime.timedelta) else v) for v in row] for row in response]
return web.json_response(formatted)
@routes.get('/events/month/{month}')
async def get_events_monthly(request):
await aiohttp_security.check_permission(request, 'user')
querystring = "SELECT * FROM events WHERE deleted=false AND %s BETWEEN DATE_FORMAT(datefrom, '%%Y-%%m') AND DATE_FORMAT(dateto, '%%Y-%%m');"
if request.match_info['month']:
query, response = await db_query(querystring, (request.match_info['month'],))
response = await request.config_dict["query"](querystring, (request.match_info['month'],))
else:
query, response = await db_query(querystring.replace("%s", "DATE_FORMAT(CURDATE(), '%%Y-%%m')"))
return web.json_response(response)
response = await request.config_dict["query"](querystring.replace("%s", "DATE_FORMAT(CURDATE(), '%%Y-%%m')"))
formatted = [[(str(v) if isinstance(v, datetime.date) or isinstance(v, datetime.timedelta) else v) for v in row] for row in response]
return web.json_response(formatted)
@routes.get('/admin/day/{day}')
async def get_events_daily(request):
await aiohttp_security.check_permission(request, 'admin')
querystring = "SELECT * FROM events WHERE %s BETWEEN datefrom AND dateto;"
if request.match_info['day']:
query, response = await db_query(querystring, (request.match_info['day'],))
response = await request.config_dict["query"](querystring, (request.match_info['day'],))
else:
query, response = await db_query(querystring.replace("%s", "CURDATE()"))
return web.json_response(response)
response = await request.config_dict["query"](querystring.replace("%s", "CURDATE()"))
formatted = [[(str(v) if isinstance(v, datetime.date) or isinstance(v, datetime.timedelta) else v) for v in row] for row in response]
return web.json_response(formatted)
@routes.get('/admin/month/{month}')
async def get_events_monthly(request):
await aiohttp_security.check_permission(request, 'admin')
querystring = "SELECT * FROM events WHERE %s BETWEEN DATE_FORMAT(datefrom, '%%Y-%%m') AND DATE_FORMAT(dateto, '%%Y-%%m');"
if request.match_info['month']:
query, response = await db_query(querystring, (request.match_info['month'],))
response = await request.config_dict["query"](querystring, (request.match_info['month'],))
else:
query, response = await db_query(querystring.replace("%s", "DATE_FORMAT(CURDATE(), '%%Y-%%m')"))
return web.json_response(response)
response = await request.config_dict["query"](querystring.replace("%s", "DATE_FORMAT(CURDATE(), '%%Y-%%m')"))
formatted = [[(str(v) if isinstance(v, datetime.date) or isinstance(v, datetime.timedelta) else v) for v in row] for row in response]
return web.json_response(formatted)
@routes.post('/event/add')
async def event_add(request):
@ -87,9 +84,9 @@ def init_app(app):
formatted = datetime_format(postdata)
querystring = "INSERT INTO events(name, message, timefrom, timeto, timetbd, datefrom, dateto, datetbd) VALUES(%s,%s,%s,%s,%s,%s,%s,%s);"
params = (postdata["name"], postdata["message"], formatted["timefrom"], formatted["timeto"], "timetbd" in postdata, postdata["datefrom"], postdata["dateto"], "datetbd" in postdata)
query, response = await db_query(querystring, params)
response = await request.config_dict["query"](querystring, params)
# await update(request)
logevent(request, query)
#logevent(request, query)
raise web.HTTPFound(app['prefix'])
@routes.post('/event/{id}/edit')
@ -100,9 +97,9 @@ def init_app(app):
querystring = "UPDATE events SET name=%s, message=%s, timefrom=%s, timeto=%s, timetbd=%s, datefrom=%s, dateto=%s, datetbd=%s WHERE id=%s;"
params = (postdata["name"], postdata["message"], formatted["timefrom"], formatted["timeto"], "timetbd" in postdata,
postdata["datefrom"], postdata["dateto"], "datetbd" in postdata, request.match_info['id'])
query, response = await db_query(querystring, params)
response = await request.config_dict["query"](querystring, params)
# await update(request)
logevent(request, query)
#logevent(request, query)
raise web.HTTPFound(app['prefix'])
@routes.post('/event/{id}/delete')
@ -110,9 +107,9 @@ def init_app(app):
await aiohttp_security.check_permission(request, 'user')
postdata = await request.post()
querystring = "UPDATE events SET deleted=true WHERE id=%s;"
query, response = await db_query(querystring, (request.match_info['id'],))
response = await request.config_dict["query"](querystring, (request.match_info['id'],))
# await update(request)
logevent(request, query)
#logevent(request, query)
raise web.HTTPFound(app['prefix'])
app.add_routes(routes)

View file

@ -22,6 +22,21 @@ let weeks = [];
let startOfWorkDay, endOfWorkDay, startOfDay, endOfDay, startOfMonth, endOfMonth, startOfCalMonth, endOfCalMonth, lastEvent;
const event_to_object = (datum) => {
return {
id: datum[0],
name: datum[1],
message: datum[2],
timefrom: datum[3],
timeto: datum[4],
timetbd: datum[5],
datefrom: datum[6],
dateto: datum[7],
datetbd: datum[8],
deleted: datum[9]
}
}
const init_times = (today) => {
startOfWorkDay = today.hour(8).minute(0).second(0);
endOfWorkDay = today.hour(17).minute(0).second(0);
@ -342,7 +357,8 @@ const day_onload = (request) => {
//else { }
let dailyEvents = [];
let allDayEvents = [];
for (let event of data) {
for (let datum of data) {
let event = event_to_object(datum);
const tf = dayjs(event.timefrom, "H:mm:ss");
event.datefrom = dayjs(event.datefrom);
event.timefrom = dayjs(event.datefrom).hour(tf.hour()).minute(tf.minute());
@ -388,7 +404,10 @@ const month_onload = (request) => {
data = JSON.parse(request.responseText);
}
//else { }
for (let event of data) {
let converted_data = [];
for (let datum of data) {
let event = event_to_object(datum);
converted_data.push(event);
let tf = dayjs(event.timefrom, "H:mm:ss");
event.datefrom = dayjs(event.datefrom);
event.timefrom = dayjs(event.datefrom).hour(tf.hour()).minute(tf.minute());
@ -408,7 +427,7 @@ const month_onload = (request) => {
}
event.colour = event.deleted ? "#ff0000" : "#32acea";
}
setup_monthly(data);
setup_monthly(converted_data);
}
const adjustField = (field) => {

View file

@ -79,13 +79,6 @@ def init_app(app):
app['stats'] = {'reports_ran': 0, 'status': 'Normal'}
app['menu'] = build_menu(app)
async def db_query(query, params=()):
await app['cur'].execute(query, params)
q = app['cur'].mogrify(query, params)
r = await app['cur'].fetchall()
result = [{k: (str(v) if isinstance(v, datetime.date) or isinstance(v, datetime.timedelta) else v) for k, v in row.items()} for row in r]
return (q, result)
routes = web.RouteTableDef()
app.add_subapp('/admin', subapps.admin)
@ -133,9 +126,7 @@ def init_app(app):
return web.json_response([])
params = ()
await request.config_dict['cur'].execute(query, params)
q = request.config_dict['cur'].mogrify(query, params)
results = await request.config_dict['cur'].fetchall()
results = await request.config_dict['query'](query, params)
return web.json_response([row[0] for row in results], dumps=simplejson.dumps)
@ -306,7 +297,7 @@ def init_app(app):
else:
user_options[fieldname] = value
query_response = await report['query'](request.config_dict['cur'], user_options)
query_response = await report['query'](request.config_dict['query'], user_options)
report_options = {
'formatting': report.get('formatting', True),
'group_by': report.get('group_by')

View file

@ -1,8 +1,4 @@
from decimal import Decimal
import datetime
from dateutil.relativedelta import relativedelta
async def orders_by_employee(cursor, options):
async def orders_by_employee(query_fn, options):
errors = {}
if options["date"]["from"] == '' or options["date"]["to"] == '':
@ -35,8 +31,7 @@ async def orders_by_employee(cursor, options):
) AS inter ON O.OrderID = inter.OrderID
WHERE O.OrderDate BETWEEN %s AND %s;""".format(",".join(['%s'] * len(options["category"])))
await cursor.execute(query, [*options["category"].keys(), options["date"]["from"], options["date"]["to"]])
rows = await cursor.fetchall()
rows = await query_fn(query, [*options["category"].keys(), options["date"]["from"], options["date"]["to"]])
results = []
for row in rows:
@ -46,7 +41,7 @@ async def orders_by_employee(cursor, options):
return {'status': 'ok', 'rows': results, 'period': f'{options["date"]["from"]} - {options["date"]["to"]}'}
async def orders_by_location(cursor, options):
async def orders_by_location(query_fn, options):
errors = {}
if "location" not in options:
@ -86,8 +81,7 @@ async def orders_by_location(cursor, options):
WHERE O.OrderDate BETWEEN %s AND %s;\
""".format(location_query[options["location"]], ",".join(['%s'] * len(options["category"])))
await cursor.execute(query, [*options["category"].keys(), options["date"]["from"], options["date"]["to"]])
rows = await cursor.fetchall()
rows = await query_fn(query, [*options["category"].keys(), options["date"]["from"], options["date"]["to"]])
results = []
for row in rows:
@ -97,7 +91,7 @@ async def orders_by_location(cursor, options):
return {'status': 'ok', 'rows': results, 'period': f'{options["date"]["from"]} - {options["date"]["to"]}'}
async def orders_by_product(cursor, options):
async def orders_by_product(query_fn, options):
errors = {}
if options["date"]["from"] == '' or options["date"]["to"] == '':
@ -125,8 +119,7 @@ async def orders_by_product(cursor, options):
AND O.OrderDate BETWEEN %s AND %s;\
""".format(",".join(['%s'] * len(options["category"])))
await cursor.execute(query, [*options["category"].keys(), options["date"]["from"], options["date"]["to"]])
rows = await cursor.fetchall()
rows = await query_fn(query, [*options["category"].keys(), options["date"]["from"], options["date"]["to"]])
results = []
for row in rows:
@ -136,7 +129,7 @@ async def orders_by_product(cursor, options):
return {'status': 'ok', 'rows': results, 'period': f'{options["date"]["from"]} - {options["date"]["to"]}'}
async def orders_by_supplier(cursor, options):
async def orders_by_supplier(query_fn, options):
errors = {}
if options["date"]["from"] == '' or options["date"]["to"] == '':
@ -166,8 +159,7 @@ async def orders_by_supplier(cursor, options):
AND O.OrderDate BETWEEN %s AND %s;\
""".format(",".join(['%s'] * len(options["category"])))
await cursor.execute(query, [*options["category"].keys(), options["date"]["from"], options["date"]["to"]])
rows = await cursor.fetchall()
rows = await query_fn(query, [*options["category"].keys(), options["date"]["from"], options["date"]["to"]])
results = []
for row in rows:
@ -177,7 +169,7 @@ async def orders_by_supplier(cursor, options):
return {'status': 'ok', 'rows': results, 'period': f'{options["date"]["from"]} - {options["date"]["to"]}'}
async def pivot_table(cursor, options):
async def pivot_table(query_fn, options):
errors = {}
valid_rows = set(['month', 'year', 'employee', 'shipper', 'customer', 'supplier', 'category', 'product'])
valid_columns = set(['month', 'year', 'employee', 'shipper', 'category'])
@ -252,11 +244,10 @@ async def pivot_table(cursor, options):
groupcols=', '+parts[options['columns']][1] if options["columns"] != 'none' else ''
)
await cursor.execute(query, [*options["category"].keys(), options["date"]["from"], options["date"]["to"]])
response = await cursor.fetchall()
rows = await query_fn(query, [*options["category"].keys(), options["date"]["from"], options["date"]["to"]])
if options["columns"] == 'none':
results = [ list(row) for row in response ]
results = [ list(row) for row in rows ]
value_lookup = {'sales': 'Order Value', 'qty': 'Item Quantity'}
rv = {'status': 'ok', 'rows': results, 'columns': [{'name': options['rows'].capitalize()}, {'name': value_lookup[options["values"]], 'format': '$'}]}
return rv
@ -264,7 +255,7 @@ async def pivot_table(cursor, options):
results = []
intermediate = {}
cols = set()
for row in response:
for row in rows:
if row[0] is None:
continue
cols.add(row[1])

13
main.py
View file

@ -7,9 +7,6 @@ import aiomysql
from pymysql.err import OperationalError
import datetime
import simplejson
from dateutil.relativedelta import relativedelta
import urllib.parse
import psutil
# Local
@ -23,7 +20,15 @@ async def mysql_engine(app):
pool = await aiomysql.create_pool(autocommit=True, **app['config']['database'])
app['con'] = await pool.acquire()
app['cur'] = await app['con'].cursor()
app['dcur'] = await app['con'].cursor(aiomysql.DictCursor)
async def db_query(query, params=()):
await app['cur'].execute(query, params)
#q = app['cur'].mogrify(query, params)
r = await app['cur'].fetchall()
#return (q, r)
return r
app['query'] = db_query
except OperationalError as e:
print(e)
print("Done.")