Some fixes for bills.

This commit is contained in:
James Cole
2016-10-23 14:56:05 +02:00
parent e092515dff
commit 78deb1420d
6 changed files with 70 additions and 49 deletions

View File

@@ -137,23 +137,15 @@ class BillController extends Controller
$bills = $repository->getBills(); $bills = $repository->getBills();
$bills->each( $bills->each(
function (Bill $bill) use ($repository, $start, $end) { function (Bill $bill) use ($repository, $start, $end) {
$bill->nextExpectedMatch = $repository->nextExpectedMatch($bill, new Carbon);
$bill->lastFoundMatch = $repository->lastFoundMatch($bill); // paid in this period?
$journals = $repository->getJournalsInRange($bill, $start, $end); $bill->paidDates = $repository->getPaidDatesInRange($bill, $start, $end);
// loop journals, find average: $bill->payDates = $repository->getPayDatesInRange($bill, $start, $end);
$average = '0'; $lastDate = clone $start;
$count = $journals->count(); if ($bill->paidDates->count() >= $bill->payDates->count()) {
if ($count > 0) { $lastDate = $end;
$sum = '0';
foreach ($journals as $journal) {
$sum = bcadd($sum, TransactionJournal::amountPositive($journal));
}
$average = bcdiv($sum, strval($count));
} }
$bill->nextExpectedMatch = $repository->nextExpectedMatch($bill, $lastDate);
$bill->lastPaidAmount = $average;
$bill->paidInPeriod = ($start <= $bill->lastFoundMatch) && ($end >= $bill->lastFoundMatch);
} }
); );

View File

@@ -326,11 +326,11 @@ class BillRepository implements BillRepositoryInterface
} }
/** /**
* @param $bill * @param Bill $bill
* *
* @return string * @return string
*/ */
public function getOverallAverage($bill): string public function getOverallAverage(Bill $bill): string
{ {
$journals = $bill->transactionJournals()->get(); $journals = $bill->transactionJournals()->get();
$sum = '0'; $sum = '0';
@@ -347,6 +347,21 @@ class BillRepository implements BillRepositoryInterface
return $avg; return $avg;
} }
/**
* @param Bill $bill
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function getPaidDatesInRange(Bill $bill, Carbon $start, Carbon $end): Collection
{
$dates = $bill->transactionJournals()->before($end)->after($start)->get(['transaction_journals.date'])->pluck('date');
return $dates;
}
/** /**
* Between start and end, tells you on which date(s) the bill is expected to hit. * Between start and end, tells you on which date(s) the bill is expected to hit.
* *

View File

@@ -125,11 +125,20 @@ interface BillRepositoryInterface
public function getJournalsInRange(Bill $bill, Carbon $start, Carbon $end): Collection; public function getJournalsInRange(Bill $bill, Carbon $start, Carbon $end): Collection;
/** /**
* @param $bill * @param Bill $bill
* *
* @return string * @return string
*/ */
public function getOverallAverage($bill): string; public function getOverallAverage(Bill $bill): string;
/**
* @param Bill $bill
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function getPaidDatesInRange(Bill $bill, Carbon $start, Carbon $end): Collection;
/** /**
* Between start and end, tells you on which date(s) the bill is expected to hit. * Between start and end, tells you on which date(s) the bill is expected to hit.

View File

@@ -427,7 +427,8 @@ return [
'rescanned_bill' => 'Rescanned everything.', 'rescanned_bill' => 'Rescanned everything.',
'average_bill_amount_year' => 'Average bill amount (:year)', 'average_bill_amount_year' => 'Average bill amount (:year)',
'average_bill_amount_overall' => 'Average bill amount (overall)', 'average_bill_amount_overall' => 'Average bill amount (overall)',
'not_or_not_yet' => 'Not (yet)',
'not_expected_period' => 'Not expected this period',
// accounts: // accounts:
'details_for_asset' => 'Details for asset account ":name"', 'details_for_asset' => 'Details for asset account ":name"',
'details_for_expense' => 'Details for expense account ":name"', 'details_for_expense' => 'Details for expense account ":name"',

View File

@@ -33,7 +33,7 @@ return [
'split_number' => 'Split #', 'split_number' => 'Split #',
'destination' => 'Destination', 'destination' => 'Destination',
'source' => 'Source', 'source' => 'Source',
'expectedMatch' => 'Expected match', 'next_expected_match' => 'Next expected match',
'automatch' => 'Auto match?', 'automatch' => 'Auto match?',
'repeat_freq' => 'Repeats', 'repeat_freq' => 'Repeats',
'description' => 'Description', 'description' => 'Description',

View File

@@ -5,8 +5,8 @@
<th>{{ trans('list.name') }}</th> <th>{{ trans('list.name') }}</th>
<th class="hidden-sm hidden-xs">{{ trans('list.matchesOn') }}</th> <th class="hidden-sm hidden-xs">{{ trans('list.matchesOn') }}</th>
<th colspan="2">{{ trans('list.matchingAmount') }}</th> <th colspan="2">{{ trans('list.matchingAmount') }}</th>
<th class="hidden-sm hidden-xs">{{ trans('list.paid_current_period') }}</th> <th class="hidden-sm hidden-xs" data-defaultsort="disabled">{{ trans('list.paid_current_period') }}</th>
<th class="hidden-sm hidden-xs">{{ trans('list.next_expected_match') }}</th> <th class="hidden-sm hidden-xs" data-defaultsort="disabled">{{ trans('list.next_expected_match') }}</th>
<th class="hidden-sm hidden-xs">{{ trans('list.active') }}</th> <th class="hidden-sm hidden-xs">{{ trans('list.active') }}</th>
<th class="hidden-sm hidden-xs">{{ trans('list.automatch') }}</th> <th class="hidden-sm hidden-xs">{{ trans('list.automatch') }}</th>
<th class="hidden-sm hidden-xs">{{ trans('list.repeat_freq') }}</th> <th class="hidden-sm hidden-xs">{{ trans('list.repeat_freq') }}</th>
@@ -35,37 +35,41 @@
<td data-value="{{ entry.amount_max }}"> <td data-value="{{ entry.amount_max }}">
{{ entry.amount_max|formatAmount }} {{ entry.amount_max|formatAmount }}
</td> </td>
{% if not entry.lastFoundMatch.isFuture %}
<td class="hidden-sm hidden-xs {% if entry.paidDates.count() == 0 and entry.payDates.count() == 0 and entry.active %}
{% if entry.active %} <td class="text-muted">
{% if entry.paidInPeriod %} {{ 'not_expected_period'|_ }}
bg-success
{% else %}
bg-danger
{% endif %}
{% endif %}
" data-value="{{ entry.lastFoundMatch.format('U') }}">
{{ entry.lastFoundMatch.formatLocalized(monthAndDayFormat) }}
{% if entry.active and entry.paidInPeriod %}
({{ entry.lastPaidAmount|formatAmountPlain }})
{% endif %}
</td> </td>
{% else %} <td class=" hidden-sm hidden-xs">
<td class="hidden-sm hidden-xs" data-value="0"> {{ entry.nextExpectedMatch.formatLocalized(monthAndDayFormat) }}
<em>{{ 'unknown'|_ }}</em>
</td> </td>
{% endif %} {% endif %}
{% if entry.paidDates.count() == 0 and entry.payDates.count() > 0 and entry.active %}
{% if entry.nextExpectedMatch.year == 1900 %} <td class="text-danger">
<td class="hidden-sm hidden-xs" data-value="0"> {{ 'not_or_not_yet'|_ }}
<em>{{ 'unknown'|_ }}</em>
</td> </td>
{% else %} <td class=" hidden-sm hidden-xs">
<td class="hidden-sm hidden-xs" data-value="{{ entry.nextExpectedMatch.format('U') }}"> {{ entry.nextExpectedMatch.formatLocalized(monthAndDayFormat) }}
~ {{ entry.nextExpectedMatch.formatLocalized(monthAndDayFormat) }} </td>
{% endif %}
{% if entry.paidDates.count() == entry.payDates.count() and entry.payDates.count() > 0 and entry.active %}
<td class="text-success">
{% for date in entry.paidDates %}
{{ date.formatLocalized(monthAndDayFormat) }}<br/>
{% endfor %}
</td>
<td class=" hidden-sm hidden-xs">
{{ entry.nextExpectedMatch.formatLocalized(monthAndDayFormat) }}
</td>
{% endif %}
{% if not entry.active %}
<td class="text-muted">
~
</td>
<td class="text-muted hidden-sm hidden-xs">
~
</td> </td>
{% endif %} {% endif %}
<td class="hidden-sm hidden-xs" data-value="{{ entry.active }}"> <td class="hidden-sm hidden-xs" data-value="{{ entry.active }}">
{% if entry.active %} {% if entry.active %}
<i class="fa fa-fw fa-check"></i> <i class="fa fa-fw fa-check"></i>