180 lines
4.8 KiB
Python
180 lines
4.8 KiB
Python
#from datetime import datetime
|
|
|
|
from django.conf import settings
|
|
from django.db import connection
|
|
from django.utils.translation import gettext
|
|
from calendar import day_name
|
|
|
|
|
|
COMBINE_ALPHABET = "abcdefghijklmnopqrstuvwxyz"
|
|
|
|
|
|
def _db_select(sql_select:str):
|
|
result = None
|
|
with connection.cursor() as cursor:
|
|
cursor.execute(sql_select)
|
|
result = cursor.fetchall()
|
|
return result
|
|
|
|
def _combine_results(results:list) -> dict:
|
|
'''
|
|
e.g.
|
|
input: [
|
|
[("x", 12), ("y", 13)],
|
|
[("y", 10), ("z", 42)]
|
|
]
|
|
output: {
|
|
"x": {"a": 12},
|
|
"y": {"a": 13, "b": 10},
|
|
"z": {"b": 42}
|
|
}
|
|
'''
|
|
result = {}
|
|
for i, d in enumerate(results):
|
|
a = COMBINE_ALPHABET[i]
|
|
for r in d:
|
|
r_0 = r[0]
|
|
if r_0 not in result:
|
|
result[r_0] = {}
|
|
result[r_0][a] = r[1]
|
|
return result
|
|
|
|
|
|
def select_history(user, language_code="en") -> list:
|
|
# select order history and deposits
|
|
user_id = user.pk
|
|
result = _db_select(f"""
|
|
select
|
|
price_sum as "sum",
|
|
concat(
|
|
product_name,
|
|
' (',
|
|
content_litres::real, -- converting to real removes trailing zeros
|
|
'l) x ', amount
|
|
) as "text",
|
|
datetime
|
|
from app_order
|
|
where user_id = {user_id}
|
|
|
|
union
|
|
|
|
select
|
|
transaction_sum as "sum",
|
|
'{gettext("Deposit")}' as "text",
|
|
datetime
|
|
from app_userdeposits_view
|
|
where user_id = {user_id}
|
|
|
|
union
|
|
|
|
select
|
|
transaction_sum as "sum",
|
|
comment as "text",
|
|
datetime
|
|
from app_registertransaction
|
|
where user_id = {user_id} and is_transfer = true
|
|
|
|
order by datetime desc
|
|
fetch first 30 rows only;
|
|
""")
|
|
result = [list(row) for row in result]
|
|
return result
|
|
|
|
def select_orders_per_month(user) -> dict:
|
|
# number of orders per month (last 12 months)
|
|
result_user = _db_select(f"""
|
|
select
|
|
to_char(date_trunc('month', datetime), 'YYYY-MM') as "month",
|
|
sum(amount) as "count"
|
|
from app_order
|
|
where user_id = {user.pk}
|
|
and date_trunc('month', datetime) > date_trunc('month', now() - '12 months'::interval)
|
|
group by "month"
|
|
order by "month" desc;
|
|
""")
|
|
result_all = _db_select(f"""
|
|
select
|
|
to_char(date_trunc('month', datetime), 'YYYY-MM') as "month",
|
|
sum(amount) as "count"
|
|
from app_order
|
|
where date_trunc('month', datetime) > date_trunc('month', now() - '12 months'::interval)
|
|
group by "month"
|
|
order by "month" desc;
|
|
""")
|
|
return _combine_results([result_all, result_user])
|
|
|
|
def select_orders_per_weekday(user) -> list:
|
|
# number of orders per weekday (all time)
|
|
result = _db_select(f"""
|
|
with q_all as (
|
|
select
|
|
extract(isodow from datetime) as "d",
|
|
sum(amount) as "c"
|
|
from app_order
|
|
group by d
|
|
), q_user as (
|
|
select
|
|
extract(isodow from datetime) as "d",
|
|
sum(amount) as "c"
|
|
from app_order
|
|
where user_id = {user.pk}
|
|
group by d
|
|
)
|
|
select q_all.d as "day", q_all.c, q_user.c from q_all full join q_user on q_all.d = q_user.d
|
|
group by day, q_all.c, q_user.c
|
|
order by day asc;
|
|
""")
|
|
for i in range(len(result)):
|
|
day_, all_, user_ = result[i]
|
|
result[i] = (day_name[int(day_)-1], all_, user_)
|
|
return result
|
|
|
|
def select_orders_per_drink(user) -> dict:
|
|
# number of orders per drink (all time)
|
|
result_user = _db_select(f"""
|
|
select
|
|
d.product_name as "label",
|
|
sum(o.amount) as "data"
|
|
from app_drink d
|
|
join app_order o on (d.id = o.drink_id)
|
|
where o.user_id = {user.pk}
|
|
group by d.product_name
|
|
order by "data" desc;
|
|
""")
|
|
result_all = _db_select(f"""
|
|
select
|
|
d.product_name as "label",
|
|
sum(o.amount) as "data"
|
|
from app_drink d
|
|
join app_order o on (d.id = o.drink_id)
|
|
group by d.product_name
|
|
order by "data" desc;
|
|
""")
|
|
return _combine_results([result_all, result_user])
|
|
|
|
def select_order_sum_per_user_all_users() -> list:
|
|
# sum of all orders per user, for all users
|
|
result = _db_select(f"""
|
|
select
|
|
app_user.username as user,
|
|
sum(app_order.price_sum) as sum
|
|
from app_user
|
|
left outer join app_order on (app_user.id = app_order.user_id)
|
|
group by app_user.id
|
|
order by app_user asc;
|
|
""")
|
|
return result
|
|
|
|
def select_deposit_sum_per_user_all_users() -> list:
|
|
# sum of all orders per user, for all users
|
|
result = _db_select(f"""
|
|
select
|
|
app_user.username as user,
|
|
sum(rt.transaction_sum) as sum
|
|
from app_user
|
|
left outer join app_registertransaction rt on (app_user.id = rt.user_id)
|
|
where rt.is_user_deposit is true or rt.is_user_deposit is null
|
|
group by app_user.id
|
|
order by app_user asc;
|
|
""")
|
|
return result
|