mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Updated code for #384
This commit is contained in:
parent
b1b6fe553a
commit
0c529cb7e7
@ -59,6 +59,60 @@ class ExpenseController extends Controller
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $accounts
|
||||||
|
* @param Collection $expense
|
||||||
|
* @param Carbon $start
|
||||||
|
* @param Carbon $end
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @throws \Throwable
|
||||||
|
*/
|
||||||
|
public function budget(Collection $accounts, Collection $expense, Carbon $start, Carbon $end)
|
||||||
|
{
|
||||||
|
// Properties for cache:
|
||||||
|
$cache = new CacheProperties;
|
||||||
|
$cache->addProperty($start);
|
||||||
|
$cache->addProperty($end);
|
||||||
|
$cache->addProperty('expense-budget');
|
||||||
|
$cache->addProperty($accounts->pluck('id')->toArray());
|
||||||
|
$cache->addProperty($expense->pluck('id')->toArray());
|
||||||
|
if ($cache->has()) {
|
||||||
|
return $cache->get(); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
$combined = $this->combineAccounts($expense);
|
||||||
|
$all = new Collection;
|
||||||
|
foreach ($combined as $name => $combi) {
|
||||||
|
$all = $all->merge($combi);
|
||||||
|
}
|
||||||
|
// now find spent / earned:
|
||||||
|
$spent = $this->spentByBudget($accounts, $all, $start, $end);
|
||||||
|
// do some merging to get the budget info ready.
|
||||||
|
$together = [];
|
||||||
|
foreach ($spent as $budgetId => $spentInfo) {
|
||||||
|
if (!isset($together[$budgetId])) {
|
||||||
|
$together[$budgetId]['spent'] = $spentInfo;
|
||||||
|
// get category info:
|
||||||
|
$first = reset($spentInfo);
|
||||||
|
$together[$budgetId]['budget'] = $first['budget'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = view('reports.partials.exp-budgets', compact('together'))->render();
|
||||||
|
$cache->store($result);
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $accounts
|
||||||
|
* @param Collection $expense
|
||||||
|
* @param Carbon $start
|
||||||
|
* @param Carbon $end
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @throws \Throwable
|
||||||
|
*/
|
||||||
public function category(Collection $accounts, Collection $expense, Carbon $start, Carbon $end)
|
public function category(Collection $accounts, Collection $expense, Carbon $start, Carbon $end)
|
||||||
{
|
{
|
||||||
// Properties for cache:
|
// Properties for cache:
|
||||||
@ -82,20 +136,20 @@ class ExpenseController extends Controller
|
|||||||
|
|
||||||
// join arrays somehow:
|
// join arrays somehow:
|
||||||
$together = [];
|
$together = [];
|
||||||
foreach($spent as $categoryId => $spentInfo) {
|
foreach ($spent as $categoryId => $spentInfo) {
|
||||||
if(!isset($together[$categoryId])) {
|
if (!isset($together[$categoryId])) {
|
||||||
$together[$categoryId]['spent'] = $spentInfo;
|
$together[$categoryId]['spent'] = $spentInfo;
|
||||||
// get category info:
|
// get category info:
|
||||||
$first = reset($spentInfo);
|
$first = reset($spentInfo);
|
||||||
$together[$categoryId]['category'] = $first['category'];
|
$together[$categoryId]['category'] = $first['category'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($earned as $categoryId => $earnedInfo) {
|
foreach ($earned as $categoryId => $earnedInfo) {
|
||||||
if(!isset($together[$categoryId])) {
|
if (!isset($together[$categoryId])) {
|
||||||
$together[$categoryId]['earned'] = $earnedInfo;
|
$together[$categoryId]['earned'] = $earnedInfo;
|
||||||
// get category info:
|
// get category info:
|
||||||
$first = reset($earnedInfo);
|
$first = reset($earnedInfo);
|
||||||
$together[$categoryId]['category'] = $first['category'];
|
$together[$categoryId]['category'] = $first['category'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -223,6 +277,58 @@ class ExpenseController extends Controller
|
|||||||
return $combined;
|
return $combined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $assets
|
||||||
|
* @param Collection $opposing
|
||||||
|
* @param Carbon $start
|
||||||
|
* @param Carbon $end
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function earnedByCategory(Collection $assets, Collection $opposing, Carbon $start, Carbon $end): array
|
||||||
|
{
|
||||||
|
/** @var JournalCollectorInterface $collector */
|
||||||
|
$collector = app(JournalCollectorInterface::class);
|
||||||
|
$collector->setRange($start, $end)->setTypes([TransactionType::DEPOSIT])->setAccounts($assets);
|
||||||
|
$collector->setOpposingAccounts($opposing)->withCategoryInformation();
|
||||||
|
$set = $collector->getJournals();
|
||||||
|
$sum = [];
|
||||||
|
// loop to support multi currency
|
||||||
|
foreach ($set as $transaction) {
|
||||||
|
$currencyId = $transaction->transaction_currency_id;
|
||||||
|
$categoryName = $transaction->transaction_category_name;
|
||||||
|
$categoryId = intval($transaction->transaction_category_id);
|
||||||
|
// if null, grab from journal:
|
||||||
|
if ($categoryId === 0) {
|
||||||
|
$categoryName = $transaction->transaction_journal_category_name;
|
||||||
|
$categoryId = intval($transaction->transaction_journal_category_id);
|
||||||
|
}
|
||||||
|
if ($categoryId !== 0) {
|
||||||
|
$categoryName = app('steam')->tryDecrypt($categoryName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if not set, set to zero:
|
||||||
|
if (!isset($sum[$categoryId][$currencyId])) {
|
||||||
|
$sum[$categoryId][$currencyId] = [
|
||||||
|
'sum' => '0',
|
||||||
|
'category' => [
|
||||||
|
'id' => $categoryId,
|
||||||
|
'name' => $categoryName,
|
||||||
|
],
|
||||||
|
'currency' => [
|
||||||
|
'symbol' => $transaction->transaction_currency_symbol,
|
||||||
|
'dp' => $transaction->transaction_currency_dp,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// add amount
|
||||||
|
$sum[$categoryId][$currencyId]['sum'] = bcadd($sum[$categoryId][$currencyId]['sum'], $transaction->transaction_amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $sum;
|
||||||
|
}
|
||||||
|
|
||||||
protected function earnedInPeriod(Collection $assets, Collection $opposing, Carbon $start, Carbon $end): array
|
protected function earnedInPeriod(Collection $assets, Collection $opposing, Carbon $start, Carbon $end): array
|
||||||
{
|
{
|
||||||
/** @var JournalCollectorInterface $collector */
|
/** @var JournalCollectorInterface $collector */
|
||||||
@ -259,37 +365,34 @@ class ExpenseController extends Controller
|
|||||||
* @param Carbon $start
|
* @param Carbon $start
|
||||||
* @param Carbon $end
|
* @param Carbon $end
|
||||||
*
|
*
|
||||||
* @return string
|
* @return array
|
||||||
*/
|
*/
|
||||||
protected function earnedByCategory(Collection $assets, Collection $opposing, Carbon $start, Carbon $end): array
|
protected function spentByBudget(Collection $assets, Collection $opposing, Carbon $start, Carbon $end): array
|
||||||
{
|
{
|
||||||
/** @var JournalCollectorInterface $collector */
|
/** @var JournalCollectorInterface $collector */
|
||||||
$collector = app(JournalCollectorInterface::class);
|
$collector = app(JournalCollectorInterface::class);
|
||||||
$collector->setRange($start, $end)->setTypes([TransactionType::DEPOSIT])->setAccounts($assets);
|
$collector->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])->setAccounts($assets);
|
||||||
$collector->setOpposingAccounts($opposing)->withCategoryInformation();
|
$collector->setOpposingAccounts($opposing)->withBudgetInformation();
|
||||||
$set = $collector->getJournals();
|
$set = $collector->getJournals();
|
||||||
$sum = [];
|
$sum = [];
|
||||||
// loop to support multi currency
|
// loop to support multi currency
|
||||||
foreach ($set as $transaction) {
|
foreach ($set as $transaction) {
|
||||||
$currencyId = $transaction->transaction_currency_id;
|
$currencyId = $transaction->transaction_currency_id;
|
||||||
$categoryName = $transaction->transaction_category_name;
|
$budgetName = $transaction->transaction_budget_name;
|
||||||
$categoryId = intval($transaction->transaction_category_id);
|
$budgetId = intval($transaction->transaction_budget_id);
|
||||||
// if null, grab from journal:
|
// if null, grab from journal:
|
||||||
if ($categoryId === 0) {
|
if ($budgetId === 0) {
|
||||||
$categoryName = $transaction->transaction_journal_category_name;
|
$budgetName = $transaction->transaction_journal_budget_name;
|
||||||
$categoryId = intval($transaction->transaction_journal_category_id);
|
$budgetId = intval($transaction->transaction_journal_budget_id);
|
||||||
}
|
|
||||||
if($categoryId !== 0) {
|
|
||||||
$categoryName = app('steam')->tryDecrypt($categoryName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if not set, set to zero:
|
// if not set, set to zero:
|
||||||
if (!isset($sum[$categoryId][$currencyId])) {
|
if (!isset($sum[$budgetId][$currencyId])) {
|
||||||
$sum[$categoryId][$currencyId] = [
|
$sum[$budgetId][$currencyId] = [
|
||||||
'sum' => '0',
|
'sum' => '0',
|
||||||
'category' => [
|
'budget' => [
|
||||||
'id' => $categoryId,
|
'id' => $budgetId,
|
||||||
'name' => $categoryName,
|
'name' => $budgetName,
|
||||||
],
|
],
|
||||||
'currency' => [
|
'currency' => [
|
||||||
'symbol' => $transaction->transaction_currency_symbol,
|
'symbol' => $transaction->transaction_currency_symbol,
|
||||||
@ -299,7 +402,7 @@ class ExpenseController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add amount
|
// add amount
|
||||||
$sum[$categoryId][$currencyId]['sum'] = bcadd($sum[$categoryId][$currencyId]['sum'], $transaction->transaction_amount);
|
$sum[$budgetId][$currencyId]['sum'] = bcadd($sum[$budgetId][$currencyId]['sum'], $transaction->transaction_amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $sum;
|
return $sum;
|
||||||
@ -354,7 +457,6 @@ class ExpenseController extends Controller
|
|||||||
return $sum;
|
return $sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Collection $assets
|
* @param Collection $assets
|
||||||
* @param Collection $opposing
|
* @param Collection $opposing
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
// general stuff:
|
// general stuff:
|
||||||
'close' => 'Close',
|
'close' => 'Close',
|
||||||
@ -716,6 +717,7 @@ return [
|
|||||||
'mass_edit_journals' => 'Edit a number of transactions',
|
'mass_edit_journals' => 'Edit a number of transactions',
|
||||||
'cannot_edit_other_fields' => 'You cannot mass-edit other fields than the ones here, because there is no room to show them. Please follow the link and edit them by one-by-one, if you need to edit these fields.',
|
'cannot_edit_other_fields' => 'You cannot mass-edit other fields than the ones here, because there is no room to show them. Please follow the link and edit them by one-by-one, if you need to edit these fields.',
|
||||||
'no_budget' => 'none',
|
'no_budget' => 'none',
|
||||||
|
'no_budget_squared' => '(no budget)',
|
||||||
'perm-delete-many' => 'Deleting many items in one go can be very disruptive. Please be cautious.',
|
'perm-delete-many' => 'Deleting many items in one go can be very disruptive. Please be cautious.',
|
||||||
'mass_deleted_transactions_success' => 'Deleted :amount transaction(s).',
|
'mass_deleted_transactions_success' => 'Deleted :amount transaction(s).',
|
||||||
'mass_edited_transactions_success' => 'Updated :amount transaction(s)',
|
'mass_edited_transactions_success' => 'Updated :amount transaction(s)',
|
||||||
|
31
resources/views/reports/partials/exp-budgets.twig
Normal file
31
resources/views/reports/partials/exp-budgets.twig
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<table class="table table-hover sortable">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="width:50%;" data-defaultsign="az">{{ 'budget'|_ }}</th>
|
||||||
|
<th style="width:50%;text-align: right;" data-defaultsort="disabled">{{ 'spent'|_ }}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for budgetId, entry in together %}
|
||||||
|
<tr>
|
||||||
|
<td style="width:50%;" data-value="{% if entry.budget.name|length ==0 %}{{ 'no_budget_squared'|_ }}{% else %}{{ entry.budget.name }}{% endif %}">
|
||||||
|
|
||||||
|
{% if entry.budget.name|length ==0 %}
|
||||||
|
<a href="{{ route('budgets.no-budget') }}">{{ 'no_budget_squared'|_ }}</a>
|
||||||
|
{% else %}
|
||||||
|
<a href="{{ route('budgets.show', budgetId) }}">{{ entry.budget.name }}</a>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td style="text-align: right;">
|
||||||
|
{% if entry.spent|length ==0 %}
|
||||||
|
{{ '0'|formatAmount }}
|
||||||
|
{% else %}
|
||||||
|
{% for expense in entry.spent %}
|
||||||
|
{{ formatAmountBySymbol(expense.sum, expense.currency.symbol, expense.currency.dp) }}<br />
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
@ -1,16 +1,20 @@
|
|||||||
<table class="table table-hover sortable">
|
<table class="table table-hover sortable">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th data-defaultsign="az">{{ 'category'|_ }}</th>
|
<th style="width:50%;" data-defaultsign="az">{{ 'category'|_ }}</th>
|
||||||
<th style="text-align: right;">{{ 'spent'|_ }}</th>
|
<th style="width:25%;text-align: right;" data-defaultsort="disabled">{{ 'spent'|_ }}</th>
|
||||||
<th style="text-align: right;">{{ 'earned'|_ }}</th>
|
<th style="width:25%;text-align: right;" data-defaultsort="disabled">{{ 'earned'|_ }}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for categoryId, entry in together %}
|
{% for categoryId, entry in together %}
|
||||||
<tr>
|
<tr>
|
||||||
<td data-value="{% if entry.category.name|length ==0 %}{{ 'noCategory'|_ }}{% else %}{{ entry.category.name }}{% endif %}">
|
<td style="width:50%;" data-value="{% if entry.category.name|length ==0 %}{{ 'noCategory'|_ }}{% else %}{{ entry.category.name }}{% endif %}">
|
||||||
<a href="{{ route('categories.show', categoryId) }}">{% if entry.category.name|length ==0 %}{{ 'noCategory'|_ }}{% else %}{{ entry.category.name }}{% endif %}</a>
|
{% if entry.category.name|length ==0 %}
|
||||||
|
<a href="{{ route('categories.no-category') }}">{{ 'noCategory'|_ }}</a>
|
||||||
|
{% else %}
|
||||||
|
<a href="{{ route('categories.show', categoryId) }}">{{ entry.category.name }}</a>
|
||||||
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td style="text-align: right;">
|
<td style="text-align: right;">
|
||||||
{% if entry.spent|length ==0 %}
|
{% if entry.spent|length ==0 %}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
<table class="table table-hover sortable">
|
<table class="table table-hover sortable">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th data-defaultsign="az">{{ 'name'|_ }}</th>
|
<th style="width:40%;" data-defaultsign="az">{{ 'name'|_ }}</th>
|
||||||
<th data-defaultsign="az">{{ 'period'|_ }}</th>
|
<th style="width:20%;" data-defaultsign="az">{{ 'period'|_ }}</th>
|
||||||
<th class="hidden-xs" style="text-align: right;" data-defaultsort="disabled">{{ 'spent'|_ }}</th>
|
<th class="hidden-xs" style="width:20%;text-align: right;" data-defaultsort="disabled">{{ 'spent'|_ }}</th>
|
||||||
<th class="hidden-xs" style="text-align: right;" data-defaultsort="disabled">{{ 'earned'|_ }}</th>
|
<th class="hidden-xs" style="width:20%;text-align: right;" data-defaultsort="disabled">{{ 'earned'|_ }}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
<table class="table table-hover sortable">
|
<table class="table table-hover sortable">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th data-defaultsign="az">{{ 'name'|_ }}</th>
|
<th style="width:50%;" data-defaultsign="az">{{ 'name'|_ }}</th>
|
||||||
<th class="hidden-xs" style="text-align: right;" data-defaultsort="disabled">{{ 'spent'|_ }}</th>
|
<th style="width:25%;text-align:right;" class="hidden-xs" style="text-align: right;" data-defaultsort="disabled">{{ 'spent'|_ }}</th>
|
||||||
<th class="hidden-xs" style="text-align: right;" data-defaultsort="disabled">{{ 'earned'|_ }}</th>
|
<th style="width:25%;text-align:right;" class="hidden-xs" style="text-align: right;" data-defaultsort="disabled">{{ 'earned'|_ }}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
Loading…
Reference in New Issue
Block a user