Files
firefly-iii/app/Http/Controllers/ReportController.php

428 lines
14 KiB
PHP
Raw Normal View History

2016-05-20 08:57:45 +02:00
<?php
/**
* ReportController.php
2020-01-31 07:32:04 +01:00
* Copyright (c) 2019 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
2017-10-21 08:40:00 +02:00
*
* This program is distributed in the hope that it will be useful,
2017-10-21 08:40:00 +02:00
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
2017-10-21 08:40:00 +02:00
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
2018-07-08 12:08:53 +02:00
/** @noinspection CallableParameterUseCaseInTypeContextInspection */
2017-03-24 15:15:12 +01:00
declare(strict_types=1);
2016-05-20 08:57:45 +02:00
namespace FireflyIII\Http\Controllers;
2015-02-23 20:25:48 +01:00
use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Generator\Report\ReportGeneratorFactory;
2015-02-23 20:25:48 +01:00
use FireflyIII\Helpers\Report\ReportHelperInterface;
use FireflyIII\Http\Requests\ReportFormRequest;
2020-03-13 18:17:53 +01:00
use FireflyIII\Models\Account;
2016-05-20 11:02:07 +02:00
use FireflyIII\Models\AccountType;
2016-10-10 07:49:39 +02:00
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Support\Http\Controllers\RenderPartialViews;
use Illuminate\Contracts\View\Factory;
2021-09-18 10:20:19 +02:00
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Routing\Redirector;
use Illuminate\Support\Collection;
use Illuminate\View\View;
2017-03-24 11:07:38 +01:00
use Log;
2015-02-23 20:25:48 +01:00
/**
2017-11-15 12:25:49 +01:00
* Class ReportController.
2018-07-22 08:10:16 +02:00
*
2015-02-23 20:25:48 +01:00
*/
class ReportController extends Controller
{
use RenderPartialViews;
2018-07-22 08:10:16 +02:00
/** @var ReportHelperInterface Helper interface. */
2015-03-29 12:25:46 +02:00
protected $helper;
2018-07-21 08:06:24 +02:00
/** @var BudgetRepositoryInterface The budget repository */
2018-01-24 05:17:26 +01:00
private $repository;
2015-02-23 20:25:48 +01:00
/**
2018-07-22 08:10:16 +02:00
* ReportController constructor.
2015-02-23 20:25:48 +01:00
*/
2016-09-16 09:36:08 +02:00
public function __construct()
2015-02-23 20:25:48 +01:00
{
2015-05-15 22:00:00 +02:00
parent::__construct();
2016-01-27 20:45:49 +01:00
2016-10-29 07:44:46 +02:00
$this->middleware(
function ($request, $next) {
2022-03-29 14:58:06 +02:00
app('view')->share('title', (string) trans('firefly.reports'));
app('view')->share('mainTitleIcon', 'fa-bar-chart');
app('view')->share('subTitleIcon', 'fa-calendar');
2018-01-24 05:17:26 +01:00
$this->helper = app(ReportHelperInterface::class);
$this->repository = app(BudgetRepositoryInterface::class);
2016-10-29 07:44:46 +02:00
return $next($request);
}
);
2015-02-23 20:25:48 +01:00
}
2017-12-09 21:49:19 +01:00
/**
2018-07-22 08:10:16 +02:00
* Show audit report.
*
2017-12-09 21:49:19 +01:00
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return Factory|View|string
2017-12-22 18:32:43 +01:00
*
2021-03-28 11:46:23 +02:00
* @throws FireflyException
2016-02-04 07:28:39 +01:00
*/
2018-07-09 19:24:08 +02:00
public function auditReport(Collection $accounts, Carbon $start, Carbon $end)
2016-02-04 07:28:39 +01:00
{
if ($end < $start) {
2022-03-29 14:58:06 +02:00
return view('error')->with('message', (string) trans('firefly.end_after_start_date'));
}
2018-01-24 05:17:26 +01:00
$this->repository->cleanupBudgets();
2016-02-04 07:28:39 +01:00
app('view')->share(
2017-11-15 10:52:29 +01:00
'subTitle',
trans(
2017-11-15 11:33:07 +01:00
'firefly.report_audit',
[
2022-03-27 20:24:13 +02:00
'start' => $start->isoFormat($this->monthAndDayFormat),
'end' => $end->isoFormat($this->monthAndDayFormat),
2017-11-15 11:33:07 +01:00
]
)
);
$generator = ReportGeneratorFactory::reportGenerator('Audit', $start, $end);
$generator->setAccounts($accounts);
2016-02-04 07:28:39 +01:00
2018-03-27 19:29:58 +02:00
return $generator->generate();
}
/**
2018-07-22 08:10:16 +02:00
* Show budget report.
*
* @param Collection $accounts
2016-12-09 07:07:53 +01:00
* @param Collection $budgets
* @param Carbon $start
* @param Carbon $end
*
* @return Factory|View|string
2017-12-22 18:32:43 +01:00
*
2021-03-28 11:46:23 +02:00
* @throws FireflyException
*/
2018-07-09 19:24:08 +02:00
public function budgetReport(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end)
{
if ($end < $start) {
2022-03-29 14:58:06 +02:00
return view('error')->with('message', (string) trans('firefly.end_after_start_date'));
}
2018-01-24 05:17:26 +01:00
$this->repository->cleanupBudgets();
app('view')->share(
2017-11-15 10:52:29 +01:00
'subTitle',
trans(
2017-11-15 11:33:07 +01:00
'firefly.report_budget',
[
2022-03-27 20:24:13 +02:00
'start' => $start->isoFormat($this->monthAndDayFormat),
'end' => $end->isoFormat($this->monthAndDayFormat),
2017-11-15 11:33:07 +01:00
]
)
);
$generator = ReportGeneratorFactory::reportGenerator('Budget', $start, $end);
$generator->setAccounts($accounts);
$generator->setBudgets($budgets);
2018-04-02 15:10:40 +02:00
return $generator->generate();
}
2016-02-04 07:28:39 +01:00
/**
2018-07-22 08:10:16 +02:00
* Show category report.
*
2016-02-04 07:28:39 +01:00
* @param Collection $accounts
2016-11-18 20:06:08 +01:00
* @param Collection $categories
2016-12-06 06:52:17 +01:00
* @param Carbon $start
* @param Carbon $end
2016-11-18 20:06:08 +01:00
*
* @return Factory|View|string
2017-12-22 18:32:43 +01:00
*
2021-03-28 11:46:23 +02:00
* @throws FireflyException
2016-02-04 07:28:39 +01:00
*/
2018-07-09 19:24:08 +02:00
public function categoryReport(Collection $accounts, Collection $categories, Carbon $start, Carbon $end)
2016-02-04 07:28:39 +01:00
{
if ($end < $start) {
2022-03-29 14:58:06 +02:00
return view('error')->with('message', (string) trans('firefly.end_after_start_date'));
}
2018-01-24 05:17:26 +01:00
$this->repository->cleanupBudgets();
2016-02-04 07:28:39 +01:00
app('view')->share(
2017-11-15 10:52:29 +01:00
'subTitle',
trans(
2017-11-15 11:33:07 +01:00
'firefly.report_category',
[
2022-03-27 20:24:13 +02:00
'start' => $start->isoFormat($this->monthAndDayFormat),
'end' => $end->isoFormat($this->monthAndDayFormat),
2017-11-15 11:33:07 +01:00
]
)
);
$generator = ReportGeneratorFactory::reportGenerator('Category', $start, $end);
$generator->setAccounts($accounts);
$generator->setCategories($categories);
2018-04-02 15:10:40 +02:00
return $generator->generate();
}
/**
2018-07-22 08:10:16 +02:00
* Show default report.
*
2016-12-06 06:52:17 +01:00
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return Factory|View|string
2017-12-22 18:32:43 +01:00
*
2021-03-28 11:46:23 +02:00
* @throws FireflyException
*/
2018-07-09 19:24:08 +02:00
public function defaultReport(Collection $accounts, Carbon $start, Carbon $end)
{
if ($end < $start) {
2022-03-29 14:58:06 +02:00
return view('error')->with('message', (string) trans('firefly.end_after_start_date'));
}
2016-11-25 16:55:04 +01:00
2018-01-24 05:17:26 +01:00
$this->repository->cleanupBudgets();
2016-02-04 07:28:39 +01:00
app('view')->share(
2017-11-15 10:52:29 +01:00
'subTitle',
trans(
2017-11-15 11:33:07 +01:00
'firefly.report_default',
[
2022-03-27 20:24:13 +02:00
'start' => $start->isoFormat($this->monthAndDayFormat),
'end' => $end->isoFormat($this->monthAndDayFormat),
2017-11-15 11:33:07 +01:00
]
)
);
$generator = ReportGeneratorFactory::reportGenerator('Standard', $start, $end);
$generator->setAccounts($accounts);
2016-02-23 20:23:10 +01:00
2018-04-02 15:10:40 +02:00
return $generator->generate();
}
/**
* Show account report.
*
* @param Collection $accounts
* @param Collection $expense
* @param Carbon $start
* @param Carbon $end
*
2021-05-24 08:54:58 +02:00
* @return string
2021-03-28 11:46:23 +02:00
* @throws FireflyException
*/
public function doubleReport(Collection $accounts, Collection $expense, Carbon $start, Carbon $end)
{
if ($end < $start) {
[$start, $end] = [$end, $start];
}
$this->repository->cleanupBudgets();
app('view')->share(
'subTitle',
trans(
'firefly.report_double',
2022-03-27 20:24:13 +02:00
['start' => $start->isoFormat($this->monthAndDayFormat),
2022-03-29 14:58:06 +02:00
'end' => $end->isoFormat($this->monthAndDayFormat)]
)
);
$generator = ReportGeneratorFactory::reportGenerator('Account', $start, $end);
$generator->setAccounts($accounts);
$generator->setExpense($expense);
return $generator->generate();
}
/**
2018-07-22 08:10:16 +02:00
* Show index.
*
* @param AccountRepositoryInterface $repository
*
* @return Factory|View
2021-09-18 10:21:29 +02:00
* @throws FireflyException
2022-03-29 15:10:05 +02:00
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
*/
public function index(AccountRepositoryInterface $repository)
{
/** @var Carbon $start */
2020-09-11 07:12:33 +02:00
$start = clone session('first', today(config('app.timezone')));
$months = $this->helper->listOfMonths($start);
$customFiscalYear = app('preferences')->get('customFiscalYear', 0)->data;
2020-03-13 18:17:53 +01:00
$accounts = $repository->getAccountsByType(
[AccountType::DEFAULT, AccountType::ASSET, AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE]
);
// group accounts by role:
$groupedAccounts = [];
/** @var Account $account */
foreach ($accounts as $account) {
$type = $account->accountType->type;
$role = sprintf('opt_group_%s', $repository->getMetaValue($account, 'account_role'));
if (in_array($type, [AccountType::MORTGAGE, AccountType::DEBT, AccountType::LOAN], true)) {
$role = sprintf('opt_group_l_%s', $type);
2020-03-13 18:17:53 +01:00
}
if ('' === $role || 'opt_group_' === $role) {
$role = 'opt_group_defaultAsset';
}
$groupedAccounts[trans(sprintf('firefly.%s', $role))][$account->id] = $account;
2020-03-13 18:17:53 +01:00
}
ksort($groupedAccounts);
$accountList = implode(',', $accounts->pluck('id')->toArray());
2018-01-24 05:17:26 +01:00
$this->repository->cleanupBudgets();
2016-02-04 07:28:39 +01:00
return view('reports.index', compact('months', 'accounts', 'start', 'accountList', 'groupedAccounts', 'customFiscalYear'));
2016-02-04 07:28:39 +01:00
}
/**
2018-07-22 08:10:16 +02:00
* Show options for reports.
*
* @param string $reportType
2015-12-12 17:51:07 +01:00
*
2021-09-18 10:20:19 +02:00
* @return JsonResponse
2019-08-17 10:47:10 +02:00
*
*/
public function options(string $reportType)
{
2021-09-18 10:21:29 +02:00
$result = match ($reportType) {
default => $this->noReportOptions(),
'category' => $this->categoryReportOptions(),
'budget' => $this->budgetReportOptions(),
'tag' => $this->tagReportOptions(),
'double' => $this->doubleReportOptions(),
};
2018-03-10 20:30:09 +01:00
return response()->json(['html' => $result]);
}
/**
2018-07-22 08:10:16 +02:00
* Process the submit of report.
*
* @param ReportFormRequest $request
*
* @return RedirectResponse|Redirector
2018-07-20 14:34:56 +02:00
*
2021-03-28 11:46:23 +02:00
* @throws FireflyException
*
*/
2017-03-24 11:07:38 +01:00
public function postIndex(ReportFormRequest $request)
{
// report type:
$reportType = $request->get('report_type');
$start = $request->getStartDate()->format('Ymd');
$end = $request->getEndDate()->format('Ymd');
2018-04-02 15:10:40 +02:00
$accounts = implode(',', $request->getAccountList()->pluck('id')->toArray());
$categories = implode(',', $request->getCategoryList()->pluck('id')->toArray());
$budgets = implode(',', $request->getBudgetList()->pluck('id')->toArray());
2018-08-17 05:54:29 +02:00
$tags = implode(',', $request->getTagList()->pluck('id')->toArray());
$double = implode(',', $request->getDoubleList()->pluck('id')->toArray());
2017-11-15 12:25:49 +01:00
if (0 === $request->getAccountList()->count()) {
2017-03-24 11:07:38 +01:00
Log::debug('Account count is zero');
2022-03-29 14:58:06 +02:00
session()->flash('error', (string) trans('firefly.select_at_least_one_account'));
2016-11-25 16:55:04 +01:00
return redirect(route('reports.index'));
}
2018-07-08 12:08:53 +02:00
if ('category' === $reportType && 0 === $request->getCategoryList()->count()) {
2022-03-29 14:58:06 +02:00
session()->flash('error', (string) trans('firefly.select_at_least_one_category'));
2016-11-28 19:45:36 +01:00
return redirect(route('reports.index'));
}
2018-07-08 12:08:53 +02:00
if ('budget' === $reportType && 0 === $request->getBudgetList()->count()) {
2022-03-29 14:58:06 +02:00
session()->flash('error', (string) trans('firefly.select_at_least_one_budget'));
return redirect(route('reports.index'));
}
2018-07-08 12:08:53 +02:00
if ('tag' === $reportType && 0 === $request->getTagList()->count()) {
2022-03-29 14:58:06 +02:00
session()->flash('error', (string) trans('firefly.select_at_least_one_tag'));
2018-11-23 08:40:08 +01:00
return redirect(route('reports.index'));
}
2019-09-03 22:35:41 +02:00
if ('double' === $reportType && 0 === $request->getDoubleList()->count()) {
2022-03-29 14:58:06 +02:00
session()->flash('error', (string) trans('firefly.select_at_least_one_expense'));
2017-02-15 20:07:10 +01:00
return redirect(route('reports.index'));
}
2017-10-22 20:13:02 +02:00
if ($request->getEndDate() < $request->getStartDate()) {
2022-03-29 14:58:06 +02:00
return view('error')->with('message', (string) trans('firefly.end_after_start_date'));
}
2022-04-12 18:19:30 +02:00
$url = match ($reportType) {
2021-09-18 10:21:29 +02:00
default => route('reports.report.default', [$accounts, $start, $end]),
'category' => route('reports.report.category', [$accounts, $categories, $start, $end]),
'audit' => route('reports.report.audit', [$accounts, $start, $end]),
'budget' => route('reports.report.budget', [$accounts, $budgets, $start, $end]),
'tag' => route('reports.report.tag', [$accounts, $tags, $start, $end]),
'double' => route('reports.report.double', [$accounts, $double, $start, $end]),
};
2022-04-12 18:19:30 +02:00
return redirect($url);
}
2021-03-28 11:46:23 +02:00
2017-02-17 06:42:36 +01:00
/**
2018-07-22 08:10:16 +02:00
* Get a tag report.
*
2017-02-17 06:42:36 +01:00
* @param Collection $accounts
* @param Collection $tags
* @param Carbon $start
* @param Carbon $end
*
* @return Factory|View|string
2021-03-28 11:46:23 +02:00
* @throws FireflyException
2017-02-17 06:42:36 +01:00
*/
2018-07-09 19:24:08 +02:00
public function tagReport(Collection $accounts, Collection $tags, Carbon $start, Carbon $end)
2017-02-17 06:42:36 +01:00
{
if ($end < $start) {
2022-03-29 14:58:06 +02:00
return view('error')->with('message', (string) trans('firefly.end_after_start_date'));
2017-02-17 06:42:36 +01:00
}
2018-01-24 05:17:26 +01:00
$this->repository->cleanupBudgets();
2017-02-17 06:42:36 +01:00
app('view')->share(
2017-11-15 10:52:29 +01:00
'subTitle',
trans(
2017-11-15 11:33:07 +01:00
'firefly.report_tag',
[
2022-03-27 20:24:13 +02:00
'start' => $start->isoFormat($this->monthAndDayFormat),
'end' => $end->isoFormat($this->monthAndDayFormat),
2017-11-15 11:33:07 +01:00
]
)
2017-02-17 06:42:36 +01:00
);
$generator = ReportGeneratorFactory::reportGenerator('Tag', $start, $end);
$generator->setAccounts($accounts);
$generator->setTags($tags);
2018-04-02 15:10:40 +02:00
return $generator->generate();
2017-02-17 06:42:36 +01:00
}
2015-02-23 20:25:48 +01:00
}