mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-29 18:20:01 +00:00
Extend report capability for issue #396 and related report issues.
This commit is contained in:
@@ -15,12 +15,18 @@ namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Generator\Report\ReportGeneratorFactory;
|
||||
use FireflyIII\Generator\Report\Standard\MonthReportGenerator;
|
||||
use FireflyIII\Generator\Report\StandardReportGenerator;
|
||||
use FireflyIII\Helpers\Collector\JournalCollector;
|
||||
use FireflyIII\Helpers\Report\ReportHelperInterface;
|
||||
use FireflyIII\Http\Requests\ReportFormRequest;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Support\Collection;
|
||||
use Preferences;
|
||||
use Response;
|
||||
@@ -59,6 +65,84 @@ class ReportController extends Controller
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function auditReport(Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
// throw an error if necessary.
|
||||
if ($end < $start) {
|
||||
throw new FireflyException('End date cannot be before start date, silly!');
|
||||
}
|
||||
|
||||
// lower threshold
|
||||
if ($start < session('first')) {
|
||||
$start = session('first');
|
||||
}
|
||||
|
||||
View::share(
|
||||
'subTitle', trans(
|
||||
'firefly.report_audit',
|
||||
[
|
||||
'start' => $start->formatLocalized($this->monthFormat),
|
||||
'end' => $end->formatLocalized($this->monthFormat),
|
||||
]
|
||||
)
|
||||
);
|
||||
View::share('subTitleIcon', 'fa-calendar');
|
||||
|
||||
$generator = ReportGeneratorFactory::reportGenerator('Audit', $start, $end);
|
||||
$generator->setAccounts($accounts);
|
||||
$result = $generator->generate();
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function defaultReport(Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
// throw an error if necessary.
|
||||
if ($end < $start) {
|
||||
throw new FireflyException('End date cannot be before start date, silly!');
|
||||
}
|
||||
|
||||
// lower threshold
|
||||
if ($start < session('first')) {
|
||||
$start = session('first');
|
||||
}
|
||||
|
||||
View::share(
|
||||
'subTitle', trans(
|
||||
'firefly.report_default',
|
||||
[
|
||||
'start' => $start->formatLocalized($this->monthFormat),
|
||||
'end' => $end->formatLocalized($this->monthFormat),
|
||||
]
|
||||
)
|
||||
);
|
||||
View::share('subTitleIcon', 'fa-calendar');
|
||||
|
||||
$generator = ReportGeneratorFactory::reportGenerator('Standard', $start, $end);
|
||||
$generator->setAccounts($accounts);
|
||||
$result = $generator->generate();
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccountRepositoryInterface $repository
|
||||
*
|
||||
@@ -93,28 +177,34 @@ class ReportController extends Controller
|
||||
*/
|
||||
public function options(string $reportType)
|
||||
{
|
||||
$result = false;
|
||||
$result = '';
|
||||
switch ($reportType) {
|
||||
default:
|
||||
$result = $this->noReportOptions();
|
||||
break;
|
||||
case 'category':
|
||||
$result = $this->categoryReportOptions();
|
||||
break;
|
||||
}
|
||||
|
||||
return Response::json($result);
|
||||
return Response::json(['html' => $result]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $reportType
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
* @param ReportFormRequest $request
|
||||
*
|
||||
* @return View
|
||||
* @return RedirectResponse
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function report(string $reportType, Carbon $start, Carbon $end, Collection $accounts)
|
||||
public function postIndex(ReportFormRequest $request): RedirectResponse
|
||||
{
|
||||
// throw an error if necessary.
|
||||
// report type:
|
||||
$reportType = $request->get('report_type');
|
||||
$start = $request->getStartDate()->format('Ymd');
|
||||
$end = $request->getEndDate()->format('Ymd');
|
||||
$accounts = join(',', $request->getAccountList()->pluck('id')->toArray());
|
||||
$categories = join(',', $request->getCategoryList()->pluck('id')->toArray());
|
||||
|
||||
if ($end < $start) {
|
||||
throw new FireflyException('End date cannot be before start date, silly!');
|
||||
}
|
||||
@@ -124,198 +214,42 @@ class ReportController extends Controller
|
||||
$start = session('first');
|
||||
}
|
||||
|
||||
View::share(
|
||||
'subTitle', trans(
|
||||
'firefly.report_' . $reportType,
|
||||
[
|
||||
'start' => $start->formatLocalized($this->monthFormat),
|
||||
'end' => $end->formatLocalized($this->monthFormat),
|
||||
]
|
||||
)
|
||||
);
|
||||
View::share('subTitleIcon', 'fa-calendar');
|
||||
|
||||
switch ($reportType) {
|
||||
default:
|
||||
throw new FireflyException('Unfortunately, reports of the type "' . e($reportType) . '" are not available at this time.');
|
||||
throw new FireflyException(sprintf('Firefly does not support the "%s"-report yet.', $reportType));
|
||||
case 'category':
|
||||
$uri = route('reports.report.category', [$start, $end, $accounts, $categories]);
|
||||
break;
|
||||
case 'default':
|
||||
|
||||
// more than one year date difference means year report.
|
||||
if ($start->diffInMonths($end) > 12) {
|
||||
return $this->defaultMultiYear($reportType, $start, $end, $accounts);
|
||||
}
|
||||
// more than two months date difference means year report.
|
||||
if ($start->diffInMonths($end) > 1) {
|
||||
return $this->defaultYear($reportType, $start, $end, $accounts);
|
||||
}
|
||||
|
||||
// otherwise default
|
||||
return $this->defaultMonth($reportType, $start, $end, $accounts);
|
||||
$uri = route('reports.report.default', [$start, $end, $accounts]);
|
||||
break;
|
||||
case 'audit':
|
||||
// always default
|
||||
return $this->auditReport($start, $end, $accounts);
|
||||
$uri = route('reports.report.audit', [$start, $end, $accounts]);
|
||||
break;
|
||||
}
|
||||
|
||||
return redirect($uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function categoryReportOptions(): string
|
||||
{
|
||||
/** @var CategoryRepositoryInterface $repository */
|
||||
$repository = app(CategoryRepositoryInterface::class);
|
||||
$categories = $repository->getCategories();
|
||||
$result = view('reports.options.category', compact('categories'))->render();
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return View
|
||||
* @return string
|
||||
*/
|
||||
private function auditReport(Carbon $start, Carbon $end, Collection $accounts)
|
||||
private function noReportOptions(): string
|
||||
{
|
||||
$auditData = [];
|
||||
$dayBefore = clone $start;
|
||||
$dayBefore->subDay();
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
// balance the day before:
|
||||
$id = $account->id;
|
||||
$dayBeforeBalance = Steam::balance($account, $dayBefore);
|
||||
$collector = new JournalCollector(auth()->user());
|
||||
$collector->setAccounts(new Collection([$account]))->setRange($start, $end);
|
||||
$journals = $collector->getJournals();
|
||||
$journals = $journals->reverse();
|
||||
$startBalance = $dayBeforeBalance;
|
||||
|
||||
|
||||
/** @var Transaction $journal */
|
||||
foreach ($journals as $transaction) {
|
||||
$transaction->before = $startBalance;
|
||||
$transactionAmount = $transaction->transaction_amount;
|
||||
$newBalance = bcadd($startBalance, $transactionAmount);
|
||||
$transaction->after = $newBalance;
|
||||
$startBalance = $newBalance;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reverse set again.
|
||||
*/
|
||||
$auditData[$id]['journals'] = $journals->reverse();
|
||||
$auditData[$id]['exists'] = $journals->count() > 0;
|
||||
$auditData[$id]['end'] = $end->formatLocalized(strval(trans('config.month_and_day')));
|
||||
$auditData[$id]['endBalance'] = Steam::balance($account, $end);
|
||||
$auditData[$id]['dayBefore'] = $dayBefore->formatLocalized(strval(trans('config.month_and_day')));
|
||||
$auditData[$id]['dayBeforeBalance'] = $dayBeforeBalance;
|
||||
}
|
||||
|
||||
$reportType = 'audit';
|
||||
$accountIds = join(',', $accounts->pluck('id')->toArray());
|
||||
|
||||
$hideable = ['buttons', 'icon', 'description', 'balance_before', 'amount', 'balance_after', 'date',
|
||||
'interest_date', 'book_date', 'process_date',
|
||||
// three new optional fields.
|
||||
'due_date', 'payment_date', 'invoice_date',
|
||||
'from', 'to', 'budget', 'category', 'bill',
|
||||
// more new optional fields
|
||||
'internal_reference', 'notes',
|
||||
|
||||
'create_date', 'update_date',
|
||||
];
|
||||
$defaultShow = ['icon', 'description', 'balance_before', 'amount', 'balance_after', 'date', 'to'];
|
||||
|
||||
return view('reports.audit.report', compact('start', 'end', 'reportType', 'accountIds', 'accounts', 'auditData', 'hideable', 'defaultShow'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $reportType
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
private function defaultMonth(string $reportType, Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
$bills = $this->helper->getBillReport($start, $end, $accounts);
|
||||
$tags = $this->helper->tagReport($start, $end, $accounts);
|
||||
|
||||
// and some id's, joined:
|
||||
$accountIds = join(',', $accounts->pluck('id')->toArray());
|
||||
|
||||
// continue!
|
||||
return view(
|
||||
'reports.default.month',
|
||||
compact(
|
||||
'start', 'end',
|
||||
'tags',
|
||||
'bills',
|
||||
'accountIds',
|
||||
'reportType'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $reportType
|
||||
* @param $start
|
||||
* @param $end
|
||||
* @param $accounts
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
private function defaultMultiYear(string $reportType, Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
// need all budgets
|
||||
// need all years.
|
||||
|
||||
|
||||
// and some id's, joined:
|
||||
$accountIds = [];
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
$accountIds[] = $account->id;
|
||||
}
|
||||
$accountIds = join(',', $accountIds);
|
||||
|
||||
return view(
|
||||
'reports.default.multi-year',
|
||||
compact(
|
||||
'accounts', 'start', 'end', 'accountIds', 'reportType'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $reportType
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Collection $accounts
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
private function defaultYear(string $reportType, Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
Session::flash('gaEventCategory', 'report');
|
||||
Session::flash('gaEventAction', 'year');
|
||||
Session::flash('gaEventLabel', $start->format('Y'));
|
||||
|
||||
// and some id's, joined:
|
||||
$accountIds = [];
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
$accountIds[] = $account->id;
|
||||
}
|
||||
$accountIds = join(',', $accountIds);
|
||||
|
||||
return view(
|
||||
'reports.default.year',
|
||||
compact(
|
||||
'start', 'reportType',
|
||||
'accountIds', 'end'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function noReportOptions(): array
|
||||
{
|
||||
return ['html' => view('reports.options.no-options')->render()];
|
||||
return view('reports.options.no-options')->render();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user