Make budget tables multi-currency

This commit is contained in:
James Cole 2019-08-27 10:25:23 +02:00
parent 33d0b8ca22
commit 7eb9086a28
5 changed files with 54 additions and 39 deletions

View File

@ -100,7 +100,8 @@ class BudgetController extends Controller
$repository = app(BudgetRepositoryInterface::class); $repository = app(BudgetRepositoryInterface::class);
$budgets = $repository->getBudgets(); $budgets = $repository->getBudgets();
$data = $repository->getBudgetPeriodReport($budgets, $accounts, $start, $end); $data = $repository->getBudgetPeriodReport($budgets, $accounts, $start, $end);
$data[0] = $repository->getNoBudgetPeriodReport($accounts, $start, $end); // append report data for "no budget" $noBudget = $repository->getNoBudgetPeriodReport($accounts, $start, $end); // append report data for "no budget"
$data = array_merge($data, $noBudget);
$report = $this->filterPeriodReport($data); $report = $this->filterPeriodReport($data);
// depending on the carbon format (a reliable way to determine the general date difference) // depending on the carbon format (a reliable way to determine the general date difference)
@ -114,7 +115,7 @@ class BudgetController extends Controller
$start->startOfMonth(); $start->startOfMonth();
} }
$periods = app('navigation')->listOfPeriods($start, $end); $periods = app('navigation')->listOfPeriods($start, $end);
try { try {
$result = view('reports.partials.budget-period', compact('report', 'periods'))->render(); $result = view('reports.partials.budget-period', compact('report', 'periods'))->render();
// @codeCoverageIgnoreStart // @codeCoverageIgnoreStart

View File

@ -182,10 +182,8 @@ class BillRepository implements BillRepositoryInterface
*/ */
public function getBillsForAccounts(Collection $accounts): Collection public function getBillsForAccounts(Collection $accounts): Collection
{ {
$fields = ['bills.id', 'bills.created_at', 'bills.updated_at', 'bills.deleted_at', 'bills.user_id', 'bills.name', 'bills.match', 'bills.amount_min', $fields = ['bills.id', 'bills.created_at', 'bills.updated_at', 'bills.deleted_at', 'bills.user_id', 'bills.name', 'bills.amount_min',
'bills.amount_max', 'bills.date', 'bills.transaction_currency_id', 'bills.repeat_freq', 'bills.skip', 'bills.automatch', 'bills.active', 'bills.amount_max', 'bills.date', 'bills.transaction_currency_id', 'bills.repeat_freq', 'bills.skip', 'bills.automatch', 'bills.active',];
'bills.name_encrypted',
'bills.match_encrypted',];
$ids = $accounts->pluck('id')->toArray(); $ids = $accounts->pluck('id')->toArray();
$set = $this->user->bills() $set = $this->user->bills()
->leftJoin( ->leftJoin(
@ -206,7 +204,6 @@ class BillRepository implements BillRepositoryInterface
->orderBy('bills.name', 'ASC') ->orderBy('bills.name', 'ASC')
->groupBy($fields) ->groupBy($fields)
->get($fields); ->get($fields);
return $set; return $set;
} }
@ -457,7 +454,7 @@ class BillRepository implements BillRepositoryInterface
$currentStart = clone $nextExpectedMatch; $currentStart = clone $nextExpectedMatch;
} }
$simple = $set->each( $simple = $set->each(
function (Carbon $date) { static function (Carbon $date) {
return $date->format('Y-m-d'); return $date->format('Y-m-d');
} }
); );

View File

@ -563,17 +563,8 @@ class BudgetRepository implements BudgetRepositoryInterface
public function getBudgetPeriodReport(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end): array public function getBudgetPeriodReport(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end): array
{ {
$carbonFormat = Navigation::preferredCarbonFormat($start, $end); $carbonFormat = Navigation::preferredCarbonFormat($start, $end);
$data = [];
$data = [];
// prep data array:
/** @var Budget $budget */
foreach ($budgets as $budget) {
$data[$budget->id] = [
'name' => $budget->name,
'sum' => '0',
'entries' => [],
];
}
// get all transactions: // get all transactions:
/** @var GroupCollectorInterface $collector */ /** @var GroupCollectorInterface $collector */
@ -585,9 +576,25 @@ class BudgetRepository implements BudgetRepositoryInterface
// loop transactions: // loop transactions:
/** @var array $journal */ /** @var array $journal */
foreach ($journals as $journal) { foreach ($journals as $journal) {
$budgetId = (int)$journal['budget_id']; // prep data array for currency:
$date = $journal['date']->format($carbonFormat); $budgetId = (int)$journal['budget_id'];
$data[$budgetId]['entries'][$date] = bcadd($data[$budgetId]['entries'][$date] ?? '0', $journal['amount']); $budgetName = $journal['budget_name'];
$currencyId = (int)$journal['currency_id'];
$key = sprintf('%d-%d', $budgetId, $currencyId);
$data[$key] = $data[$key] ?? [
'id' => $budgetId,
'name' => sprintf('%s (%s)', $budgetName, $journal['currency_name']),
'sum' => '0',
'currency_id' => $currencyId,
'currency_code' => $journal['currency_code'],
'currency_name' => $journal['currency_name'],
'currency_symbol' => $journal['currency_symbol'],
'currency_decimal_places' => $journal['currency_decimal_places'],
'entries' => [],
];
$date = $journal['date']->format($carbonFormat);
$data[$key]['entries'][$date] = bcadd($data[$budgetId]['entries'][$date] ?? '0', $journal['amount']);
} }
return $data; return $data;
@ -647,23 +654,32 @@ class BudgetRepository implements BudgetRepositoryInterface
$collector->setTypes([TransactionType::WITHDRAWAL]); $collector->setTypes([TransactionType::WITHDRAWAL]);
$collector->withoutBudget(); $collector->withoutBudget();
$journals = $collector->getExtractedJournals(); $journals = $collector->getExtractedJournals();
$result = [ $data = [];
'entries' => [],
'name' => (string)trans('firefly.no_budget'),
'sum' => '0',
];
/** @var array $journal */ /** @var array $journal */
foreach ($journals as $journal) { foreach ($journals as $journal) {
$date = $journal['date']->format($carbonFormat); $currencyId = (int)$journal['currency_id'];
if (!isset($result['entries'][$date])) { $data[$currencyId] = $data[$currencyId] ?? [
$result['entries'][$date] = '0'; 'id' => 0,
'name' => sprintf('%s (%s)', trans('firefly.no_budget'), $journal['currency_name']),
'sum' => '0',
'currency_id' => $currencyId,
'currency_code' => $journal['currency_code'],
'currency_name' => $journal['currency_name'],
'currency_symbol' => $journal['currency_symbol'],
'currency_decimal_places' => $journal['currency_decimal_places'],
'entries' => [],
];
$date = $journal['date']->format($carbonFormat);
if (!isset($data[$currencyId]['entries'][$date])) {
$data[$currencyId]['entries'][$date] = '0';
} }
$result['entries'][$date] = bcadd($result['entries'][$date], $journal['amount']); $data[$currencyId]['entries'][$date] = bcadd($data[$currencyId]['entries'][$date], $journal['amount']);
} }
return $result; return $data;
} }
/** /**

View File

@ -10,7 +10,7 @@
</thead> </thead>
<tbody> <tbody>
{% for bill in report.bills %} {% for bill in report.bills %}
{% if bill.expected_dates|length > 0 and bill.paid_moments|length > 0 and bill.active %} {% if (bill.expected_dates|length > 0 or bill.paid_moments|length > 0) and bill.active %}
<tr> <tr>
<td> <td>
<a href="{{ route('bills.show',bill.id) }}">{{ bill.name }}</a> <a href="{{ route('bills.show',bill.id) }}">{{ bill.name }}</a>

View File

@ -9,32 +9,33 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for id, info in report %} {% for key, info in report %}
<tr> <tr>
<td> <td>
{% if id != 0 %} {% if info.id != 0 %}
<a class="btn btn-default btn-xs" href="{{ route('budgets.show', [id]) }}"><i class="fa fa-external-link"></i></a> <a class="btn btn-default btn-xs" href="{{ route('budgets.show', [info.id]) }}"><i class="fa fa-external-link"></i></a>
{% else %} {% else %}
<a class="btn btn-default btn-xs" href="{{ route('budgets.no-budget') }}"><i class="fa fa-external-link"></i></a> <a class="btn btn-default btn-xs" href="{{ route('budgets.no-budget') }}"><i class="fa fa-external-link"></i></a>
{% endif %} {% endif %}
</td> </td>
<td data-value="{{ info.name }}"> <td data-value="{{ info.name }}">
<a title="{{ info.name }}" href="#" data-budget="{{ id }}" class="budget-chart-activate">{{ info.name }}</a> <a title="{{ info.name }}" href="#" data-budget="{{ info.id }}" data-currency="{{ info.currency_id }}" class="budget-chart-activate">{{ info.name }}</a>
</td> </td>
{% for key, period in periods %} {% for key, period in periods %}
{% if(info.entries[key]) %} {% if(info.entries[key]) %}
<td data-value="{{ info.entries[key] }}" style="text-align: right;"> <td data-value="{{ info.entries[key] }}" style="text-align: right;">
{{ info.entries[key]|formatAmount }} {{ formatAmountBySymbol(info.entries[key], info.currency_symbol, info.currency_decimal_places) }}
</td> </td>
{% else %} {% else %}
<td data-value="0" style="text-align: right;"> <td data-value="0" style="text-align: right;">
{{ 0|formatAmount }} {{ formatAmountBySymbol(0, info.currency_symbol, info.currency_decimal_places) }}
</td> </td>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
<td data-value="{{ info.sum }}" style="text-align: right;"> <td data-value="{{ info.sum }}" style="text-align: right;">
{{ info.sum|formatAmount }} {{ formatAmountBySymbol(info.sum, info.currency_symbol, info.currency_decimal_places) }}
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}