Implement revenue/expense in budget view

This commit is contained in:
Yingtong Li 2018-06-26 22:36:14 +09:30
parent eddddde263
commit b85b2e0765
Signed by: RunasSudo
GPG Key ID: 7234E476BF21C61A
2 changed files with 121 additions and 11 deletions

View File

@ -103,12 +103,6 @@
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/jsgrid@1.5.3/dist/jsgrid.min.css" integrity="sha256-a/jNbtm7jpeKiXCShJ8YC+eNL9Abh7CBiYXHgaofUVs=" crossorigin="anonymous"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/jsgrid@1.5.3/dist/jsgrid.min.css" integrity="sha256-a/jNbtm7jpeKiXCShJ8YC+eNL9Abh7CBiYXHgaofUVs=" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/jsgrid@1.5.3/dist/jsgrid-theme.min.css" integrity="sha256-0rD7ZUV4NLK6VtGhEim14ZUZGC45Kcikjdcr4N03ddA=" crossorigin="anonymous"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/jsgrid@1.5.3/dist/jsgrid-theme.min.css" integrity="sha256-0rD7ZUV4NLK6VtGhEim14ZUZGC45Kcikjdcr4N03ddA=" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/dragula@3.7.2/dist/dragula.min.css" integrity="sha256-iVhQxXOykHeL03K08zkxBGxDCLCuzRGGiTYf2FL6mLY=" crossorigin="anonymous"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/dragula@3.7.2/dist/dragula.min.css" integrity="sha256-iVhQxXOykHeL03K08zkxBGxDCLCuzRGGiTYf2FL6mLY=" crossorigin="anonymous">
<style type="text/css">
textarea {
font-family: Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;
}
</style>
{% endblock %} {% endblock %}
{% block script %} {% block script %}

View File

@ -34,11 +34,11 @@
</div> </div>
{% endif %} {% endif %}
<table class="ui definition table"> <table class="ui mydefinition table">
<tbody> <tbody>
<tr> <tr>
<td class="three wide">ID</td> <td class="two wide">ID</td>
<td class="thirteen wide">{{ revision.budget.id }}</td> <td class="fourteen wide">{{ revision.budget.id }}</td>
</tr> </tr>
<tr> <tr>
<td>Name</td> <td>Name</td>
@ -74,7 +74,7 @@
<tr> <tr>
<td>Revenue</td> <td>Revenue</td>
<td> <td>
<div>{{ revision.revenue }}</div> <div id="revenue_grid"></div>
{% if revision.revenue_comments %} {% if revision.revenue_comments %}
<div class="ui accordion"> <div class="ui accordion">
<div class="active title"> <div class="active title">
@ -91,7 +91,7 @@
<tr> <tr>
<td>Expenses</td> <td>Expenses</td>
<td> <td>
<div>{{ revision.expense }}</div> <div id="expense_grid"></div>
{% if revision.expense_comments %} {% if revision.expense_comments %}
<div class="ui accordion"> <div class="ui accordion">
<div class="active title"> <div class="active title">
@ -157,3 +157,119 @@
</div> </div>
{% endif %} {% endif %}
{% endblock %} {% endblock %}
{% block head %}
{{ super() }}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/jsgrid@1.5.3/dist/jsgrid.min.css" integrity="sha256-a/jNbtm7jpeKiXCShJ8YC+eNL9Abh7CBiYXHgaofUVs=" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/jsgrid@1.5.3/dist/jsgrid-theme.min.css" integrity="sha256-0rD7ZUV4NLK6VtGhEim14ZUZGC45Kcikjdcr4N03ddA=" crossorigin="anonymous">
<style>
.ui.mydefinition.table > tbody > tr > td:first-child:not(.ignored) {
background: rgba(0,0,0,.03);
font-weight: 700;
color: rgba(0,0,0,.95);
}
</style>
{% endblock %}
{% block script %}
{{ super() }}
<script src="https://cdn.jsdelivr.net/npm/jsgrid@1.5.3/dist/jsgrid.min.js" integrity="sha256-lzjMTpg04xOdI+MJdjBst98bVI6qHToLyVodu3EywFU=" crossorigin="anonymous"></script>
<script>
function recalcRevTotal(args) {
//console.log(args);
var total = 0;
var totalIWT = 0;
for (var row of args.grid.data) {
total += row['Unit cost'] * row['Units'];
if (row['Unit cost'] > 0 && row['IWT']) {
totalIWT += (row['Unit cost'] - (row['Unit cost'] - 0.8) / 1.019) * row['Units'];
}
}
$(args.grid._body).find('.totalrow').remove();
if (totalIWT > 0) {
var totalrow = $('<tr class="jsgrid-row totalrow" style="font-weight: bold;"></tr>');
totalrow.append($('<td class="jsgrid-cell">Less IWT fees:</td>').prop('colspan', args.grid.fields.length - 1));
totalrow.append($('<td class="jsgrid-cell jsgrid-align-right"></td>').text('($' + totalIWT.toFixed(2) + ')'));
$(args.grid._body).find('tr:last').after(totalrow);
}
var totalrow = $('<tr class="jsgrid-row totalrow" style="font-weight: bold;"></tr>');
totalrow.append($('<td class="jsgrid-cell">Total:</td>').prop('colspan', args.grid.fields.length - 1));
totalrow.append($('<td class="jsgrid-cell jsgrid-align-right"></td>').text('$' + (total - totalIWT).toFixed(2)));
$(args.grid._body).find('tr:last').after(totalrow);
}
function recalcExpTotal(args) {
var total = 0;
for (var row of args.grid.data) {
total += row['Unit cost'] * row['Units'];
}
$(args.grid._body).find('.totalrow').remove();
var totalrow = $('<tr class="jsgrid-row totalrow" style="font-weight: bold;"></tr>');
totalrow.append($('<td class="jsgrid-cell">Plus emergency fund:</td>').prop('colspan', args.grid.fields.length - 1));
totalrow.append($('<td class="jsgrid-cell jsgrid-align-right"></td>').text('$' + (total * 0.05).toFixed(2)));
$(args.grid._body).find('tr:last').after(totalrow);
var totalrow = $('<tr class="jsgrid-row totalrow" style="font-weight: bold;"></tr>');
totalrow.append($('<td class="jsgrid-cell">Total:</td>').prop('colspan', args.grid.fields.length - 1));
totalrow.append($('<td class="jsgrid-cell jsgrid-align-right"></td>').text('$' + (total * 1.05).toFixed(2)));
$(args.grid._body).find('tr:last').after(totalrow);
}
// Allow floats
function FloatNumberField(config) {
jsGrid.NumberField.call(this, config);
}
FloatNumberField.prototype = new jsGrid.NumberField({
filterValue: function() {
return parseFloat(this.filterControl.val());
},
insertValue: function() {
return parseFloat(this.insertControl.val());
},
editValue: function() {
return parseFloat(this.editControl.val());
}
});
jsGrid.fields.float = FloatNumberField;
var revenue_data = JSON.parse({{ import('json').dumps(import('json').dumps(revision.revenue))|safe }});
$('#revenue_grid').jsGrid({
width: '100%',
height: 'auto',
noDataContent: 'No entries',
data: revenue_data,
fields: [
{ name: 'Description', type: 'text', width: '55%', validate: 'required' },
{ name: 'Unit cost', type: 'float', width: '10%', validate: 'required', itemTemplate: function(value, item) { return '$' + value.toFixed(2); } },
{ name: 'Units', type: 'float', width: '10%', validate: 'required' },
{ name: 'IWT', type: 'checkbox', width: '5%' },
{ name: 'Total', align: 'right', width: '10%', itemTemplate: function(value, item) { return '$' + (item['Unit cost'] * item['Units']).toFixed(2); } },
],
onRefreshed: recalcRevTotal,
});
var expense_data = JSON.parse({{ import('json').dumps(import('json').dumps(revision.expense))|safe }});
$('#expense_grid').jsGrid({
width: '100%',
height: 'auto',
noDataContent: 'No entries',
data: expense_data,
fields: [
{ name: 'Description', type: 'text', width: '55%', validate: 'required' },
{ name: 'Unit cost', type: 'float', width: '10%', validate: 'required', itemTemplate: function(value, item) { return '$' + value.toFixed(2); } },
{ name: 'Units', type: 'float', width: '10%', validate: 'required' },
{ name: 'Total', align: 'right', width: '10%', itemTemplate: function(value, item) { return '$' + (item['Unit cost'] * item['Units']).toFixed(2); } },
],
onRefreshed: recalcExpTotal,
});
</script>
{% endblock %}