Graph previous year totals and year-to-date totals next to budget listing/filtering results

This commit is contained in:
Yingtong Li 2023-05-01 21:24:24 +10:00
parent 8d3a7b7ed0
commit 603e276bac
Signed by: RunasSudo
GPG Key ID: 7234E476BF21C61A
2 changed files with 60 additions and 0 deletions

View File

@ -111,6 +111,11 @@
{% endif %}
</div>
</div>
{% if yearly_totals %}
<h2>Yearly totals</h2>
<canvas id="chartYearlyTotals"></canvas>
{% endif %}
{% endblock %}
{% block head %}
@ -123,4 +128,41 @@
<script>
$('.ui.dropdown').dropdown();
</script>
{% if yearly_totals %}
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.3.0/dist/chart.umd.js" integrity="sha256-5dsP1lVzcWPn5aOwu+zs+G+TqAu9oT8NUNM0C4n3H+4=" crossorigin="anonymous"></script>
<script>
const yearlyTotalsData = JSON.parse({{ import('json').dumps(import('json').dumps(yearly_totals))|safe }});
new Chart(document.getElementById('chartYearlyTotals'), {
type: 'bar',
data: {
labels: yearlyTotalsData.map(x => x[0]),
datasets: [{
label: {{ import('json').dumps(import('json').dumps(request.GET.get('cost_centre', 'all')))|safe }},
data: yearlyTotalsData.map(x => x[1]),
backgroundColor: yearlyTotalsData.map(x => x[1] >= 0 ? '#36a2eb' : '#ff6384')
}]
},
options: {
indexAxis: 'y',
scales: {
x: {
beginAtZero: true
}
},
plugins: {
legend: {
display: false
},
tooltip: {
callbacks: {
label: i => '$' + i.parsed.x.toFixed(2)
}
}
}
},
});
</script>
{% endif %}
{% endblock %}

View File

@ -36,6 +36,7 @@ from ssmain.email import Emailer
import csv
from datetime import datetime
from decimal import Decimal
import functools
import io
import itertools
@ -266,13 +267,30 @@ def budget_list(request):
if group is not None:
group.append(revision)
# Get yearly totals
if request.GET.get('cost_centre', 'all') != 'all':
yearly_totals = [[y, float(t)] for y, t in get_yearly_totals(budgets_filtered)]
else:
yearly_totals = None
return render(request, 'sstreasury/budget_list.html', {
'budgets_action': budgets_action,
'budgets_open': budgets_open,
'budgets_closed': budgets_closed,
'yearly_totals': yearly_totals,
'page': page
})
def get_yearly_totals(budgets_filtered):
"""Get total net profit per calendar year"""
results = []
for year, g in itertools.groupby(sorted(budgets_filtered, key=lambda r: r.time.year), key=lambda r: r.time.year):
results.append((year, sum((r.get_revenue_total() - r.get_expense_total() for r in g), Decimal('0'))))
return results
@login_required
@uses_budget
def budget_view(request, budget, revision):