mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-30 02:26:58 +00:00
Fix #9650
This commit is contained in:
@@ -57,7 +57,7 @@ class IndexController extends Controller
|
|||||||
|
|
||||||
$this->middleware(
|
$this->middleware(
|
||||||
function ($request, $next) {
|
function ($request, $next) {
|
||||||
app('view')->share('title', (string) trans('firefly.bills'));
|
app('view')->share('title', (string)trans('firefly.bills'));
|
||||||
app('view')->share('mainTitleIcon', 'fa-calendar-o');
|
app('view')->share('mainTitleIcon', 'fa-calendar-o');
|
||||||
$this->repository = app(BillRepositoryInterface::class);
|
$this->repository = app(BillRepositoryInterface::class);
|
||||||
|
|
||||||
@@ -79,7 +79,6 @@ class IndexController extends Controller
|
|||||||
$total = $collection->count();
|
$total = $collection->count();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$parameters = new ParameterBag();
|
$parameters = new ParameterBag();
|
||||||
// sub one day from temp start so the last paid date is one day before it should be.
|
// sub one day from temp start so the last paid date is one day before it should be.
|
||||||
$tempStart = clone $start;
|
$tempStart = clone $start;
|
||||||
@@ -112,7 +111,7 @@ class IndexController extends Controller
|
|||||||
$bills = [
|
$bills = [
|
||||||
0 => [ // the index is the order, not the ID.
|
0 => [ // the index is the order, not the ID.
|
||||||
'object_group_id' => 0,
|
'object_group_id' => 0,
|
||||||
'object_group_title' => (string) trans('firefly.default_group_title_name'),
|
'object_group_title' => (string)trans('firefly.default_group_title_name'),
|
||||||
'bills' => [],
|
'bills' => [],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
@@ -120,7 +119,7 @@ class IndexController extends Controller
|
|||||||
/** @var Bill $bill */
|
/** @var Bill $bill */
|
||||||
foreach ($collection as $bill) {
|
foreach ($collection as $bill) {
|
||||||
$array = $transformer->transform($bill);
|
$array = $transformer->transform($bill);
|
||||||
$groupOrder = (int) $array['object_group_order'];
|
$groupOrder = (int)$array['object_group_order'];
|
||||||
// make group array if necessary:
|
// make group array if necessary:
|
||||||
$bills[$groupOrder] ??= [
|
$bills[$groupOrder] ??= [
|
||||||
'object_group_id' => $array['object_group_id'],
|
'object_group_id' => $array['object_group_id'],
|
||||||
@@ -173,16 +172,28 @@ class IndexController extends Controller
|
|||||||
'currency_symbol' => $bill['currency_symbol'],
|
'currency_symbol' => $bill['currency_symbol'],
|
||||||
'currency_decimal_places' => $bill['currency_decimal_places'],
|
'currency_decimal_places' => $bill['currency_decimal_places'],
|
||||||
'avg' => '0',
|
'avg' => '0',
|
||||||
|
'total_left_to_pay' => '0',
|
||||||
'period' => $range,
|
'period' => $range,
|
||||||
'per_period' => '0',
|
'per_period' => '0',
|
||||||
];
|
];
|
||||||
|
|
||||||
// only fill in avg when bill is active.
|
// only fill in avg when bill is active.
|
||||||
if (null !== $bill['next_expected_match']) {
|
if (null !== $bill['next_expected_match']) {
|
||||||
$avg = bcdiv(bcadd((string) $bill['amount_min'], (string) $bill['amount_max']), '2');
|
$avg = bcdiv(bcadd((string)$bill['amount_min'], (string)$bill['amount_max']), '2');
|
||||||
$avg = bcmul($avg, (string) count($bill['pay_dates']));
|
$avg = bcmul($avg, (string)count($bill['pay_dates']));
|
||||||
$sums[$groupOrder][$currencyId]['avg'] = bcadd($sums[$groupOrder][$currencyId]['avg'], $avg);
|
$sums[$groupOrder][$currencyId]['avg'] = bcadd($sums[$groupOrder][$currencyId]['avg'], $avg);
|
||||||
}
|
}
|
||||||
|
// only fill in total_left_to_pay when bill is not yet paid.
|
||||||
|
if (count($bill['paid_dates']) < count($bill['pay_dates'])) {
|
||||||
|
$count = count($bill['pay_dates']) - count($bill['paid_dates']);
|
||||||
|
if ($count > 0) {
|
||||||
|
$avg = bcdiv(bcadd((string)$bill['amount_min'], (string)$bill['amount_max']), '2');
|
||||||
|
$avg = bcmul($avg, (string)$count);
|
||||||
|
$sums[$groupOrder][$currencyId]['total_left_to_pay'] = bcadd($sums[$groupOrder][$currencyId]['total_left_to_pay'], $avg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// fill in per period regardless:
|
// fill in per period regardless:
|
||||||
$sums[$groupOrder][$currencyId]['per_period'] = bcadd($sums[$groupOrder][$currencyId]['per_period'], $this->amountPerPeriod($bill, $range));
|
$sums[$groupOrder][$currencyId]['per_period'] = bcadd($sums[$groupOrder][$currencyId]['per_period'], $this->amountPerPeriod($bill, $range));
|
||||||
}
|
}
|
||||||
@@ -193,7 +204,7 @@ class IndexController extends Controller
|
|||||||
|
|
||||||
private function amountPerPeriod(array $bill, string $range): string
|
private function amountPerPeriod(array $bill, string $range): string
|
||||||
{
|
{
|
||||||
$avg = bcdiv(bcadd((string) $bill['amount_min'], (string) $bill['amount_max']), '2');
|
$avg = bcdiv(bcadd((string)$bill['amount_min'], (string)$bill['amount_max']), '2');
|
||||||
|
|
||||||
app('log')->debug(sprintf('Amount per period for bill #%d "%s"', $bill['id'], $bill['name']));
|
app('log')->debug(sprintf('Amount per period for bill #%d "%s"', $bill['id'], $bill['name']));
|
||||||
app('log')->debug(sprintf('Average is %s', $avg));
|
app('log')->debug(sprintf('Average is %s', $avg));
|
||||||
@@ -206,8 +217,8 @@ class IndexController extends Controller
|
|||||||
'weekly' => '52.17',
|
'weekly' => '52.17',
|
||||||
'daily' => '365.24',
|
'daily' => '365.24',
|
||||||
];
|
];
|
||||||
$yearAmount = bcmul($avg, bcdiv($multiplies[$bill['repeat_freq']], (string) ($bill['skip'] + 1)));
|
$yearAmount = bcmul($avg, bcdiv($multiplies[$bill['repeat_freq']], (string)($bill['skip'] + 1)));
|
||||||
app('log')->debug(sprintf('Amount per year is %s (%s * %s / %s)', $yearAmount, $avg, $multiplies[$bill['repeat_freq']], (string) ($bill['skip'] + 1)));
|
app('log')->debug(sprintf('Amount per year is %s (%s * %s / %s)', $yearAmount, $avg, $multiplies[$bill['repeat_freq']], (string)($bill['skip'] + 1)));
|
||||||
|
|
||||||
// per period:
|
// per period:
|
||||||
$division = [
|
$division = [
|
||||||
@@ -258,8 +269,8 @@ class IndexController extends Controller
|
|||||||
'period' => $entry['period'],
|
'period' => $entry['period'],
|
||||||
'per_period' => '0',
|
'per_period' => '0',
|
||||||
];
|
];
|
||||||
$totals[$currencyId]['avg'] = bcadd($totals[$currencyId]['avg'], (string) $entry['avg']);
|
$totals[$currencyId]['avg'] = bcadd($totals[$currencyId]['avg'], (string)$entry['avg']);
|
||||||
$totals[$currencyId]['per_period'] = bcadd($totals[$currencyId]['per_period'], (string) $entry['per_period']);
|
$totals[$currencyId]['per_period'] = bcadd($totals[$currencyId]['per_period'], (string)$entry['per_period']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,8 +282,8 @@ class IndexController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function setOrder(Request $request, Bill $bill): JsonResponse
|
public function setOrder(Request $request, Bill $bill): JsonResponse
|
||||||
{
|
{
|
||||||
$objectGroupTitle = (string) $request->get('objectGroupTitle');
|
$objectGroupTitle = (string)$request->get('objectGroupTitle');
|
||||||
$newOrder = (int) $request->get('order');
|
$newOrder = (int)$request->get('order');
|
||||||
$this->repository->setOrder($bill, $newOrder);
|
$this->repository->setOrder($bill, $newOrder);
|
||||||
if ('' !== $objectGroupTitle) {
|
if ('' !== $objectGroupTitle) {
|
||||||
$this->repository->setObjectGroup($bill, $objectGroupTitle);
|
$this->repository->setObjectGroup($bill, $objectGroupTitle);
|
||||||
|
@@ -56,6 +56,7 @@ class SubscriptionEnrichment implements EnrichmentInterface
|
|||||||
$this->collectPaidDates();
|
$this->collectPaidDates();
|
||||||
$this->collectPayDates();
|
$this->collectPayDates();
|
||||||
|
|
||||||
|
|
||||||
// TODO clean me up.
|
// TODO clean me up.
|
||||||
|
|
||||||
$notes = $this->notes;
|
$notes = $this->notes;
|
||||||
|
@@ -110,8 +110,8 @@ class BillDateCalculator
|
|||||||
$currentStart = clone $nextExpectedMatch;
|
$currentStart = clone $nextExpectedMatch;
|
||||||
|
|
||||||
++$loop;
|
++$loop;
|
||||||
if ($loop > 12) {
|
if ($loop > 31) {
|
||||||
Log::debug('Loop is more than 12, so we break.');
|
Log::debug('Loop is more than 31, so we break.');
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -1864,6 +1864,7 @@ return [
|
|||||||
'remove_budgeted_amount' => 'Remove budgeted amount in :currency',
|
'remove_budgeted_amount' => 'Remove budgeted amount in :currency',
|
||||||
|
|
||||||
// bills:
|
// bills:
|
||||||
|
'left_to_pay_active_bills' => 'active, expected and not yet paid subscriptions',
|
||||||
'left_to_pay_lc' => 'left to pay',
|
'left_to_pay_lc' => 'left to pay',
|
||||||
'less_than_expected' => 'less than expected',
|
'less_than_expected' => 'less than expected',
|
||||||
'more_than_expected' => 'more than expected',
|
'more_than_expected' => 'more than expected',
|
||||||
|
@@ -158,8 +158,8 @@
|
|||||||
<td style="width:33%;">{{ 'amount'|_ }}</td>
|
<td style="width:33%;">{{ 'amount'|_ }}</td>
|
||||||
<td>
|
<td>
|
||||||
{{ formatAmountBySymbol(limit.amount, limit.transactionCurrency.symbol, limit.transactionCurrency.decimal_places) }}
|
{{ formatAmountBySymbol(limit.amount, limit.transactionCurrency.symbol, limit.transactionCurrency.decimal_places) }}
|
||||||
{% if convertToPrimary and 0 != limit.pc_amount %}
|
{% if convertToPrimary and null != limit.native_amount %}
|
||||||
({{ formatAmountBySymbol(limit.pc_amount, primaryCurrency.symbol, primaryCurrency.decimal_places) }})
|
({{ formatAmountBySymbol(limit.native_amount, primaryCurrency.symbol, primaryCurrency.decimal_places) }})
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@@ -189,6 +189,21 @@
|
|||||||
<td class="hidden-sm hidden-xs"> </td><!-- repeats -->
|
<td class="hidden-sm hidden-xs"> </td><!-- repeats -->
|
||||||
</tr>
|
</tr>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if '0' != sum.total_left_to_pay %}
|
||||||
|
<tr>
|
||||||
|
<td class="hidden-sm hidden-xs"> </td> <!-- handle -->
|
||||||
|
<td class="hidden-sm hidden-xs"> </td> <!-- buttons -->
|
||||||
|
<td colspan="2" style="text-align: right;"> <!-- title -->
|
||||||
|
<small>{{ 'sum'|_ }} ({{ sum.currency_name }}) ({{ 'left_to_pay_active_bills'|_ }})</small>
|
||||||
|
</td>
|
||||||
|
<td style="text-align: right;"> <!-- amount -->
|
||||||
|
{{ formatAmountBySymbol(sum.total_left_to_pay, sum.currency_symbol, sum.currency_decimal_places) }}
|
||||||
|
</td>
|
||||||
|
<td> </td> <!-- paid in period -->
|
||||||
|
<td class="hidden-sm hidden-xs"> </td> <!-- next expected match -->
|
||||||
|
<td class="hidden-sm hidden-xs"> </td><!-- repeats -->
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
{% if '0' != sum.per_period %}
|
{% if '0' != sum.per_period %}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="hidden-sm hidden-xs"> </td> <!-- handle -->
|
<td class="hidden-sm hidden-xs"> </td> <!-- handle -->
|
||||||
|
Reference in New Issue
Block a user