mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-10-12 15:35:15 +00:00
Finish multi-currency budget and account report.
This commit is contained in:
@@ -888,11 +888,18 @@ return [
|
||||
'cannot_change_amount_reconciled' => 'You can\'t change the amount of reconciled transactions.',
|
||||
'no_budget' => '(no budget)',
|
||||
'account_per_budget' => 'Account per budget',
|
||||
'account_per_category' => 'Account per category',
|
||||
'empty' => '(empty)',
|
||||
'all_other_budgets' => '(all other budgets)',
|
||||
'all_other_accounts' => '(all other accounts)',
|
||||
'expense_per_source_account' => 'Expenses per source account',
|
||||
'expense_per_destination_account' => 'Expenses per destination account',
|
||||
'income_per_destination_account' => 'Income per destination account',
|
||||
'spent_in_specific_category' => 'Spent in category ":category"',
|
||||
'earned_in_specific_category' => 'Earned in category ":category"',
|
||||
'income_per_source_account' => 'Income per source account',
|
||||
'average_spending_per_destination' => 'Average expense per destination account',
|
||||
'average_earning_per_source' => 'Average earning per source account',
|
||||
'no_budget_squared' => '(no budget)',
|
||||
'perm-delete-many' => 'Deleting many items in one go can be very disruptive. Please be cautious. You can delete part of a split transaction from this page, so take care.',
|
||||
'mass_deleted_transactions_success' => 'Deleted :amount transaction(s).',
|
||||
|
@@ -37,7 +37,7 @@
|
||||
<tfoot>
|
||||
{% if result|length > listLength %}
|
||||
<tr>
|
||||
<td colspan="4" class="active">
|
||||
<td colspan="5" class="active">
|
||||
<a href="#" class="listLengthTrigger">{{ trans('firefly.show_full_list',{number:incomeTopLength}) }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
@@ -20,7 +20,7 @@
|
||||
<td data-value="{{ budget.name }} ({{ currency.currency_name }})">
|
||||
<a href="{{ route('budgets.show', budget.id) }}" title="{{ budget.name }}">{{ budget.name }} ({{ currency.currency_name }})</a>
|
||||
</td>
|
||||
<td data-value="{{ currency.sym }}" style="text-align: right;">
|
||||
<td data-value="{{ currency.sum }}" style="text-align: right;">
|
||||
{{ formatAmountBySymbol(currency.sum, currency.currency_symbol, currency.currency_decimal_places) }}
|
||||
</td>
|
||||
</tr>
|
||||
|
@@ -45,7 +45,7 @@
|
||||
<tfoot>
|
||||
{% if result|length > listLength %}
|
||||
<tr>
|
||||
<td colspan="4" class="active">
|
||||
<td colspan="5" class="active">
|
||||
<a href="#" class="listLengthTrigger">{{ trans('firefly.show_full_list',{number:incomeTopLength}) }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
@@ -95,7 +95,7 @@
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div style="width:100%;margin:0 auto;">
|
||||
<canvas id="source-accounts-out-pie-chart" style="width:100%;height:250px;" height="250"></canvas>
|
||||
<canvas id="source-out-pie-chart" style="width:100%;height:250px;" height="250"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -107,7 +107,7 @@
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div style="width:100%;margin:0 auto;">
|
||||
<canvas id="source-accounts-in-pie-chart" style="width:100%;height:250px;" height="250"></canvas>
|
||||
<canvas id="source-in-pie-chart" style="width:100%;height:250px;" height="250"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -121,7 +121,7 @@
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div style="width:100%;margin:0 auto;">
|
||||
<canvas id="dest-accounts-out-pie-chart" style="width:100%;height:250px;" height="250"></canvas>
|
||||
<canvas id="dest-out-pie-chart" style="width:100%;height:250px;" height="250"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -133,7 +133,7 @@
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div style="width:100%;margin:0 auto;">
|
||||
<canvas id="dest-accounts-in-pie-chart" style="width:100%;height:250px;" height="250"></canvas>
|
||||
<canvas id="dest-in-pie-chart" style="width:100%;height:250px;" height="250"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -148,7 +148,7 @@
|
||||
<h3 class="box-title">{{ 'income_and_expenses'|_ }} ({{ category.name }})</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
{#<canvas class="main_budget_canvas" data-url="{{ route('chart.category.main', [accountIds, category.id, start.format('Ymd'), end.format('Ymd')]) }}" id="in-out-chart-{{ category.id }}" style="width:100%;height:400px;" height="400" width="100%"></canvas>#}
|
||||
<canvas class="main_category_canvas" data-url="{{ route('chart.category.main', [accountIds, category.id, start.format('Ymd'), end.format('Ymd')]) }}" id="in-out-chart-{{ category.id }}" style="width:100%;height:400px;" height="400" width="100%"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -219,6 +219,7 @@
|
||||
<script type="text/javascript" src="v1/js/ff/charts.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="v1/js/lib/bootstrap-sortable.js?v={{ FF_VERSION }}"></script>
|
||||
|
||||
<script type="text/javascript" src="v1/js/ff/reports/all.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript">
|
||||
// to report another URL:
|
||||
var startDate = '{{ start.format('Ymd') }}';
|
||||
@@ -229,22 +230,24 @@
|
||||
// html block URI's:
|
||||
|
||||
var accountsUri = '{{ route('report-data.category.accounts', [accountIds, categoryIds, start.format('Ymd'), end.format('Ymd')]) }}';
|
||||
|
||||
var categoriesUri = '{{ route('report-data.category.categories', [accountIds, categoryIds, start.format('Ymd'), end.format('Ymd')]) }}';
|
||||
{#var accountPerCategoryUri = '{{ route('report-data.category.account-per-category', [accountIds, categoryIds, start.format('Ymd'), end.format('Ymd')]) }}';#}
|
||||
{#var avgExpensesUri = '{{ route('report-data.category.avg-expenses', [accountIds, categoryIds, start.format('Ymd'), end.format('Ymd')]) }}';#}
|
||||
{#var topExpensesUri = '{{ route('report-data.category.top-expenses', [accountIds, categoryIds, start.format('Ymd'), end.format('Ymd')]) }}';#}
|
||||
var accountPerCategoryUri = '{{ route('report-data.category.account-per-category', [accountIds, categoryIds, start.format('Ymd'), end.format('Ymd')]) }}';
|
||||
|
||||
{#var avgIncomeUri = '{{ route('report-data.category.avg-income', [accountIds, categoryIds, start.format('Ymd'), end.format('Ymd')]) }}';#}
|
||||
{#var topIncomesUri = '{{ route('report-data.category.top-income', [accountIds, categoryIds, start.format('Ymd'), end.format('Ymd')]) }}';#}
|
||||
// pie charts:
|
||||
var categoryOutUri = '{{ route('chart.category.category-expense', [accountIds, categoryIds, start.format('Ymd'), end.format('Ymd')]) }}';
|
||||
var categoryInUri = '{{ route('chart.category.category-income', [accountIds, categoryIds, start.format('Ymd'), end.format('Ymd')]) }}';
|
||||
var budgetsOutUri = '{{ route('chart.category.budget-expense', [accountIds, categoryIds, start.format('Ymd'), end.format('Ymd')]) }}';
|
||||
var sourceOutUri = '{{ route('chart.category.source-expense', [accountIds, categoryIds, start.format('Ymd'), end.format('Ymd')]) }}';
|
||||
var sourceInUri = '{{ route('chart.category.source-income', [accountIds, categoryIds, start.format('Ymd'), end.format('Ymd')]) }}';
|
||||
var destOutUri = '{{ route('chart.category.dest-expense', [accountIds, categoryIds, start.format('Ymd'), end.format('Ymd')]) }}';
|
||||
var destInUri = '{{ route('chart.category.dest-income', [accountIds, categoryIds, start.format('Ymd'), end.format('Ymd')]) }}';
|
||||
|
||||
var avgExpensesUri = '{{ route('report-data.category.avg-expenses', [accountIds, categoryIds, start.format('Ymd'), end.format('Ymd')]) }}';
|
||||
var topExpensesUri = '{{ route('report-data.category.top-expenses', [accountIds, categoryIds, start.format('Ymd'), end.format('Ymd')]) }}';
|
||||
var avgIncomeUri = '{{ route('report-data.category.avg-income', [accountIds, categoryIds, start.format('Ymd'), end.format('Ymd')]) }}';
|
||||
var topIncomeUri = '{{ route('report-data.category.top-income', [accountIds, categoryIds, start.format('Ymd'), end.format('Ymd')]) }}';
|
||||
|
||||
// chart uri's
|
||||
{#var budgetExpenseUri = '{{ route('chart.category.category-expense', [accountIds, categoryIds, start.format('Ymd'), end.format('Ymd')]) }}';#}
|
||||
{#var categoryExpenseUri = '{{ route('chart.category.category-expense', [accountIds, categoryIds, start.format('Ymd'), end.format('Ymd')]) }}';#}
|
||||
{#var sourceExpenseUri = '{{ route('chart.budget.source-account-expense', [accountIds, categoryIds, start.format('Ymd'), end.format('Ymd')]) }}';#}
|
||||
{#var destinationExpenseUri = '{{ route('chart.budget.destination-account-expense', [accountIds, categoryIds, start.format('Ymd'), end.format('Ymd')]) }}';#}
|
||||
</script>
|
||||
<script type="text/javascript" src="v1/js/ff/reports/all.js?v={{ FF_VERSION }}"></script>
|
||||
<script type="text/javascript" src="v1/js/ff/reports/category/month.js?v={{ FF_VERSION }}"></script>
|
||||
|
||||
{% endblock %}
|
||||
|
@@ -0,0 +1,31 @@
|
||||
<table class="table table-hover sortable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-defaultsign="az">{{ 'name'|_ }}</th>
|
||||
{% for category in categories %}
|
||||
<th data-defaultsign="_19" style="text-align: right;">{{ category.name }}</th>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for account in report %}
|
||||
{% for currency in account.currencies %}
|
||||
<tr>
|
||||
<td data-value="{{ account.name }} ({{ currency.currency_name }})">
|
||||
<a href="{{ route('accounts.show', account.id) }}" title="{{ account.iban }}">{{ account.name }} ({{ currency.currency_name }})</a>
|
||||
</td>
|
||||
{% for category in categories %}
|
||||
<td style="text-align: right;">
|
||||
{% if currency.categories[category.id] %}
|
||||
<span title="{{ 'earned'|_ }}: {{ formatAmountBySymbol(currency.categories[category.id].earned, currency.currency_symbol, currency.currency_decimal_places, false) }}, {{ 'spent'|_ }}: {{ formatAmountBySymbol(currency.categories[category.id].spent, currency.currency_symbol, currency.currency_decimal_places, false) }}"
|
||||
{{ formatAmountBySymbol(currency.categories[category.id].sum, currency.currency_symbol, currency.currency_decimal_places) }}
|
||||
{% else %}
|
||||
—
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
@@ -0,0 +1,46 @@
|
||||
<table class="table table-hover sortable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-defaultsign="az">{{ 'account'|_ }}</th>
|
||||
<th data-defaultsign="_19" style="text-align: right;">{{ 'spent_average'|_ }}</th>
|
||||
<th data-defaultsign="_19" style="text-align: right;">{{ 'total'|_ }}</th>
|
||||
<th data-defaultsign="_19">{{ 'transaction_count'|_ }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for row in result %}
|
||||
{% if loop.index > listLength %}
|
||||
<tr class="overListLength">
|
||||
{% else %}
|
||||
<tr>
|
||||
{% endif %}
|
||||
<td data-sortable="false">
|
||||
<a href="{{ route('accounts.show', row.destination_account_id) }}">
|
||||
{{ row.destination_account_name }}
|
||||
</a>
|
||||
</td>
|
||||
<td data-value="{{ row.avg }}" style="text-align: right;">
|
||||
{{ formatAmountBySymbol(row.avg, row.currency_symbol, row.currency_decimal_places) }}
|
||||
</td>
|
||||
|
||||
<td data-value="{{ row.sum }}" style="text-align: right;">
|
||||
{{ formatAmountBySymbol(row.sum, row.currency_symbol, row.currency_decimal_places) }}
|
||||
</td>
|
||||
|
||||
<td data-value="{{ row.transactions }}">
|
||||
{{ row.transactions }}
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
{% if result|length > listLength %}
|
||||
<tr>
|
||||
<td colspan="5" class="active">
|
||||
<a href="#" class="listLengthTrigger">{{ trans('firefly.show_full_list',{number:incomeTopLength}) }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tfoot>
|
||||
</table>
|
46
resources/views/v1/reports/category/partials/avg-income.twig
Normal file
46
resources/views/v1/reports/category/partials/avg-income.twig
Normal file
@@ -0,0 +1,46 @@
|
||||
<table class="table table-hover sortable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-defaultsign="az">{{ 'account'|_ }}</th>
|
||||
<th data-defaultsign="_19" style="text-align: right;">{{ 'spent_average'|_ }}</th>
|
||||
<th data-defaultsign="_19" style="text-align: right;">{{ 'total'|_ }}</th>
|
||||
<th data-defaultsign="_19">{{ 'transaction_count'|_ }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for row in result %}
|
||||
{% if loop.index > listLength %}
|
||||
<tr class="overListLength">
|
||||
{% else %}
|
||||
<tr>
|
||||
{% endif %}
|
||||
<td data-sortable="false">
|
||||
<a href="{{ route('accounts.show', row.source_account_id) }}">
|
||||
{{ row.source_account_name }}
|
||||
</a>
|
||||
</td>
|
||||
<td data-value="{{ row.avg }}" style="text-align: right;">
|
||||
{{ formatAmountBySymbol(row.avg, row.currency_symbol, row.currency_decimal_places) }}
|
||||
</td>
|
||||
|
||||
<td data-value="{{ row.sum }}" style="text-align: right;">
|
||||
{{ formatAmountBySymbol(row.sum, row.currency_symbol, row.currency_decimal_places) }}
|
||||
</td>
|
||||
|
||||
<td data-value="{{ row.transactions }}">
|
||||
{{ row.transactions }}
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
{% if result|length > listLength %}
|
||||
<tr>
|
||||
<td colspan="5" class="active">
|
||||
<a href="#" class="listLengthTrigger">{{ trans('firefly.show_full_list',{number:incomeTopLength}) }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tfoot>
|
||||
</table>
|
56
resources/views/v1/reports/category/partials/categories.twig
Normal file
56
resources/views/v1/reports/category/partials/categories.twig
Normal file
@@ -0,0 +1,56 @@
|
||||
<table class="table table-hover sortable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-defaultsign="az">{{ 'name'|_ }}</th>
|
||||
<th data-defaultsign="_19" style="text-align: right;">{{ 'spent'|_ }}</th>
|
||||
<th data-defaultsign="_19" style="text-align: right;">{{ 'earned'|_ }}</th>
|
||||
<th data-defaultsign="_19" style="text-align: right;">{{ 'sum'|_ }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for category in report %}
|
||||
{% if category.currencies|length == 0 %}
|
||||
<tr>
|
||||
<td data-value="{{ category.name }}">
|
||||
<a href="{{ route('categories.show', category.id) }}" title="{{ category.name }}">{{ category.name }}</a>
|
||||
</td>
|
||||
<td style="text-align: right;">—</td>
|
||||
<td style="text-align: right;">—</td>
|
||||
<td style="text-align: right;">—</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% for currency in category.currencies %}
|
||||
<tr>
|
||||
<td data-value="{{ category.name }} ({{ currency.currency_name }})">
|
||||
<a href="{{ route('categories.show', category.id) }}" title="{{ category.name }}">{{ category.name }} ({{ currency.currency_name }})</a>
|
||||
</td>
|
||||
<td data-value="{{ currency.spent }}" style="text-align: right;">
|
||||
{{ formatAmountBySymbol(currency.spent, currency.currency_symbol, currency.currency_decimal_places) }}
|
||||
</td>
|
||||
<td data-value="{{ currency.earned }}" style="text-align: right;">
|
||||
{{ formatAmountBySymbol(currency.earned, currency.currency_symbol, currency.currency_decimal_places) }}
|
||||
</td>
|
||||
<td data-value="{{ currency.sum }}" style="text-align: right;">
|
||||
{{ formatAmountBySymbol(currency.sum, currency.currency_symbol, currency.currency_decimal_places) }}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
{% for sum in sums %}
|
||||
<tr>
|
||||
<td>{{ 'sum'|_ }} ({{ sum.currency_name }})</td>
|
||||
<td style="text-align: right;">
|
||||
{{ formatAmountBySymbol(sum.spent_sum, sum.currency_symbol, sum.currency_decimal_places) }}
|
||||
</td>
|
||||
<td style="text-align: right;">
|
||||
{{ formatAmountBySymbol(sum.earned_sum, sum.currency_symbol, sum.currency_decimal_places) }}
|
||||
</td>
|
||||
<td style="text-align: right;">
|
||||
{{ formatAmountBySymbol(sum.total_sum, sum.currency_symbol, sum.currency_decimal_places) }}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tfoot>
|
||||
</table>
|
@@ -0,0 +1,54 @@
|
||||
<table class="table table-hover sortable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-defaultsort="disabled">{{ 'description'|_ }}</th>
|
||||
<th data-defaultsign="month">{{ 'date'|_ }}</th>
|
||||
<th data-defaultsign="az">{{ 'account'|_ }}</th>
|
||||
<th data-defaultsign="az">{{ 'category'|_ }}</th>
|
||||
<th data-defaultsign="_19" style="text-align: right;">{{ 'amount'|_ }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for row in result %}
|
||||
{% if loop.index > listLength %}
|
||||
<tr class="overListLength">
|
||||
{% else %}
|
||||
<tr>
|
||||
{% endif %}
|
||||
<td data-sortable="false">
|
||||
<a href="{{ route('transactions.show', row.transaction_group_id) }}">
|
||||
{{ row.description }}
|
||||
</a>
|
||||
</td>
|
||||
<td data-sortable="false">
|
||||
{{ row.date }}
|
||||
</td>
|
||||
|
||||
<td data-sortable="false">
|
||||
<a href="{{ route('accounts.show', row.destination_account_id) }}">
|
||||
{{ row.destination_account_name }}
|
||||
</a>
|
||||
</td>
|
||||
<td data-sortable="false">
|
||||
<a href="{{ route('categories.show', row.category_id) }}">
|
||||
{{ row.category_name }}
|
||||
</a>
|
||||
</td>
|
||||
|
||||
<td data-value="{{ row.amount }}" style="text-align: right;">
|
||||
{{ formatAmountBySymbol(row.amount, row.currency_symbol, row.currency_decimal_places) }}
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
{% if result|length > listLength %}
|
||||
<tr>
|
||||
<td colspan="5" class="active">
|
||||
<a href="#" class="listLengthTrigger">{{ trans('firefly.show_full_list',{number:incomeTopLength}) }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tfoot>
|
||||
</table>
|
54
resources/views/v1/reports/category/partials/top-income.twig
Normal file
54
resources/views/v1/reports/category/partials/top-income.twig
Normal file
@@ -0,0 +1,54 @@
|
||||
<table class="table table-hover sortable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-defaultsort="disabled">{{ 'description'|_ }}</th>
|
||||
<th data-defaultsign="month">{{ 'date'|_ }}</th>
|
||||
<th data-defaultsign="az">{{ 'account'|_ }}</th>
|
||||
<th data-defaultsign="az">{{ 'category'|_ }}</th>
|
||||
<th data-defaultsign="_19" style="text-align: right;">{{ 'amount'|_ }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for row in result %}
|
||||
{% if loop.index > listLength %}
|
||||
<tr class="overListLength">
|
||||
{% else %}
|
||||
<tr>
|
||||
{% endif %}
|
||||
<td data-sortable="false">
|
||||
<a href="{{ route('transactions.show', row.transaction_group_id) }}">
|
||||
{{ row.description }}
|
||||
</a>
|
||||
</td>
|
||||
<td data-sortable="false">
|
||||
{{ row.date }}
|
||||
</td>
|
||||
|
||||
<td data-sortable="false">
|
||||
<a href="{{ route('accounts.show', row.source_account_id) }}">
|
||||
{{ row.source_account_name }}
|
||||
</a>
|
||||
</td>
|
||||
<td data-sortable="false">
|
||||
<a href="{{ route('categories.show', row.category_id) }}">
|
||||
{{ row.category_name }}
|
||||
</a>
|
||||
</td>
|
||||
|
||||
<td data-value="{{ row.amount }}" style="text-align: right;">
|
||||
{{ formatAmountBySymbol(row.amount, row.currency_symbol, row.currency_decimal_places) }}
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
{% if result|length > listLength %}
|
||||
<tr>
|
||||
<td colspan="5" class="active">
|
||||
<a href="#" class="listLengthTrigger">{{ trans('firefly.show_full_list',{number:incomeTopLength}) }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tfoot>
|
||||
</table>
|
Reference in New Issue
Block a user