mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-31 10:47:00 +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