-
-
Are you sure you want to submit this budget for Treasury review? You will not be able to make any additional changes without withdrawing the budget.
-
-
-
Are you sure you want to give this budget Treasury endorsement?
-
-
-
Are you sure you want to give this budget Treasury endorsement?
-
-
-
Are you sure you want to refuse this budget Treasury endorsement and return it for re-drafting?
-
-
-
Are you sure you want to refuse this budget Treasury endorsement and return it for re-drafting?
-
-
-
Are you sure you want to mark this budget as committee-approved?
-
-
-
Are you sure you want to mark this budget as committee-approved?
-
-
-
Are you sure you want to refuse this budget committee approval and return it for re-drafting?
-
-
-
Are you sure you want to refuse this budget committee approval and return it for re-drafting?
-
-
-
Are you sure you want to withdraw this budget from being considered for approval? The budget will be reverted to a draft.
-
-
-
Are you sure you want to cancel this budget?
-
-
+
+
+
+
+
+
{% endblock %}
@@ -327,6 +338,15 @@
.jsgrid-header-row .jsgrid-header-cell {
text-align: center !important;
}
+
+ /* Full screen width for graphs */
+ @media only screen and (min-width: 768px) {
+ .ui.container {
+ width: auto;
+ margin-left: 64px !important;
+ margin-right: 64px !important;
+ }
+ }
{% endblock %}
@@ -355,6 +375,7 @@
+
@@ -363,5 +384,6 @@
var expense_data = JSON.parse({{ import('json').dumps(import('json').dumps(revision.expense))|safe }});
var editing = false;
makeGrid();
+ makeCharts();
{% endblock %}
diff --git a/sstreasury/static/sstreasury/budget.js b/sstreasury/static/sstreasury/budget.js
index bd2199d..aa07095 100644
--- a/sstreasury/static/sstreasury/budget.js
+++ b/sstreasury/static/sstreasury/budget.js
@@ -1,6 +1,7 @@
/*
Society Self-Service
- Copyright © 2018-2019 Yingtong Li (RunasSudo)
+ Copyright © 2018-2023 Yingtong Li (RunasSudo)
+ Copyright © 2023 MUMUS Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
@@ -18,22 +19,27 @@
$('.ui.accordion').accordion();
+var revTotal = 0;
+var revTotalIWT = 0;
+var expTotal = 0;
+var emergency_fund_mult = 0.05;
+
function recalcRevTotal(args) {
- var total = 0;
- var totalIWT = 0;
+ revTotal = 0;
+ revTotalIWT = 0;
for (var row of args.grid.data) {
- total += row['Unit price'] * row['Units'];
+ revTotal += row['Unit price'] * row['Units'];
if (row['Unit price'] > 0 && row['IWT']) {
- totalIWT += (row['Unit price'] - (row['Unit price'] - 0.8133) / 1.01884) * row['Units'];
+ revTotalIWT += (row['Unit price'] - (row['Unit price'] - 0.8133) / 1.01884) * row['Units'];
}
}
$(args.grid._body).find('.totalrow').remove();
- if (totalIWT > 0) {
+ if (revTotalIWT > 0) {
var totalrow = $('
|
');
totalrow.append($('
Less IWT fees: | ').prop('colspan', args.grid.fields.length - (editing ? 2 : 1)));
- totalrow.append($('
| ').text('($' + totalIWT.toFixed(2) + ')'));
+ totalrow.append($('
| ').text('($' + revTotalIWT.toFixed(2) + ')'));
if (editing) {
totalrow.append($('
| '));
}
@@ -42,7 +48,7 @@ function recalcRevTotal(args) {
var totalrow = $('
|
');
totalrow.append($('
Total: | ').prop('colspan', args.grid.fields.length - (editing ? 2 : 1)));
- totalrow.append($('
| ').text('$' + (total - totalIWT).toFixed(2)));
+ totalrow.append($('
| ').text('$' + (revTotal - revTotalIWT).toFixed(2)));
if (editing) {
totalrow.append($('
| '));
}
@@ -50,21 +56,21 @@ function recalcRevTotal(args) {
}
function recalcExpTotal(args) {
- var total = 0;
+ expTotal = 0;
for (var row of args.grid.data) {
- total += row['Unit price'] * row['Units'];
+ expTotal += row['Unit price'] * row['Units'];
}
$(args.grid._body).find('.totalrow').remove();
- var emergency_fund_mult = 0.05;
+ emergency_fund_mult = 0.05;
if ($('#expense_no_emergency_fund').length > 0 && $('#expense_no_emergency_fund').prop('checked')) {
emergency_fund_mult = 0;
}
var totalrow = $('
|
');
totalrow.append($('
Plus emergency fund: | ').prop('colspan', args.grid.fields.length - (editing ? 2 : 1)));
- totalrow.append($('
| ').text('$' + (total * emergency_fund_mult).toFixed(2)));
+ totalrow.append($('
| ').text('$' + (expTotal * emergency_fund_mult).toFixed(2)));
if (editing) {
totalrow.append($('
| '));
}
@@ -72,7 +78,7 @@ function recalcExpTotal(args) {
var totalrow = $('
|
');
totalrow.append($('
Total: | ').prop('colspan', args.grid.fields.length - (editing ? 2 : 1)));
- totalrow.append($('
| ').text('$' + (total * (1 + emergency_fund_mult)).toFixed(2)));
+ totalrow.append($('
| ').text('$' + (expTotal * (1 + emergency_fund_mult)).toFixed(2)));
if (editing) {
totalrow.append($('
| '));
}
@@ -146,3 +152,56 @@ function makeGrid() {
$('.jsgrid-filter-row, .jsgrid-insert-row').attr('style', 'display: none !important;'); /* Override Semantic UI */
}
}
+
+function makeCharts() {
+ // Display expense, revenue charts on budget view page
+
+ new Chart(document.getElementById('chartExpenses'), {
+ type: 'pie',
+ data: {
+ labels: expense_data.map(e => e['Description']),
+ datasets: [{
+ label: 'Expenses',
+ data: expense_data.map(e => e['Unit price'] * e['Units'])
+ }]
+ },
+ options: {
+ plugins: {
+ tooltip: {
+ callbacks: {
+ label: i => '$' + i.parsed.toFixed(2)
+ }
+ }
+ }
+ },
+ });
+
+ new Chart(document.getElementById('chartRevExp'), {
+ type: 'bar',
+ data: {
+ labels: ['Revenue', 'Expenses'],
+ datasets: [{
+ label: 'Budget',
+ data: [revTotal - revTotalIWT, (expTotal * (1 + emergency_fund_mult))],
+ backgroundColor: ['#36a2eb', '#ff6384']
+ }]
+ },
+ options: {
+ scales: {
+ y: {
+ beginAtZero: true
+ }
+ },
+ plugins: {
+ legend: {
+ display: false
+ },
+ tooltip: {
+ callbacks: {
+ label: i => '$' + i.parsed.y.toFixed(2)
+ }
+ }
+ }
+ },
+ });
+}