Graph previous year totals and year-to-date totals next to budget listing/filtering results
This commit is contained in:
parent
8d3a7b7ed0
commit
603e276bac
@ -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 %}
|
||||
|
@ -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):
|
||||
|
Loading…
Reference in New Issue
Block a user