You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

149 lines
3.9 KiB
Python

10 years ago
from datetime import timedelta, date
import pygal
from .models import User
from payments.models import BACKENDS
from payments.models import Payment
PERIOD_VERBOSE_NAME = {
"y": "per month",
"m": "per day",
10 years ago
}
def monthdelta(date, delta):
m = (date.month + delta) % 12
y = date.year + (date.month + delta - 1) // 12
if not m:
m = 12
d = min(
date.day,
[
31,
29 if y % 4 == 0 and not y % 400 == 0 else 28,
31,
30,
31,
30,
31,
31,
30,
31,
30,
31,
][m - 1],
)
10 years ago
return date.replace(day=d, month=m, year=y)
def last_days(n=30):
now = date.today()
for i in range(n - 1, -1, -1):
yield now - timedelta(days=i)
def last_months(n=12):
now = date.today().replace(day=1)
for i in range(n - 1, -1, -1):
yield monthdelta(now, -i)
def time_filter_future(period, m, df):
def _filter(o):
if period == "m":
10 years ago
return df(o).date() <= m
if period == "y":
10 years ago
return df(o).date().replace(day=1) <= m
10 years ago
return _filter
def time_filter_between(period, m, df):
def _filter(o):
if period == "m":
return (
df(o).year == m.year and df(o).month == m.month and df(o).day == m.day
)
10 years ago
return df(o).date() <= m and df(o).date() > (m - timedelta(days=1))
if period == "y":
10 years ago
return df(o).year == m.year and df(o).month == m.month
return df(o).date().replace(day=1) <= m and df(o).date().replace(day=1) > (
m - timedelta(days=30)
)
10 years ago
return _filter
def users_graph(period):
chart = pygal.Line(fill=True, x_label_rotation=75, show_legend=False)
chart.title = "Users %s" % PERIOD_VERBOSE_NAME[period]
10 years ago
chart.x_labels = []
values = []
gen = last_days(30) if period == "m" else last_months(12)
10 years ago
users = User.objects.all()
for m in gen:
filter_ = time_filter_future(period, m, lambda o: o.date_joined)
users_filtered = filter(filter_, users)
values.append(len(list(users_filtered)))
chart.x_labels.append("%02d/%02d" % (m.month, m.day))
10 years ago
chart.add("Users", values)
10 years ago
return chart.render()
def payments_paid_graph(period):
chart = pygal.StackedBar(x_label_rotation=75, show_legend=True)
chart.x_labels = []
gen = list(last_days(30) if period == "m" else last_months(12))
10 years ago
chart.title = "Payments %s in €" % (PERIOD_VERBOSE_NAME[period])
10 years ago
for m in gen:
chart.x_labels.append("%02d/%02d" % (m.month, m.day))
10 years ago
values = dict()
for backend_id, backend in BACKENDS.items():
values = []
payments = list(
Payment.objects.filter(status="confirmed", backend_id=backend_id)
)
10 years ago
for m in gen:
filter_ = time_filter_between(period, m, lambda o: o.created)
filtered = filter(filter_, payments)
values.append(sum(u.paid_amount for u in filtered) / 100)
chart.add(backend_id, values)
return chart.render()
def payments_success_graph(period):
chart = pygal.StackedBar(x_label_rotation=75, show_legend=True)
chart.x_labels = []
gen = list(last_days(30) if period == "m" else last_months(12))
10 years ago
chart.title = "Successful payments %s" % (PERIOD_VERBOSE_NAME[period])
10 years ago
for m in gen:
chart.x_labels.append("%02d/%02d" % (m.month, m.day))
10 years ago
values = dict()
for backend_id, backend in BACKENDS.items():
values = []
payments = list(
Payment.objects.filter(status="confirmed", backend_id=backend_id)
)
10 years ago
for m in gen:
filter_ = time_filter_between(period, m, lambda o: o.created)
filtered = filter(filter_, payments)
values.append(sum(1 for u in filtered))
chart.add(backend_id, values)
return chart.render()