2016-10-26 09:46:43 -05:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* CategoryController.php
|
2017-10-21 01:40:00 -05:00
|
|
|
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
2016-10-26 09:46:43 -05:00
|
|
|
*
|
2017-10-21 01:40:00 -05:00
|
|
|
* This file is part of Firefly III.
|
2016-10-26 09:46:43 -05:00
|
|
|
*
|
2017-10-21 01:40:00 -05:00
|
|
|
* Firefly III is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* Firefly III is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2017-12-17 07:41:58 -06:00
|
|
|
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
2016-10-26 09:46:43 -05:00
|
|
|
*/
|
2017-04-09 00:44:22 -05:00
|
|
|
declare(strict_types=1);
|
2016-10-26 09:46:43 -05:00
|
|
|
|
|
|
|
namespace FireflyIII\Http\Controllers\Report;
|
|
|
|
|
|
|
|
use Carbon\Carbon;
|
|
|
|
use FireflyIII\Http\Controllers\Controller;
|
2016-12-03 13:38:13 -06:00
|
|
|
use FireflyIII\Models\Category;
|
|
|
|
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
2019-08-27 03:52:07 -05:00
|
|
|
use FireflyIII\Repositories\Category\NoCategoryRepositoryInterface;
|
|
|
|
use FireflyIII\Repositories\Category\OperationsRepositoryInterface;
|
2016-10-26 09:46:43 -05:00
|
|
|
use FireflyIII\Support\CacheProperties;
|
2018-08-10 23:39:29 -05:00
|
|
|
use FireflyIII\Support\Http\Controllers\BasicDataSupport;
|
2016-10-26 09:46:43 -05:00
|
|
|
use Illuminate\Support\Collection;
|
2018-07-20 07:34:56 -05:00
|
|
|
use Log;
|
|
|
|
use Throwable;
|
2016-10-26 09:46:43 -05:00
|
|
|
|
|
|
|
/**
|
2017-11-15 05:25:49 -06:00
|
|
|
* Class CategoryController.
|
2016-10-26 09:46:43 -05:00
|
|
|
*/
|
|
|
|
class CategoryController extends Controller
|
|
|
|
{
|
2018-08-10 23:39:29 -05:00
|
|
|
use BasicDataSupport;
|
2018-07-08 05:08:53 -05:00
|
|
|
|
2016-12-03 13:38:13 -06:00
|
|
|
/**
|
2018-07-21 01:55:32 -05:00
|
|
|
* Show overview of expenses in category.
|
|
|
|
*
|
2016-12-06 00:48:41 -06:00
|
|
|
* @param Collection $accounts
|
2016-12-03 13:38:13 -06:00
|
|
|
* @param Carbon $start
|
|
|
|
* @param Carbon $end
|
|
|
|
*
|
2016-12-06 00:48:41 -06:00
|
|
|
* @return mixed|string
|
2016-12-03 13:38:13 -06:00
|
|
|
*/
|
2016-12-06 00:48:41 -06:00
|
|
|
public function expenses(Collection $accounts, Carbon $start, Carbon $end)
|
2016-12-03 13:38:13 -06:00
|
|
|
{
|
2016-12-03 14:24:55 -06:00
|
|
|
$cache = new CacheProperties;
|
|
|
|
$cache->addProperty($start);
|
|
|
|
$cache->addProperty($end);
|
2016-12-04 11:02:19 -06:00
|
|
|
$cache->addProperty('category-period-expenses-report');
|
2016-12-03 14:24:55 -06:00
|
|
|
$cache->addProperty($accounts->pluck('id')->toArray());
|
|
|
|
if ($cache->has()) {
|
2019-08-27 07:45:14 -05:00
|
|
|
//return $cache->get(); // @codeCoverageIgnore
|
2016-12-03 14:24:55 -06:00
|
|
|
}
|
2016-12-03 13:38:13 -06:00
|
|
|
/** @var CategoryRepositoryInterface $repository */
|
|
|
|
$repository = app(CategoryRepositoryInterface::class);
|
2019-08-27 03:52:07 -05:00
|
|
|
|
|
|
|
/** @var OperationsRepositoryInterface $opsRepository */
|
|
|
|
$opsRepository = app(OperationsRepositoryInterface::class);
|
|
|
|
|
2019-08-27 07:45:14 -05:00
|
|
|
/** @var NoCategoryRepositoryInterface $noCatRepos */
|
|
|
|
$noCatRepos = app(NoCategoryRepositoryInterface::class);
|
|
|
|
|
2019-08-01 22:24:51 -05:00
|
|
|
// depending on the carbon format (a reliable way to determine the general date difference)
|
|
|
|
// change the "listOfPeriods" call so the entire period gets included correctly.
|
2019-08-28 05:28:23 -05:00
|
|
|
$format = app('navigation')->preferredCarbonFormat($start, $end);
|
2019-08-01 22:24:51 -05:00
|
|
|
|
2019-08-28 05:28:23 -05:00
|
|
|
if ('Y' === $format) {
|
2019-08-01 22:24:51 -05:00
|
|
|
$start->startOfYear();
|
|
|
|
}
|
2019-08-28 05:28:23 -05:00
|
|
|
if ('Y-m' === $format) {
|
2019-08-01 22:24:51 -05:00
|
|
|
$start->startOfMonth();
|
|
|
|
}
|
|
|
|
|
2019-08-28 05:28:23 -05:00
|
|
|
$periods = app('navigation')->listOfPeriods($start, $end);
|
|
|
|
$data = [];
|
|
|
|
$with = $opsRepository->listExpenses($start, $end, $accounts);
|
|
|
|
$without = $noCatRepos->listExpenses($start, $end, $accounts);
|
|
|
|
|
|
|
|
foreach ($with as $currencyId => $currencyRow) {
|
|
|
|
foreach ($currencyRow['categories'] as $categoryId => $categoryRow) {
|
|
|
|
$key = sprintf('%d-%d', $currencyId, $categoryId);
|
|
|
|
$data[$key] = $data[$key] ?? [
|
|
|
|
'id' => $categoryRow['id'],
|
|
|
|
'title' => sprintf('%s (%s)', $categoryRow['name'], $currencyRow['currency_name']),
|
|
|
|
'currency_id' => $currencyRow['currency_id'],
|
|
|
|
'currency_symbol' => $currencyRow['currency_symbol'],
|
|
|
|
'currency_name' => $currencyRow['currency_name'],
|
|
|
|
'currency_code' => $currencyRow['currency_code'],
|
|
|
|
'currency_decimal_places' => $currencyRow['currency_decimal_places'],
|
|
|
|
'sum' => '0',
|
|
|
|
'entries' => [],
|
|
|
|
|
|
|
|
];
|
|
|
|
foreach ($categoryRow['transaction_journals'] as $journalId => $journal) {
|
|
|
|
$date = $journal['date']->format($format);
|
|
|
|
$data[$key]['entries'][$date] = $data[$key]['entries'][$date] ?? '0';
|
|
|
|
$data[$key]['entries'][$date] = bcadd($data[$key]['entries'][$date], $journal['amount']);
|
|
|
|
$data[$key]['sum'] = bcadd($data[$key]['sum'], $journal['amount']);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
foreach ($without as $currencyId => $currencyRow) {
|
|
|
|
$key = sprintf('0-%d', $currencyId);
|
|
|
|
$data[$key] = $data[$key] ?? [
|
|
|
|
'id' => 0,
|
|
|
|
'title' => sprintf('%s (%s)', trans('firefly.noCategory'), $currencyRow['currency_name']),
|
|
|
|
'currency_id' => $currencyRow['currency_id'],
|
|
|
|
'currency_symbol' => $currencyRow['currency_symbol'],
|
|
|
|
'currency_name' => $currencyRow['currency_name'],
|
|
|
|
'currency_code' => $currencyRow['currency_code'],
|
|
|
|
'currency_decimal_places' => $currencyRow['currency_decimal_places'],
|
|
|
|
'sum' => '0',
|
|
|
|
'entries' => [],
|
|
|
|
];
|
|
|
|
foreach ($currencyRow['transaction_journals'] as $journalId => $journal) {
|
|
|
|
$date = $journal['date']->format($format);
|
|
|
|
$data[$key]['entries'][$date] = $data[$key]['entries'][$date] ?? '0';
|
|
|
|
$data[$key]['entries'][$date] = bcadd($data[$key]['entries'][$date], $journal['amount']);
|
|
|
|
$data[$key]['sum'] = bcadd($data[$key]['sum'], $journal['amount']);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$cache->store($data);
|
|
|
|
|
|
|
|
$report = $data;
|
2019-08-27 07:45:14 -05:00
|
|
|
|
2018-07-20 07:34:56 -05:00
|
|
|
try {
|
|
|
|
$result = view('reports.partials.category-period', compact('report', 'periods'))->render();
|
2018-09-02 13:13:25 -05:00
|
|
|
// @codeCoverageIgnoreStart
|
2018-07-20 07:34:56 -05:00
|
|
|
} catch (Throwable $e) {
|
|
|
|
Log::error(sprintf('Could not render category::expenses: %s', $e->getMessage()));
|
2019-05-31 06:35:33 -05:00
|
|
|
$result = sprintf('An error prevented Firefly III from rendering: %s. Apologies.', $e->getMessage());
|
2018-07-20 07:34:56 -05:00
|
|
|
}
|
2018-09-02 13:13:25 -05:00
|
|
|
// @codeCoverageIgnoreEnd
|
2016-12-03 13:38:13 -06:00
|
|
|
|
2016-12-03 14:24:55 -06:00
|
|
|
$cache->store($result);
|
|
|
|
|
2016-12-03 13:38:13 -06:00
|
|
|
return $result;
|
|
|
|
}
|
2016-10-26 09:46:43 -05:00
|
|
|
|
2018-07-08 05:08:53 -05:00
|
|
|
|
2016-10-26 09:46:43 -05:00
|
|
|
/**
|
2018-07-21 01:55:32 -05:00
|
|
|
* Show overview of income in category.
|
|
|
|
*
|
2018-04-27 23:23:13 -05:00
|
|
|
* @param Collection $accounts
|
|
|
|
*
|
2016-12-04 11:02:19 -06:00
|
|
|
* @param Carbon $start
|
|
|
|
* @param Carbon $end
|
|
|
|
*
|
|
|
|
* @return string
|
2016-10-26 09:46:43 -05:00
|
|
|
*/
|
2018-07-08 05:28:42 -05:00
|
|
|
public function income(Collection $accounts, Carbon $start, Carbon $end): string
|
2016-10-26 09:46:43 -05:00
|
|
|
{
|
|
|
|
$cache = new CacheProperties;
|
|
|
|
$cache->addProperty($start);
|
|
|
|
$cache->addProperty($end);
|
2016-12-04 11:02:19 -06:00
|
|
|
$cache->addProperty('category-period-income-report');
|
2016-10-26 09:46:43 -05:00
|
|
|
$cache->addProperty($accounts->pluck('id')->toArray());
|
|
|
|
if ($cache->has()) {
|
2019-08-28 05:28:23 -05:00
|
|
|
// return $cache->get(); // @codeCoverageIgnore
|
2016-10-26 09:46:43 -05:00
|
|
|
}
|
2019-08-27 03:52:07 -05:00
|
|
|
|
|
|
|
/** @var OperationsRepositoryInterface $opsRepository */
|
|
|
|
$opsRepository = app(OperationsRepositoryInterface::class);
|
|
|
|
|
2019-08-28 05:28:23 -05:00
|
|
|
/** @var NoCategoryRepositoryInterface $noCatRepos */
|
|
|
|
$noCatRepos = app(NoCategoryRepositoryInterface::class);
|
2019-08-01 22:24:51 -05:00
|
|
|
|
|
|
|
// depending on the carbon format (a reliable way to determine the general date difference)
|
|
|
|
// change the "listOfPeriods" call so the entire period gets included correctly.
|
2019-08-28 05:28:23 -05:00
|
|
|
$format = app('navigation')->preferredCarbonFormat($start, $end);
|
2019-08-01 22:24:51 -05:00
|
|
|
|
2019-08-28 05:28:23 -05:00
|
|
|
if ('Y' === $format) {
|
2019-08-01 22:24:51 -05:00
|
|
|
$start->startOfYear();
|
|
|
|
}
|
2019-08-28 05:28:23 -05:00
|
|
|
if ('Y-m' === $format) {
|
2019-08-01 22:24:51 -05:00
|
|
|
$start->startOfMonth();
|
|
|
|
}
|
|
|
|
|
2019-08-27 07:45:14 -05:00
|
|
|
$periods = app('navigation')->listOfPeriods($start, $end);
|
2019-08-28 05:28:23 -05:00
|
|
|
$data = [];
|
|
|
|
$with = $opsRepository->listIncome($start, $end, $accounts);
|
|
|
|
$without = $noCatRepos->listIncome($start, $end, $accounts);
|
|
|
|
|
|
|
|
foreach ($with as $currencyId => $currencyRow) {
|
|
|
|
foreach ($currencyRow['categories'] as $categoryId => $categoryRow) {
|
|
|
|
$key = sprintf('%d-%d', $currencyId, $categoryId);
|
|
|
|
$data[$key] = $data[$key] ?? [
|
|
|
|
'id' => $categoryRow['id'],
|
|
|
|
'title' => sprintf('%s (%s)', $categoryRow['name'], $currencyRow['currency_name']),
|
|
|
|
'currency_id' => $currencyRow['currency_id'],
|
|
|
|
'currency_symbol' => $currencyRow['currency_symbol'],
|
|
|
|
'currency_name' => $currencyRow['currency_name'],
|
|
|
|
'currency_code' => $currencyRow['currency_code'],
|
|
|
|
'currency_decimal_places' => $currencyRow['currency_decimal_places'],
|
|
|
|
'sum' => '0',
|
|
|
|
'entries' => [],
|
|
|
|
|
|
|
|
];
|
|
|
|
foreach ($categoryRow['transaction_journals'] as $journalId => $journal) {
|
|
|
|
$date = $journal['date']->format($format);
|
|
|
|
$data[$key]['entries'][$date] = $data[$key]['entries'][$date] ?? '0';
|
|
|
|
$data[$key]['entries'][$date] = bcadd($data[$key]['entries'][$date], $journal['amount']);
|
|
|
|
$data[$key]['sum'] = bcadd($data[$key]['sum'], $journal['amount']);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
foreach ($without as $currencyId => $currencyRow) {
|
|
|
|
$key = sprintf('0-%d', $currencyId);
|
|
|
|
$data[$key] = $data[$key] ?? [
|
|
|
|
'id' => 0,
|
|
|
|
'title' => sprintf('%s (%s)', trans('firefly.noCategory'), $currencyRow['currency_name']),
|
|
|
|
'currency_id' => $currencyRow['currency_id'],
|
|
|
|
'currency_symbol' => $currencyRow['currency_symbol'],
|
|
|
|
'currency_name' => $currencyRow['currency_name'],
|
|
|
|
'currency_code' => $currencyRow['currency_code'],
|
|
|
|
'currency_decimal_places' => $currencyRow['currency_decimal_places'],
|
|
|
|
'sum' => '0',
|
|
|
|
'entries' => [],
|
|
|
|
];
|
|
|
|
foreach ($currencyRow['transaction_journals'] as $journalId => $journal) {
|
|
|
|
$date = $journal['date']->format($format);
|
|
|
|
$data[$key]['entries'][$date] = $data[$key]['entries'][$date] ?? '0';
|
|
|
|
$data[$key]['entries'][$date] = bcadd($data[$key]['entries'][$date], $journal['amount']);
|
|
|
|
$data[$key]['sum'] = bcadd($data[$key]['sum'], $journal['amount']);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$cache->store($data);
|
|
|
|
|
|
|
|
$report = $data;
|
|
|
|
|
2018-07-20 07:34:56 -05:00
|
|
|
try {
|
|
|
|
$result = view('reports.partials.category-period', compact('report', 'periods'))->render();
|
2018-09-02 13:13:25 -05:00
|
|
|
// @codeCoverageIgnoreStart
|
2018-07-20 07:34:56 -05:00
|
|
|
} catch (Throwable $e) {
|
|
|
|
Log::error(sprintf('Could not render category::expenses: %s', $e->getMessage()));
|
2019-05-31 06:35:33 -05:00
|
|
|
$result = sprintf('An error prevented Firefly III from rendering: %s. Apologies.', $e->getMessage());
|
2018-07-20 07:34:56 -05:00
|
|
|
}
|
2018-09-02 13:13:25 -05:00
|
|
|
// @codeCoverageIgnoreEnd
|
2019-08-28 05:28:23 -05:00
|
|
|
|
2016-10-26 09:46:43 -05:00
|
|
|
$cache->store($result);
|
|
|
|
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
2018-07-08 05:08:53 -05:00
|
|
|
|
2016-12-06 01:59:08 -06:00
|
|
|
/**
|
2018-07-21 01:55:32 -05:00
|
|
|
* Show overview of operations.
|
|
|
|
*
|
2016-12-15 10:16:46 -06:00
|
|
|
* @param Collection $accounts
|
|
|
|
* @param Carbon $start
|
|
|
|
* @param Carbon $end
|
2016-12-06 01:59:08 -06:00
|
|
|
*
|
|
|
|
* @return mixed|string
|
2017-11-15 05:25:49 -06:00
|
|
|
*
|
2016-12-06 01:59:08 -06:00
|
|
|
*/
|
|
|
|
public function operations(Collection $accounts, Carbon $start, Carbon $end)
|
|
|
|
{
|
|
|
|
// chart properties for cache:
|
|
|
|
$cache = new CacheProperties;
|
|
|
|
$cache->addProperty($start);
|
|
|
|
$cache->addProperty($end);
|
|
|
|
$cache->addProperty('category-report');
|
|
|
|
$cache->addProperty($accounts->pluck('id')->toArray());
|
|
|
|
if ($cache->has()) {
|
2019-08-28 05:28:23 -05:00
|
|
|
// return $cache->get(); // @codeCoverageIgnore
|
2016-12-06 01:59:08 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
/** @var CategoryRepositoryInterface $repository */
|
|
|
|
$repository = app(CategoryRepositoryInterface::class);
|
2019-08-27 03:52:07 -05:00
|
|
|
|
|
|
|
/** @var OperationsRepositoryInterface $opsRepository */
|
|
|
|
$opsRepository = app(OperationsRepositoryInterface::class);
|
|
|
|
|
2019-08-28 05:28:23 -05:00
|
|
|
/** @var NoCategoryRepositoryInterface $noCatRepository */
|
|
|
|
$noCatRepository = app(NoCategoryRepositoryInterface::class);
|
|
|
|
|
|
|
|
$categories = $repository->getCategories();
|
|
|
|
$earnedWith = $opsRepository->listIncome($start, $end, $accounts);
|
|
|
|
$spentWith = $opsRepository->listExpenses($start, $end, $accounts);
|
|
|
|
$earnedWithout = $noCatRepository->listIncome($start, $end, $accounts);
|
|
|
|
$spentWithout = $noCatRepository->listExpenses($start, $end, $accounts);
|
|
|
|
|
|
|
|
$report = [
|
2019-08-16 10:54:38 -05:00
|
|
|
'categories' => [],
|
|
|
|
'sums' => [],
|
|
|
|
];
|
|
|
|
|
2019-08-28 05:28:23 -05:00
|
|
|
// needs four for-each loops.
|
|
|
|
// TODO improve this.
|
|
|
|
foreach ([$earnedWith, $spentWith] as $data) {
|
|
|
|
foreach ($data as $currencyId => $currencyRow) {
|
|
|
|
$report['sums'][$currencyId] = $report['sums'][$currencyId] ?? [
|
|
|
|
'spent' => '0',
|
|
|
|
'earned' => '0',
|
|
|
|
'sum' => '0',
|
|
|
|
'currency_id' => $currencyRow['currency_id'],
|
|
|
|
'currency_symbol' => $currencyRow['currency_symbol'],
|
|
|
|
'currency_name' => $currencyRow['currency_name'],
|
|
|
|
'currency_code' => $currencyRow['currency_code'],
|
|
|
|
'currency_decimal_places' => $currencyRow['currency_decimal_places'],
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
foreach ($currencyRow['categories'] as $categoryId => $categoryRow) {
|
|
|
|
$key = sprintf('%s-%s', $currencyId, $categoryId);
|
|
|
|
$report['categories'][$key] = $report['categories'][$key] ?? [
|
|
|
|
'id' => $categoryId,
|
|
|
|
'title' => sprintf('%s (%s)', $categoryRow['name'], $currencyRow['currency_name']),
|
|
|
|
'currency_id' => $currencyRow['currency_id'],
|
|
|
|
'currency_symbol' => $currencyRow['currency_symbol'],
|
|
|
|
'currency_name' => $currencyRow['currency_name'],
|
|
|
|
'currency_code' => $currencyRow['currency_code'],
|
|
|
|
'currency_decimal_places' => $currencyRow['currency_decimal_places'],
|
|
|
|
'spent' => '0',
|
|
|
|
'earned' => '0',
|
|
|
|
'sum' => '0',
|
|
|
|
];
|
|
|
|
// loop journals:
|
|
|
|
foreach ($categoryRow['transaction_journals'] as $journal) {
|
|
|
|
// sum of sums
|
|
|
|
$report['sums'][$currencyId]['sum'] = bcadd($report['sums'][$currencyId]['sum'], $journal['amount']);
|
|
|
|
// sum of spent:
|
|
|
|
$report['sums'][$currencyId]['spent'] = -1 === bccomp($journal['amount'], '0') ? bcadd($report['sums'][$currencyId]['spent'], $journal['amount']): $report['sums'][$currencyId]['spent'];
|
|
|
|
// sum of earned
|
|
|
|
$report['sums'][$currencyId]['earned'] = 1 === bccomp($journal['amount'], '0') ? bcadd($report['sums'][$currencyId]['earned'], $journal['amount']): $report['sums'][$currencyId]['earned'];
|
|
|
|
|
|
|
|
// sum of category
|
|
|
|
$report['categories'][$key]['sum'] = bcadd($report['categories'][$key]['sum'], $journal['amount']);
|
|
|
|
// total spent in category
|
|
|
|
$report['categories'][$key]['spent'] = -1 === bccomp($journal['amount'], '0') ? bcadd(
|
|
|
|
$report['categories'][$key]['spent'], $journal['amount']
|
|
|
|
) : $report['categories'][$key]['spent'];
|
|
|
|
// total earned in category
|
|
|
|
$report['categories'][$key]['earned'] = 1 === bccomp($journal['amount'], '0') ? bcadd(
|
|
|
|
$report['categories'][$key]['earned'], $journal['amount']
|
|
|
|
) : $report['categories'][$key]['earned'];
|
|
|
|
}
|
|
|
|
}
|
2016-12-06 03:42:13 -06:00
|
|
|
}
|
|
|
|
}
|
2019-08-28 05:28:23 -05:00
|
|
|
foreach ([$earnedWithout, $spentWithout] as $data) {
|
|
|
|
foreach ($data as $currencyId => $currencyRow) {
|
|
|
|
$report['sums'][$currencyId] = $report['sums'][$currencyId] ?? [
|
|
|
|
'spent' => '0',
|
|
|
|
'earned' => '0',
|
|
|
|
'sum' => '0',
|
|
|
|
'currency_id' => $currencyRow['currency_id'],
|
|
|
|
'currency_symbol' => $currencyRow['currency_symbol'],
|
|
|
|
'currency_name' => $currencyRow['currency_name'],
|
|
|
|
'currency_code' => $currencyRow['currency_code'],
|
|
|
|
'currency_decimal_places' => $currencyRow['currency_decimal_places'],
|
|
|
|
];
|
|
|
|
$key = sprintf('%s-0', $currencyId);
|
|
|
|
$report['categories'][$key] = $report['categories'][$key] ?? [
|
|
|
|
'id' => 0,
|
|
|
|
'title' => sprintf('%s (%s)', trans('firefly.noCategory'), $currencyRow['currency_name']),
|
|
|
|
'currency_id' => $currencyRow['currency_id'],
|
|
|
|
'currency_symbol' => $currencyRow['currency_symbol'],
|
|
|
|
'currency_name' => $currencyRow['currency_name'],
|
|
|
|
'currency_code' => $currencyRow['currency_code'],
|
|
|
|
'currency_decimal_places' => $currencyRow['currency_decimal_places'],
|
|
|
|
'spent' => '0',
|
|
|
|
'earned' => '0',
|
|
|
|
'sum' => '0',
|
|
|
|
];
|
|
|
|
// loop journals:
|
|
|
|
foreach ($currencyRow['transaction_journals'] as $journal) {
|
|
|
|
// sum of all
|
|
|
|
$report['sums'][$currencyId]['sum'] = bcadd($report['sums'][$currencyId]['sum'], $journal['amount']);
|
|
|
|
|
|
|
|
// sum of spent:
|
|
|
|
$report['sums'][$currencyId]['spent'] = -1 === bccomp($journal['amount'], '0') ? bcadd($report['sums'][$currencyId]['spent'], $journal['amount']): $report['sums'][$currencyId]['spent'];
|
|
|
|
// sum of earned
|
|
|
|
$report['sums'][$currencyId]['earned'] = 1 === bccomp($journal['amount'], '0') ? bcadd($report['sums'][$currencyId]['earned'], $journal['amount']): $report['sums'][$currencyId]['earned'];
|
|
|
|
|
|
|
|
// sum of category
|
|
|
|
$report['categories'][$key]['sum'] = bcadd($report['categories'][$key]['sum'], $journal['amount']);
|
|
|
|
// total spent in no category
|
|
|
|
$report['categories'][$key]['spent'] = -1 === bccomp($journal['amount'], '0') ? bcadd(
|
|
|
|
$report['categories'][$key]['spent'], $journal['amount']
|
|
|
|
) : $report['categories'][$key]['spent'];
|
|
|
|
// total earned in no category
|
|
|
|
$report['categories'][$key]['earned'] = 1 === bccomp($journal['amount'], '0') ? bcadd(
|
|
|
|
$report['categories'][$key]['earned'], $journal['amount']
|
|
|
|
) : $report['categories'][$key]['earned'];
|
|
|
|
}
|
|
|
|
}
|
2016-12-06 01:59:08 -06:00
|
|
|
}
|
2019-08-12 11:18:51 -05:00
|
|
|
|
2019-07-24 12:02:41 -05:00
|
|
|
// @codeCoverageIgnoreStart
|
2018-07-20 07:34:56 -05:00
|
|
|
try {
|
|
|
|
$result = view('reports.partials.categories', compact('report'))->render();
|
|
|
|
$cache->store($result);
|
|
|
|
} catch (Throwable $e) {
|
|
|
|
Log::error(sprintf('Could not render category::expenses: %s', $e->getMessage()));
|
2019-05-31 06:35:33 -05:00
|
|
|
$result = sprintf('An error prevented Firefly III from rendering: %s. Apologies.', $e->getMessage());
|
2018-07-20 07:34:56 -05:00
|
|
|
}
|
2019-02-13 10:38:41 -06:00
|
|
|
|
2018-09-02 13:13:25 -05:00
|
|
|
// @codeCoverageIgnoreEnd
|
2016-12-06 01:59:08 -06:00
|
|
|
|
|
|
|
return $result;
|
|
|
|
}
|
2016-12-04 11:02:19 -06:00
|
|
|
|
2019-08-12 11:18:51 -05:00
|
|
|
/**
|
|
|
|
* @param array $array
|
|
|
|
*
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
private function noAmountInArray(array $array): bool
|
|
|
|
{
|
|
|
|
if (0 === count($array)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-12-03 13:38:13 -06:00
|
|
|
|
2016-12-22 12:42:45 -06:00
|
|
|
}
|