Better sum for bill view.

This commit is contained in:
James Cole 2019-08-23 21:54:47 +02:00
parent 4b45c0d0a9
commit e5e3797d9c
5 changed files with 69 additions and 84 deletions

View File

@ -38,7 +38,6 @@ use FireflyIII\User;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator; use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
use League\Fractal\Manager; use League\Fractal\Manager;
use League\Fractal\Pagination\IlluminatePaginatorAdapter; use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection; use League\Fractal\Resource\Collection as FractalCollection;
@ -141,11 +140,7 @@ class BillController extends Controller
*/ */
public function index(Request $request): JsonResponse public function index(Request $request): JsonResponse
{ {
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; $bills = $this->repository->getBills();
$paginator = $this->repository->getPaginator($pageSize);
/** @var Collection $bills */
$bills = $paginator->getCollection();
$manager = new Manager(); $manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl)); $manager->setSerializer(new JsonApiSerializer($baseUrl));

View File

@ -223,9 +223,7 @@ class CurrencyController extends Controller
/** @var BillRepositoryInterface $repository */ /** @var BillRepositoryInterface $repository */
$repository = app(BillRepositoryInterface::class); $repository = app(BillRepositoryInterface::class);
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$paginator = $repository->getPaginator($pageSize); $unfiltered = $repository->getBills();
/** @var Collection $bills */
$unfiltered = $paginator->getCollection();
// filter and paginate list: // filter and paginate list:
$collection = $unfiltered->filter( $collection = $unfiltered->filter(

View File

@ -28,6 +28,7 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Http\Requests\BillFormRequest; use FireflyIII\Http\Requests\BillFormRequest;
use FireflyIII\Models\Attachment; use FireflyIII\Models\Attachment;
use FireflyIII\Models\Bill; use FireflyIII\Models\Bill;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Bill\BillRepositoryInterface; use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use FireflyIII\TransactionRules\TransactionMatcher; use FireflyIII\TransactionRules\TransactionMatcher;
use FireflyIII\Transformers\AttachmentTransformer; use FireflyIII\Transformers\AttachmentTransformer;
@ -194,8 +195,7 @@ class BillController extends Controller
{ {
$start = session('start'); $start = session('start');
$end = session('end'); $end = session('end');
$pageSize = (int)app('preferences')->get('listPageSize', 50)->data; $unfiltered = $this->billRepository->getBills();
$paginator = $this->billRepository->getPaginator($pageSize);
$defaultCurrency = app('amount')->getDefaultCurrency(); $defaultCurrency = app('amount')->getDefaultCurrency();
$parameters = new ParameterBag(); $parameters = new ParameterBag();
$parameters->set('start', $start); $parameters->set('start', $start);
@ -206,28 +206,34 @@ class BillController extends Controller
$transformer->setParameters($parameters); $transformer->setParameters($parameters);
/** @var Collection $bills */ /** @var Collection $bills */
$bills = $paginator->getCollection()->map( $bills = $unfiltered->map(
static function (Bill $bill) use ($transformer, $defaultCurrency) { static function (Bill $bill) use ($transformer, $defaultCurrency) {
$return = $transformer->transform($bill); $return = $transformer->transform($bill);
$return['currency'] = $bill->transactionCurrency ?? $defaultCurrency; $currency = $bill->transactionCurrency ?? $defaultCurrency;
$return['currency_id'] = $currency->id;
$return['currency_name'] = $currency->name;
$return['currency_symbol'] = $currency->symbol;
$return['currency_code'] = $currency->code;
$return['currency_decimal_places'] = $currency->decimal_places;
return $return; return $return;
} }
); );
// add info about rules: // add info about rules:
$rules = $this->billRepository->getRulesForBills($paginator->getCollection()); $rules = $this->billRepository->getRulesForBills($unfiltered);
$bills = $bills->map( $bills = $bills->map(
function (array $bill) use ($rules) { static function (array $bill) use ($rules) {
$bill['rules'] = $rules[$bill['id']] ?? []; $bill['rules'] = $rules[$bill['id']] ?? [];
return $bill; return $bill;
} }
); );
$paginator->setPath(route('bills.index')); // summarise per currency:
$sums = $this->getSums($bills);
return view('bills.index', compact('bills', 'paginator')); return view('bills.index', compact('bills', 'sums'));
} }
/** /**
@ -413,4 +419,35 @@ class BillController extends Controller
return $redirect; return $redirect;
} }
/**
* @param Collection $bills
*
* @return array
*/
private function getSums(Collection $bills): array
{
$sums = [];
/** @var array $bill */
foreach ($bills as $bill) {
if (false === $bill['active']) {
continue;
}
/** @var TransactionCurrency $currency */
$currencyId = $bill['currency_id'];
$sums[$currencyId] = $sums[$currencyId] ?? [
'currency_id' => $currencyId,
'currency_code' => $bill['currency_code'],
'currency_name' => $bill['currency_name'],
'currency_symbol' => $bill['currency_symbol'],
'currency_decimal_places' => $bill['currency_decimal_places'],
'avg' => '0',
];
$avg = bcdiv(bcadd((string)$bill['amount_min'], (string)$bill['amount_max']), '2');
$sums[$currencyId]['avg'] = bcadd($sums[$currencyId]['avg'], $avg);
}
return $sums;
}
} }

View File

@ -172,9 +172,7 @@ class BillRepository implements BillRepositoryInterface
public function getBills(): Collection public function getBills(): Collection
{ {
/** @var Collection $set */ /** @var Collection $set */
$set = $this->user->bills()->orderBy('active', 'DESC')->orderBy('name', 'ASC')->get(); return $this->user->bills()->orderBy('active', 'DESC')->orderBy('name', 'ASC')->get();
return $set;
} }
/** /**

View File

@ -14,18 +14,7 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% set sum_min =0 %}
{% set sum_max =0 %}
{% set expected_total = 0 %}
{% set count = 0 %}
{% for entry in bills %} {% for entry in bills %}
{% if entry.active %}
{% set count = count + 1 %}
{% set sum_min = sum_min + entry.amount_min %}
{% set sum_max = sum_max + entry.amount_max %}
{% set expected_total = expected_total + ((entry.amount_min + entry.amount_max) / 2) %}
{% endif %}
<tr{% if not entry.active %} data-disablesort="true"{% endif %}> <tr{% if not entry.active %} data-disablesort="true"{% endif %}>
<td class="hidden-sm hidden-xs"> <td class="hidden-sm hidden-xs">
<div class="btn-group btn-group-xs edit_tr_buttons"><a href="{{ route('bills.edit',entry.id) }}" class="btn btn-default btn-xs"><i <div class="btn-group btn-group-xs edit_tr_buttons"><a href="{{ route('bills.edit',entry.id) }}" class="btn btn-default btn-xs"><i
@ -58,8 +47,10 @@
{% endif %} {% endif %}
</td> </td>
<td data-value="{{ entry.amount_min }}" style="text-align: right;"> <td data-value="{{ entry.amount_min }}" style="text-align: right;">
<span style="margin-right:5px;"> <span style="margin-right:5px;"
~ {{ formatAmountByCurrency(entry.currency, (entry.amount_max + entry.amount_min)/2) }} title="{{ formatAmountBySymbol(entry.amount_min, entry.currency_symbol, entry.currency_decimal_places, false)|escape }} -- {{ formatAmountBySymbol(entry.amount_max, entry.currency_symbol, entry.currency_decimal_places, false)|escape }}"
>
~ {{ formatAmountBySymbol((entry.amount_max + entry.amount_min)/2, entry.currency_symbol, entry.currency_decimal_places) }}
</span> </span>
</td> </td>
@ -125,53 +116,19 @@
{% endfor %} {% endfor %}
</tbody> </tbody>
<tfoot> <tfoot>
{% for sum in sums %}
<tr> <tr>
<td style="text-align:right;" colspan="3">{{ 'sum'|_ }} ({{ 'active_bills_only'|_ }})</td> <td style="text-align:right;" colspan="3">
<td style="text-align:right;" colspan="1"> {{ 'sum'|_ }} ({{ sum.currency_name }}) ({{ 'active_bills_only'|_ }})<br />
<span style="margin-right:5px;">
{{ formatAmountBySymbol(sum_min,'¤') }}
</span>
</td> </td>
<td style="text-align:right;" colspan="1"> <td style="text-align:right;" colspan="1">
<span style="margin-right:5px;"> <span style="margin-right:5px;">
{{ formatAmountBySymbol(sum_max,'¤') }} {{ formatAmountBySymbol(sum.avg, sum.currency_symbol, sum.currency_decimal_places) }}
</span>
</td>
<td colspan="5">&nbsp;</td>
</tr>
{# calculate total#}
{% if count > 0 %}
{% set avg_min = (sum_min / count) %}
{% set avg_max = (sum_max / count) %}
{% else %}
{% set avg_min = 0 %}
{% set avg_max = 0 %}
{% endif %}
<tr>
<td style="text-align:right;" colspan="3">{{ 'average_per_bill'|_ }} ({{ 'active_bills_only'|_ }})</td>
<td style="text-align:right;" colspan="1">
<span style="margin-right:5px;">
{{ formatAmountBySymbol(avg_min,'¤') }}
</span>
</td>
<td style="text-align:right;" colspan="1">
<span style="margin-right:5px;">
{{ formatAmountBySymbol(avg_max,'¤') }}
</span>
</td>
<td colspan="6">&nbsp;</td>
</tr>
<tr>
<td style="text-align:right;" colspan="3">{{ 'expected_total'|_ }} ({{ 'active_bills_only'|_ }})</td>
<td style="text-align:right;" colspan="1">
<span style="margin-right:5px;">
~ {{ formatAmountBySymbol(expected_total,'¤') }}
</span> </span>
</td> </td>
<td colspan="6">&nbsp;</td> <td colspan="6">&nbsp;</td>
</tr> </tr>
{% endfor %}
</tfoot> </tfoot>
</table> </table>
<div style="padding-left:8px;"> <div style="padding-left:8px;">