mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-31 10:47:00 +00:00 
			
		
		
		
	Code cleanup.
This commit is contained in:
		| @@ -40,7 +40,6 @@ use Psr\Container\ContainerExceptionInterface; | ||||
| use Psr\Container\NotFoundExceptionInterface; | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * Class CreateController | ||||
|  */ | ||||
| class CreateController extends Controller | ||||
| @@ -52,8 +51,6 @@ class CreateController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * CreateController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -76,9 +73,6 @@ class CreateController extends Controller | ||||
|     /** | ||||
|      * Create a new account. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * @param string  $objectType | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function create(Request $request, string $objectType) | ||||
| @@ -134,9 +128,8 @@ class CreateController extends Controller | ||||
|     /** | ||||
|      * Store the new account. | ||||
|      * | ||||
|      * @param AccountFormRequest $request | ||||
|      * @return Redirector|RedirectResponse | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * @throws FireflyException | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
| @@ -161,7 +154,7 @@ class CreateController extends Controller | ||||
|         } | ||||
| 
 | ||||
|         // store attachment(s):
 | ||||
|         /** @var array|null $files */ | ||||
|         /** @var null|array $files */ | ||||
|         $files = $request->hasFile('attachments') ? $request->file('attachments') : null; | ||||
|         if (null !== $files && !auth()->user()->hasRole('demo')) { | ||||
|             $this->attachments->saveAttachmentsForModel($account, $files); | ||||
|   | ||||
| @@ -42,8 +42,6 @@ class DeleteController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * DeleteController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -65,9 +63,7 @@ class DeleteController extends Controller | ||||
|     /** | ||||
|      * Delete account screen. | ||||
|      * | ||||
|      * @param Account $account | ||||
|      * | ||||
|      * @return Factory|RedirectResponse|Redirector|View | ||||
|      * @return Factory|Redirector|RedirectResponse|View | ||||
|      */ | ||||
|     public function delete(Account $account) | ||||
|     { | ||||
| @@ -90,10 +86,7 @@ class DeleteController extends Controller | ||||
|     /** | ||||
|      * Delete the account. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * @param Account $account | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * @return Redirector|RedirectResponse | ||||
|      */ | ||||
|     public function destroy(Request $request, Account $account) | ||||
|     { | ||||
|   | ||||
| @@ -36,7 +36,6 @@ use Illuminate\Routing\Redirector; | ||||
| use Illuminate\View\View; | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * Class EditController | ||||
|  */ | ||||
| class EditController extends Controller | ||||
| @@ -70,11 +69,7 @@ class EditController extends Controller | ||||
|     /** | ||||
|      * Edit account overview. | ||||
|      * | ||||
|      * @param Request                    $request | ||||
|      * @param Account                    $account | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * | ||||
|      * @return Factory|RedirectResponse|Redirector|View | ||||
|      * @return Factory|Redirector|RedirectResponse|View | ||||
|      */ | ||||
|     public function edit(Request $request, Account $account, AccountRepositoryInterface $repository) | ||||
|     { | ||||
| @@ -178,10 +173,7 @@ class EditController extends Controller | ||||
|     /** | ||||
|      * Update the account. | ||||
|      * | ||||
|      * @param AccountFormRequest $request | ||||
|      * @param Account            $account | ||||
|      * | ||||
|      * @return $this|RedirectResponse|Redirector | ||||
|      * @return $this|Redirector|RedirectResponse | ||||
|      */ | ||||
|     public function update(AccountFormRequest $request, Account $account) | ||||
|     { | ||||
| @@ -195,7 +187,7 @@ class EditController extends Controller | ||||
|         $request->session()->flash('success', (string)trans('firefly.updated_account', ['name' => $account->name])); | ||||
| 
 | ||||
|         // store new attachment(s):
 | ||||
|         /** @var array|null $files */ | ||||
|         /** @var null|array $files */ | ||||
|         $files = $request->hasFile('attachments') ? $request->file('attachments') : null; | ||||
|         if (null !== $files && !auth()->user()->hasRole('demo')) { | ||||
|             $this->attachments->saveAttachmentsForModel($account, $files); | ||||
|   | ||||
| @@ -33,12 +33,10 @@ use Illuminate\Contracts\View\Factory; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use Illuminate\View\View; | ||||
| use JsonException; | ||||
| use Psr\Container\ContainerExceptionInterface; | ||||
| use Psr\Container\NotFoundExceptionInterface; | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * Class IndexController | ||||
|  */ | ||||
| class IndexController extends Controller | ||||
| @@ -49,8 +47,6 @@ class IndexController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * IndexController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -70,12 +66,10 @@ class IndexController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Request $request | ||||
|      * @param string  $objectType | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * @throws JsonException | ||||
|      * @throws \JsonException | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
|      */ | ||||
| @@ -91,8 +85,10 @@ class IndexController extends Controller | ||||
|         $pageSize     = (int)app('preferences')->get('listPageSize', 50)->data; | ||||
|         $accounts     = $collection->slice(($page - 1) * $pageSize, $pageSize); | ||||
|         unset($collection); | ||||
| 
 | ||||
|         /** @var Carbon $start */ | ||||
|         $start = clone session('start', today(config('app.timezone'))->startOfMonth()); | ||||
| 
 | ||||
|         /** @var Carbon $end */ | ||||
|         $end = clone session('end', today(config('app.timezone'))->endOfMonth()); | ||||
|         $start->subDay(); | ||||
| @@ -126,12 +122,10 @@ class IndexController extends Controller | ||||
|     /** | ||||
|      * Show list of accounts. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * @param string  $objectType | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * @throws JsonException | ||||
|      * @throws \JsonException | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
|      */ | ||||
| @@ -154,8 +148,10 @@ class IndexController extends Controller | ||||
|         app('log')->debug(sprintf('Count of collection: %d, count of accounts: %d', $total, $accounts->count())); | ||||
| 
 | ||||
|         unset($collection); | ||||
| 
 | ||||
|         /** @var Carbon $start */ | ||||
|         $start = clone session('start', today(config('app.timezone'))->startOfMonth()); | ||||
| 
 | ||||
|         /** @var Carbon $end */ | ||||
|         $end = clone session('end', today(config('app.timezone'))->endOfMonth()); | ||||
|         $start->subDay(); | ||||
| @@ -165,7 +161,6 @@ class IndexController extends Controller | ||||
|         $endBalances   = app('steam')->balancesByAccounts($accounts, $end); | ||||
|         $activities    = app('steam')->getLastActivities($ids); | ||||
| 
 | ||||
| 
 | ||||
|         $accounts->each( | ||||
|             function (Account $account) use ($activities, $startBalances, $endBalances) { | ||||
|                 $interest = (string)$this->repository->getMetaValue($account, 'interest'); | ||||
| @@ -189,6 +184,7 @@ class IndexController extends Controller | ||||
|         ); | ||||
|         // make paginator:
 | ||||
|         app('log')->debug(sprintf('Count of accounts before LAP: %d', $accounts->count())); | ||||
| 
 | ||||
|         /** @var LengthAwarePaginator $accounts */ | ||||
|         $accounts = new LengthAwarePaginator($accounts, $total, $pageSize, $page); | ||||
|         $accounts->setPath(route('accounts.index', [$objectType])); | ||||
|   | ||||
| @@ -39,7 +39,6 @@ use Illuminate\Contracts\View\Factory; | ||||
| use Illuminate\Http\RedirectResponse; | ||||
| use Illuminate\Routing\Redirector; | ||||
| use Illuminate\View\View; | ||||
| use JsonException; | ||||
| use Psr\Container\ContainerExceptionInterface; | ||||
| use Psr\Container\NotFoundExceptionInterface; | ||||
| 
 | ||||
| @@ -53,8 +52,6 @@ class ReconcileController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * ReconcileController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -76,13 +73,10 @@ class ReconcileController extends Controller | ||||
|     /** | ||||
|      * Reconciliation overview. | ||||
|      * | ||||
|      * @param Account     $account | ||||
|      * @param Carbon|null $start | ||||
|      * @param Carbon|null $end | ||||
|      * @return Factory|Redirector|RedirectResponse|View | ||||
|      * | ||||
|      * @return Factory|RedirectResponse|Redirector|View | ||||
|      * @throws FireflyException | ||||
|      * @throws JsonException | ||||
|      * @throws \JsonException | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
|      */ | ||||
| @@ -106,6 +100,7 @@ class ReconcileController extends Controller | ||||
|         if (null === $start && null === $end) { | ||||
|             /** @var Carbon $start */ | ||||
|             $start = clone session('start', app('navigation')->startOfPeriod(new Carbon(), $range)); | ||||
| 
 | ||||
|             /** @var Carbon $end */ | ||||
|             $end = clone session('end', app('navigation')->endOfPeriod(new Carbon(), $range)); | ||||
|         } | ||||
| @@ -153,14 +148,10 @@ class ReconcileController extends Controller | ||||
|     /** | ||||
|      * Submit a new reconciliation. | ||||
|      * | ||||
|      * @param ReconciliationStoreRequest $request | ||||
|      * @param Account                    $account | ||||
|      * @param Carbon                     $start | ||||
|      * @param Carbon                     $end | ||||
|      * @return Redirector|RedirectResponse | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * @throws DuplicateTransactionException | ||||
|      * @throws JsonException | ||||
|      * @throws \JsonException | ||||
|      */ | ||||
|     public function submit(ReconciliationStoreRequest $request, Account $account, Carbon $start, Carbon $end) | ||||
|     { | ||||
| @@ -202,14 +193,8 @@ class ReconcileController extends Controller | ||||
|     /** | ||||
|      * Creates a reconciliation group. | ||||
|      * | ||||
|      * @param Account $account | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * @param string  $difference | ||||
|      * | ||||
|      * @return string | ||||
|      * @throws DuplicateTransactionException | ||||
|      * @throws JsonException | ||||
|      * @throws \JsonException | ||||
|      */ | ||||
|     private function createReconciliation(Account $account, Carbon $start, Carbon $end, string $difference): string | ||||
|     { | ||||
| @@ -258,11 +243,14 @@ class ReconcileController extends Controller | ||||
|                 ], | ||||
|             ], | ||||
|         ]; | ||||
| 
 | ||||
|         /** @var TransactionGroupFactory $factory */ | ||||
|         $factory = app(TransactionGroupFactory::class); | ||||
| 
 | ||||
|         /** @var User $user */ | ||||
|         $user = auth()->user(); | ||||
|         $factory->setUser($user); | ||||
| 
 | ||||
|         try { | ||||
|             $factory->create($submission); | ||||
|         } catch (FireflyException $e) { | ||||
|   | ||||
| @@ -36,13 +36,11 @@ use Illuminate\Http\Request; | ||||
| use Illuminate\Routing\Redirector; | ||||
| use Illuminate\Support\Collection; | ||||
| use Illuminate\View\View; | ||||
| use JsonException; | ||||
| use Psr\Container\ContainerExceptionInterface; | ||||
| use Psr\Container\NotFoundExceptionInterface; | ||||
| 
 | ||||
| /** | ||||
|  * Class ShowController | ||||
|  * | ||||
|  */ | ||||
| class ShowController extends Controller | ||||
| { | ||||
| @@ -52,8 +50,6 @@ class ShowController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * ShowController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -77,14 +73,10 @@ class ShowController extends Controller | ||||
|     /** | ||||
|      * Show an account. | ||||
|      * | ||||
|      * @param Request     $request | ||||
|      * @param Account     $account | ||||
|      * @param Carbon|null $start | ||||
|      * @param Carbon|null $end | ||||
|      * @return Factory|Redirector|RedirectResponse|View | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector|Factory|View | ||||
|      * @throws FireflyException | ||||
|      * @throws JsonException | ||||
|      * @throws \JsonException | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
|      */ | ||||
| @@ -96,9 +88,9 @@ class ShowController extends Controller | ||||
|             return $this->redirectAccountToAccount($account); | ||||
|         } | ||||
| 
 | ||||
|         /** @var Carbon $start */ | ||||
|         // @var Carbon $start
 | ||||
|         $start ??= session('start'); | ||||
|         /** @var Carbon $end */ | ||||
|         // @var Carbon $end
 | ||||
|         $end ??= session('end'); | ||||
| 
 | ||||
|         if ($end < $start) { | ||||
| @@ -123,20 +115,19 @@ class ShowController extends Controller | ||||
|             $subTitle = (string)trans('firefly.all_journals_for_account', ['name' => $account->name]); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         /** @var GroupCollectorInterface $collector */ | ||||
|         $collector = app(GroupCollectorInterface::class); | ||||
|         $collector | ||||
|             ->setAccounts(new Collection([$account])) | ||||
|             ->setLimit($pageSize) | ||||
|             ->setPage($page)->withAccountInformation()->withCategoryInformation() | ||||
|             ->setRange($start, $end); | ||||
|             ->setRange($start, $end) | ||||
|         ; | ||||
| 
 | ||||
|         // this search will not include transaction groups where this asset account (or liability)
 | ||||
|         // is just part of ONE of the journals. To force this:
 | ||||
|         $collector->setExpandGroupSearch(true); | ||||
| 
 | ||||
| 
 | ||||
|         $groups = $collector->getPaginatedGroups(); | ||||
| 
 | ||||
|         $groups->setPath(route('accounts.show', [$account->id, $start->format('Y-m-d'), $end->format('Y-m-d')])); | ||||
| @@ -168,12 +159,10 @@ class ShowController extends Controller | ||||
|     /** | ||||
|      * Show an account. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * @param Account $account | ||||
|      * @return Factory|Redirector|RedirectResponse|View | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector|Factory|View | ||||
|      * @throws FireflyException | ||||
|      * @throws JsonException | ||||
|      * @throws \JsonException | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
|      */ | ||||
| @@ -189,12 +178,13 @@ class ShowController extends Controller | ||||
|         $end          = today(config('app.timezone')); | ||||
|         $today        = today(config('app.timezone')); | ||||
|         $start        = $this->repository->oldestJournalDate($account) ?? today(config('app.timezone'))->startOfMonth(); | ||||
|         $subTitleIcon = config('firefly.subIconsByIdentifier.' . $account->accountType->type); | ||||
|         $subTitleIcon = config('firefly.subIconsByIdentifier.'.$account->accountType->type); | ||||
|         $page         = (int)$request->get('page'); | ||||
|         $pageSize     = (int)app('preferences')->get('listPageSize', 50)->data; | ||||
|         $currency     = $this->repository->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency(); | ||||
|         $subTitle     = (string)trans('firefly.all_journals_for_account', ['name' => $account->name]); | ||||
|         $periods      = new Collection(); | ||||
| 
 | ||||
|         /** @var GroupCollectorInterface $collector */ | ||||
|         $collector = app(GroupCollectorInterface::class); | ||||
|         $collector->setAccounts(new Collection([$account]))->setLimit($pageSize)->setPage($page)->withAccountInformation()->withCategoryInformation(); | ||||
|   | ||||
| @@ -40,8 +40,6 @@ class ConfigurationController extends Controller | ||||
| { | ||||
|     /** | ||||
|      * ConfigurationController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -62,6 +60,7 @@ class ConfigurationController extends Controller | ||||
|      * Show configuration index. | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
|      */ | ||||
| @@ -86,10 +85,6 @@ class ConfigurationController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Store new configuration values. | ||||
|      * | ||||
|      * @param ConfigurationRequest $request | ||||
|      * | ||||
|      * @return RedirectResponse | ||||
|      */ | ||||
|     public function postIndex(ConfigurationRequest $request): RedirectResponse | ||||
|     { | ||||
|   | ||||
| @@ -44,8 +44,6 @@ class HomeController extends Controller | ||||
| { | ||||
|     /** | ||||
|      * ConfigurationController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -57,6 +55,7 @@ class HomeController extends Controller | ||||
|      * Index of the admin. | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
|      */ | ||||
| @@ -81,11 +80,6 @@ class HomeController extends Controller | ||||
|         return view('admin.index', compact('title', 'mainTitleIcon', 'email', 'notifications', 'slackUrl')); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return RedirectResponse | ||||
|      */ | ||||
|     public function notifications(Request $request): RedirectResponse | ||||
|     { | ||||
|         foreach (config('firefly.admin_notifications') as $item) { | ||||
| @@ -104,17 +98,19 @@ class HomeController extends Controller | ||||
|         } | ||||
| 
 | ||||
|         session()->flash('success', (string)trans('firefly.notification_settings_saved')); | ||||
| 
 | ||||
|         return redirect(route('admin.index')); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Send a test message to the admin. | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * @return Redirector|RedirectResponse | ||||
|      */ | ||||
|     public function testMessage() | ||||
|     { | ||||
|         Log::channel('audit')->info('User sends test message.'); | ||||
| 
 | ||||
|         /** @var User $user */ | ||||
|         $user = auth()->user(); | ||||
|         app('log')->debug('Now in testMessage() controller.'); | ||||
|   | ||||
| @@ -44,8 +44,6 @@ class LinkController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * LinkController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -86,10 +84,7 @@ class LinkController extends Controller | ||||
|     /** | ||||
|      * Delete a link form. | ||||
|      * | ||||
|      * @param Request  $request | ||||
|      * @param LinkType $linkType | ||||
|      * | ||||
|      * @return Factory|RedirectResponse|Redirector|View | ||||
|      * @return Factory|Redirector|RedirectResponse|View | ||||
|      */ | ||||
|     public function delete(Request $request, LinkType $linkType) | ||||
|     { | ||||
| @@ -122,10 +117,7 @@ class LinkController extends Controller | ||||
|     /** | ||||
|      * Actually destroy the link. | ||||
|      * | ||||
|      * @param Request  $request | ||||
|      * @param LinkType $linkType | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * @return Redirector|RedirectResponse | ||||
|      */ | ||||
|     public function destroy(Request $request, LinkType $linkType) | ||||
|     { | ||||
| @@ -143,10 +135,7 @@ class LinkController extends Controller | ||||
|     /** | ||||
|      * Edit a link form. | ||||
|      * | ||||
|      * @param Request  $request | ||||
|      * @param LinkType $linkType | ||||
|      * | ||||
|      * @return Factory|RedirectResponse|Redirector|View | ||||
|      * @return Factory|Redirector|RedirectResponse|View | ||||
|      */ | ||||
|     public function edit(Request $request, LinkType $linkType) | ||||
|     { | ||||
| @@ -193,8 +182,6 @@ class LinkController extends Controller | ||||
|     /** | ||||
|      * Show a single link. | ||||
|      * | ||||
|      * @param LinkType $linkType | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function show(LinkType $linkType) | ||||
| @@ -211,9 +198,7 @@ class LinkController extends Controller | ||||
|     /** | ||||
|      * Store the new link. | ||||
|      * | ||||
|      * @param LinkTypeFormRequest $request | ||||
|      * | ||||
|      * @return $this|RedirectResponse|Redirector | ||||
|      * @return $this|Redirector|RedirectResponse | ||||
|      */ | ||||
|     public function store(LinkTypeFormRequest $request) | ||||
|     { | ||||
| @@ -242,10 +227,7 @@ class LinkController extends Controller | ||||
|     /** | ||||
|      * Update an existing link. | ||||
|      * | ||||
|      * @param LinkTypeFormRequest $request | ||||
|      * @param LinkType            $linkType | ||||
|      * | ||||
|      * @return $this|RedirectResponse|Redirector | ||||
|      * @return $this|Redirector|RedirectResponse | ||||
|      */ | ||||
|     public function update(LinkTypeFormRequest $request, LinkType $linkType) | ||||
|     { | ||||
|   | ||||
| @@ -62,6 +62,7 @@ class UpdateController extends Controller | ||||
|      * Show page with update options. | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
|      */ | ||||
| @@ -91,9 +92,7 @@ class UpdateController extends Controller | ||||
|     /** | ||||
|      * Post new settings. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * @return Redirector|RedirectResponse | ||||
|      */ | ||||
|     public function post(Request $request) | ||||
|     { | ||||
|   | ||||
| @@ -69,9 +69,7 @@ class UserController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param User $user | ||||
|      * | ||||
|      * @return Application|Factory|RedirectResponse|Redirector|View | ||||
|      * @return Application|Factory|Redirector|RedirectResponse|View | ||||
|      */ | ||||
|     public function delete(User $user) | ||||
|     { | ||||
| @@ -86,31 +84,26 @@ class UserController extends Controller | ||||
|         return view('admin.users.delete', compact('user', 'subTitle')); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param InvitedUser $invitedUser | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function deleteInvite(InvitedUser $invitedUser): JsonResponse | ||||
|     { | ||||
|         app('log')->debug('Will now delete invitation'); | ||||
|         if ($invitedUser->redeemed) { | ||||
|             app('log')->debug('Is already redeemed.'); | ||||
|             session()->flash('error', trans('firefly.invite_is_already_redeemed', ['address' => $invitedUser->email])); | ||||
| 
 | ||||
|             return response()->json(['success' => false]); | ||||
|         } | ||||
|         app('log')->debug('Delete!'); | ||||
|         session()->flash('success', trans('firefly.invite_is_deleted', ['address' => $invitedUser->email])); | ||||
|         $this->repository->deleteInvite($invitedUser); | ||||
| 
 | ||||
|         return response()->json(['success' => true]); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Destroy a user. | ||||
|      * | ||||
|      * @param User $user | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * @return Redirector|RedirectResponse | ||||
|      */ | ||||
|     public function destroy(User $user) | ||||
|     { | ||||
| @@ -128,8 +121,6 @@ class UserController extends Controller | ||||
|     /** | ||||
|      * Edit user form. | ||||
|      * | ||||
|      * @param User $user | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function edit(User $user) | ||||
| @@ -162,6 +153,7 @@ class UserController extends Controller | ||||
|      * Show index of user manager. | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
|      */ | ||||
| @@ -190,11 +182,6 @@ class UserController extends Controller | ||||
|         return view('admin.users.index', compact('subTitle', 'subTitleIcon', 'users', 'allowInvites', 'invitedUsers')); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param InviteUserFormRequest $request | ||||
|      * | ||||
|      * @return RedirectResponse | ||||
|      */ | ||||
|     public function invite(InviteUserFormRequest $request): RedirectResponse | ||||
|     { | ||||
|         $address = (string)$request->get('invited_user'); | ||||
| @@ -210,8 +197,6 @@ class UserController extends Controller | ||||
|     /** | ||||
|      * Show single user. | ||||
|      * | ||||
|      * @param User $user | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function show(User $user) | ||||
| @@ -238,17 +223,14 @@ class UserController extends Controller | ||||
|     /** | ||||
|      * Update single user. | ||||
|      * | ||||
|      * @param UserFormRequest $request | ||||
|      * @param User            $user | ||||
|      * | ||||
|      * @return $this|RedirectResponse|Redirector | ||||
|      * @return $this|Redirector|RedirectResponse | ||||
|      */ | ||||
|     public function update(UserFormRequest $request, User $user) | ||||
|     { | ||||
|         app('log')->debug('Actually here'); | ||||
|         $data = $request->getUserData(); | ||||
| 
 | ||||
|         //var_dump($data);
 | ||||
|         // var_dump($data);
 | ||||
| 
 | ||||
|         // update password
 | ||||
|         if (array_key_exists('password', $data) && '' !== $data['password']) { | ||||
|   | ||||
| @@ -37,7 +37,6 @@ use Illuminate\View\View; | ||||
| 
 | ||||
| /** | ||||
|  * Class AttachmentController. | ||||
|  * | ||||
|  */ | ||||
| class AttachmentController extends Controller | ||||
| { | ||||
| @@ -45,8 +44,6 @@ class AttachmentController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * AttachmentController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -67,8 +64,6 @@ class AttachmentController extends Controller | ||||
|     /** | ||||
|      * Form to delete an attachment. | ||||
|      * | ||||
|      * @param Attachment $attachment | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function delete(Attachment $attachment) | ||||
| @@ -84,10 +79,7 @@ class AttachmentController extends Controller | ||||
|     /** | ||||
|      * Destroy attachment. | ||||
|      * | ||||
|      * @param Request    $request | ||||
|      * @param Attachment $attachment | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * @return Redirector|RedirectResponse | ||||
|      */ | ||||
|     public function destroy(Request $request, Attachment $attachment) | ||||
|     { | ||||
| @@ -104,8 +96,6 @@ class AttachmentController extends Controller | ||||
|     /** | ||||
|      * Download attachment to PC. | ||||
|      * | ||||
|      * @param Attachment $attachment | ||||
|      * | ||||
|      * @return LaravelResponse | ||||
|      * | ||||
|      * @throws FireflyException | ||||
| @@ -121,25 +111,24 @@ class AttachmentController extends Controller | ||||
|             $response | ||||
|                 ->header('Content-Description', 'File Transfer') | ||||
|                 ->header('Content-Type', 'application/octet-stream') | ||||
|                 ->header('Content-Disposition', 'attachment; filename=' . $quoted) | ||||
|                 ->header('Content-Disposition', 'attachment; filename='.$quoted) | ||||
|                 ->header('Content-Transfer-Encoding', 'binary') | ||||
|                 ->header('Connection', 'Keep-Alive') | ||||
|                 ->header('Expires', '0') | ||||
|                 ->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0') | ||||
|                 ->header('Pragma', 'public') | ||||
|                 ->header('Content-Length', (string)strlen($content)); | ||||
|                 ->header('Content-Length', (string)strlen($content)) | ||||
|             ; | ||||
| 
 | ||||
|             return $response; | ||||
|         } | ||||
| 
 | ||||
|         throw new FireflyException('Could not find the indicated attachment. The file is no longer there.'); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Edit an attachment. | ||||
|      * | ||||
|      * @param Request    $request | ||||
|      * @param Attachment $attachment | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function edit(Request $request, Attachment $attachment) | ||||
| @@ -181,11 +170,6 @@ class AttachmentController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Update attachment. | ||||
|      * | ||||
|      * @param AttachmentFormRequest $request | ||||
|      * @param Attachment            $attachment | ||||
|      * | ||||
|      * @return RedirectResponse | ||||
|      */ | ||||
|     public function update(AttachmentFormRequest $request, Attachment $attachment): RedirectResponse | ||||
|     { | ||||
| @@ -209,9 +193,6 @@ class AttachmentController extends Controller | ||||
|     /** | ||||
|      * View attachment in browser. | ||||
|      * | ||||
|      * @param Attachment $attachment | ||||
|      * | ||||
|      * @return LaravelResponse | ||||
|      * @throws FireflyException | ||||
|      * @throws BindingResolutionException | ||||
|      */ | ||||
| @@ -239,10 +220,11 @@ class AttachmentController extends Controller | ||||
|                 [ | ||||
|                     'Content-Security-Policy' => implode('; ', $csp), | ||||
|                     'Content-Type'            => $attachment->mime, | ||||
|                     'Content-Disposition'     => 'inline; filename="' . $attachment->filename . '"', | ||||
|                     'Content-Disposition'     => 'inline; filename="'.$attachment->filename.'"', | ||||
|                 ] | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         throw new FireflyException('Could not find the indicated attachment. The file is no longer there.'); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -37,8 +37,6 @@ use Psr\Container\NotFoundExceptionInterface; | ||||
| 
 | ||||
| /** | ||||
|  * Class ForgotPasswordController | ||||
|  * | ||||
| 
 | ||||
|  */ | ||||
| class ForgotPasswordController extends Controller | ||||
| { | ||||
| @@ -60,9 +58,6 @@ class ForgotPasswordController extends Controller | ||||
|     /** | ||||
|      * Send a reset link to the given user. | ||||
|      * | ||||
|      * @param Request                 $request | ||||
|      * @param UserRepositoryInterface $repository | ||||
|      * | ||||
|      * @return Factory|RedirectResponse|View | ||||
|      */ | ||||
|     public function sendResetLinkEmail(Request $request, UserRepositoryInterface $repository) | ||||
| @@ -75,11 +70,10 @@ class ForgotPasswordController extends Controller | ||||
|             return view('error', compact('message')); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         $this->validateEmail($request); | ||||
| 
 | ||||
|         // verify if the user is not a demo user. If so, we give him back an error.
 | ||||
|         /** @var User|null $user */ | ||||
|         /** @var null|User $user */ | ||||
|         $user = User::where('email', $request->get('email'))->first(); | ||||
| 
 | ||||
|         if (null !== $user && $repository->hasRole($user, 'demo')) { | ||||
| @@ -103,8 +97,8 @@ class ForgotPasswordController extends Controller | ||||
|     /** | ||||
|      * Show form for email recovery. | ||||
|      * | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
|   | ||||
| @@ -24,7 +24,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Http\Controllers\Auth; | ||||
| 
 | ||||
| use Cookie; | ||||
| use DB; | ||||
| use FireflyIII\Events\ActuallyLoggedIn; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Http\Controllers\Controller; | ||||
| @@ -50,8 +49,6 @@ use Psr\Container\NotFoundExceptionInterface; | ||||
|  * This controller handles authenticating users for the application and | ||||
|  * redirecting them to your home screen. The controller uses a trait | ||||
|  * to conveniently provide its functionality to your applications. | ||||
|  * | ||||
| 
 | ||||
|  */ | ||||
| class LoginController extends Controller | ||||
| { | ||||
| @@ -60,8 +57,6 @@ class LoginController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Where to redirect users after login. | ||||
|      * | ||||
|      * @var string | ||||
|      */ | ||||
|     protected string $redirectTo = RouteServiceProvider::HOME; | ||||
| 
 | ||||
| @@ -69,8 +64,6 @@ class LoginController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Create a new controller instance. | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -82,10 +75,9 @@ class LoginController extends Controller | ||||
|     /** | ||||
|      * Handle a login request to the application. | ||||
|      * | ||||
|      * @return JsonResponse|RedirectResponse | ||||
|      * @throws ValidationException | ||||
|      */ | ||||
|     public function login(Request $request): JsonResponse | RedirectResponse | ||||
|     public function login(Request $request): JsonResponse|RedirectResponse | ||||
|     { | ||||
|         Log::channel('audit')->info(sprintf('User is trying to login using "%s"', $request->get($this->username()))); | ||||
|         app('log')->info('User is trying to login.'); | ||||
| @@ -93,7 +85,7 @@ class LoginController extends Controller | ||||
|         $this->validateLogin($request); | ||||
|         app('log')->debug('Login data is present.'); | ||||
| 
 | ||||
|         /** Copied directly from AuthenticatesUsers, but with logging added: */ | ||||
|         // Copied directly from AuthenticatesUsers, but with logging added:
 | ||||
|         // If the class is using the ThrottlesLogins trait, we can automatically throttle
 | ||||
|         // the login attempts for this application. We'll key this by the username and
 | ||||
|         // the IP address of the client making these requests into this application.
 | ||||
| @@ -104,7 +96,7 @@ class LoginController extends Controller | ||||
| 
 | ||||
|             $this->sendLockoutResponse($request); | ||||
|         } | ||||
|         /** Copied directly from AuthenticatesUsers, but with logging added: */ | ||||
|         // Copied directly from AuthenticatesUsers, but with logging added:
 | ||||
|         if ($this->attemptLogin($request)) { | ||||
|             Log::channel('audit')->info(sprintf('User "%s" has been logged in.', $request->get($this->username()))); | ||||
|             app('log')->debug(sprintf('Redirect after login is %s.', $this->redirectPath())); | ||||
| @@ -119,7 +111,7 @@ class LoginController extends Controller | ||||
|         } | ||||
|         app('log')->warning('Login attempt failed.'); | ||||
| 
 | ||||
|         /** Copied directly from AuthenticatesUsers, but with logging added: */ | ||||
|         // Copied directly from AuthenticatesUsers, but with logging added:
 | ||||
|         // If the login attempt was unsuccessful we will increment the number of attempts
 | ||||
|         // to login and redirect the user back to the login form. Of course, when this
 | ||||
|         // user surpasses their maximum number of attempts they will get locked out.
 | ||||
| @@ -128,7 +120,7 @@ class LoginController extends Controller | ||||
| 
 | ||||
|         $this->sendFailedLoginResponse($request); | ||||
| 
 | ||||
|         /** @noinspection PhpUnreachableStatementInspection */ | ||||
|         // @noinspection PhpUnreachableStatementInspection
 | ||||
|         return response()->json([]); | ||||
|     } | ||||
| 
 | ||||
| @@ -142,33 +134,10 @@ class LoginController extends Controller | ||||
|         return $this->username; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get the failed login response instance. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return void | ||||
|      * @SuppressWarnings(PHPMD.UnusedFormalParameter) | ||||
|      * @throws ValidationException | ||||
|      */ | ||||
|     protected function sendFailedLoginResponse(Request $request) | ||||
|     { | ||||
|         $exception             = ValidationException::withMessages( | ||||
|             [ | ||||
|                 $this->username() => [trans('auth.failed')], | ||||
|             ] | ||||
|         ); | ||||
|         $exception->redirectTo = route('login'); | ||||
| 
 | ||||
|         throw $exception; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Log the user out of the application. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector|Response | ||||
|      * @return Redirector|RedirectResponse|Response | ||||
|      */ | ||||
|     public function logout(Request $request) | ||||
|     { | ||||
| @@ -183,7 +152,7 @@ class LoginController extends Controller | ||||
| 
 | ||||
|         // also logout current 2FA tokens.
 | ||||
|         $cookieName = config('google2fa.cookie_name', 'google2fa_token'); | ||||
|         Cookie::forget($cookieName); | ||||
|         \Cookie::forget($cookieName); | ||||
| 
 | ||||
|         $this->guard()->logout(); | ||||
| 
 | ||||
| @@ -201,9 +170,8 @@ class LoginController extends Controller | ||||
|     /** | ||||
|      * Show the application's login form. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * @return Application|Factory|Redirector|RedirectResponse|View | ||||
|      * | ||||
|      * @return Factory|Application|View|Redirector|RedirectResponse | ||||
|      * @throws FireflyException | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
| @@ -212,7 +180,7 @@ class LoginController extends Controller | ||||
|     { | ||||
|         Log::channel('audit')->info('Show login form (1.1).'); | ||||
| 
 | ||||
|         $count = DB::table('users')->count(); | ||||
|         $count = \DB::table('users')->count(); | ||||
|         $guard = config('auth.defaults.guard'); | ||||
|         $title = (string)trans('firefly.login_page_title'); | ||||
| 
 | ||||
| @@ -246,4 +214,23 @@ class LoginController extends Controller | ||||
| 
 | ||||
|         return view('auth.login', compact('allowRegistration', 'email', 'remember', 'allowReset', 'title', 'usernameField')); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get the failed login response instance. | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.UnusedFormalParameter) | ||||
|      * | ||||
|      * @throws ValidationException | ||||
|      */ | ||||
|     protected function sendFailedLoginResponse(Request $request) | ||||
|     { | ||||
|         $exception             = ValidationException::withMessages( | ||||
|             [ | ||||
|                 $this->username() => [trans('auth.failed')], | ||||
|             ] | ||||
|         ); | ||||
|         $exception->redirectTo = route('login'); | ||||
| 
 | ||||
|         throw $exception; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -46,8 +46,6 @@ use Psr\Container\NotFoundExceptionInterface; | ||||
|  * This controller handles the registration of new users as well as their | ||||
|  * validation and creation. By default this controller uses a trait to | ||||
|  * provide this functionality without requiring any additional code. | ||||
|  * | ||||
| 
 | ||||
|  */ | ||||
| class RegisterController extends Controller | ||||
| { | ||||
| @@ -77,9 +75,8 @@ class RegisterController extends Controller | ||||
|     /** | ||||
|      * Handle a registration request for the application. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return Application|Redirector|RedirectResponse | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * @throws ValidationException | ||||
|      */ | ||||
| @@ -94,7 +91,6 @@ class RegisterController extends Controller | ||||
|             throw new FireflyException('Registration is currently not available :('); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         $this->validator($request->all())->validate(); | ||||
|         $user = $this->createUser($request->all()); | ||||
|         app('log')->info(sprintf('Registered new user %s', $user->email)); | ||||
| @@ -113,35 +109,11 @@ class RegisterController extends Controller | ||||
|         return redirect($this->redirectPath()); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @return bool | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     protected function allowedToRegister(): bool | ||||
|     { | ||||
|         // is allowed to register?
 | ||||
|         $allowRegistration = true; | ||||
|         try { | ||||
|             $singleUserMode = app('fireflyconfig')->get('single_user_mode', config('firefly.configuration.single_user_mode'))->data; | ||||
|         } catch (ContainerExceptionInterface | NotFoundExceptionInterface $e) { | ||||
|             $singleUserMode = true; | ||||
|         } | ||||
|         $userCount = User::count(); | ||||
|         $guard     = config('auth.defaults.guard'); | ||||
|         if (true === $singleUserMode && $userCount > 0 && 'web' === $guard) { | ||||
|             $allowRegistration = false; | ||||
|         } | ||||
|         if ('web' !== $guard) { | ||||
|             $allowRegistration = false; | ||||
|         } | ||||
|         return $allowRegistration; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Show the application registration form if the invitation code is valid. | ||||
|      * | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws FireflyException | ||||
|      * @throws NotFoundExceptionInterface | ||||
| @@ -174,9 +146,8 @@ class RegisterController extends Controller | ||||
|     /** | ||||
|      * Show the application registration form. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws FireflyException | ||||
|      * @throws NotFoundExceptionInterface | ||||
| @@ -197,4 +168,29 @@ class RegisterController extends Controller | ||||
| 
 | ||||
|         return view('auth.register', compact('isDemoSite', 'email', 'pageTitle')); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     protected function allowedToRegister(): bool | ||||
|     { | ||||
|         // is allowed to register?
 | ||||
|         $allowRegistration = true; | ||||
| 
 | ||||
|         try { | ||||
|             $singleUserMode = app('fireflyconfig')->get('single_user_mode', config('firefly.configuration.single_user_mode'))->data; | ||||
|         } catch (ContainerExceptionInterface|NotFoundExceptionInterface $e) { | ||||
|             $singleUserMode = true; | ||||
|         } | ||||
|         $userCount = User::count(); | ||||
|         $guard     = config('auth.defaults.guard'); | ||||
|         if (true === $singleUserMode && $userCount > 0 && 'web' === $guard) { | ||||
|             $allowRegistration = false; | ||||
|         } | ||||
|         if ('web' !== $guard) { | ||||
|             $allowRegistration = false; | ||||
|         } | ||||
| 
 | ||||
|         return $allowRegistration; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -43,8 +43,6 @@ use Psr\Container\NotFoundExceptionInterface; | ||||
|  * This controller is responsible for handling password reset requests | ||||
|  * and uses a simple trait to include this behavior. You're free to | ||||
|  * explore this trait and override any methods you wish to tweak. | ||||
|  * | ||||
| 
 | ||||
|  */ | ||||
| class ResetPasswordController extends Controller | ||||
| { | ||||
| @@ -73,11 +71,9 @@ class ResetPasswordController extends Controller | ||||
|     /** | ||||
|      * Reset the given user's password. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return Factory|JsonResponse|RedirectResponse|View | ||||
|      * @throws ValidationException | ||||
|      * | ||||
|      * @throws ValidationException | ||||
|      */ | ||||
|     public function reset(Request $request) | ||||
|     { | ||||
| @@ -107,7 +103,7 @@ class ResetPasswordController extends Controller | ||||
|         // If the password was successfully reset, we will redirect the user back to
 | ||||
|         // the application's home authenticated view. If there is an error we can
 | ||||
|         // redirect them back to where they came from with their error message.
 | ||||
|         return $response === Password::PASSWORD_RESET | ||||
|         return Password::PASSWORD_RESET === $response | ||||
|             ? $this->sendResetResponse($request, $response) | ||||
|             : $this->sendResetFailedResponse($request, $response); | ||||
|     } | ||||
| @@ -117,10 +113,10 @@ class ResetPasswordController extends Controller | ||||
|      * | ||||
|      * If no token is present, display the link request form. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * @param null    $token | ||||
|      * @param null $token | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
|   | ||||
| @@ -54,9 +54,7 @@ class TwoFactorController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * @return Redirector|RedirectResponse | ||||
|      */ | ||||
|     public function submitMFA(Request $request) | ||||
|     { | ||||
| @@ -101,11 +99,6 @@ class TwoFactorController extends Controller | ||||
|     /** | ||||
|      * Each MFA history has a timestamp and a code, saving the MFA entries for 5 minutes. So if the | ||||
|      * submitted MFA code has been submitted in the last 5 minutes, it won't work despite being valid. | ||||
|      * | ||||
|      * @param string $mfaCode | ||||
|      * @param array  $mfaHistory | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     private function inMFAHistory(string $mfaCode, array $mfaHistory): bool | ||||
|     { | ||||
| @@ -143,9 +136,6 @@ class TwoFactorController extends Controller | ||||
|         app('preferences')->set('mfa_history', $newHistory); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param string $mfaCode | ||||
|      */ | ||||
|     private function addToMFAHistory(string $mfaCode): void | ||||
|     { | ||||
|         /** @var array $mfaHistory */ | ||||
| @@ -162,10 +152,6 @@ class TwoFactorController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Checks if code is in users backup codes. | ||||
|      * | ||||
|      * @param string $mfaCode | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     private function isBackupCode(string $mfaCode): bool | ||||
|     { | ||||
| @@ -182,8 +168,6 @@ class TwoFactorController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Remove the used code from the list of backup codes. | ||||
|      * | ||||
|      * @param string $mfaCode | ||||
|      */ | ||||
|     private function removeFromBackupCodes(string $mfaCode): void | ||||
|     { | ||||
|   | ||||
| @@ -44,8 +44,6 @@ class CreateController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * BillController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -66,17 +64,16 @@ class CreateController extends Controller | ||||
|     /** | ||||
|      * Create a new bill. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function create(Request $request) | ||||
|     { | ||||
|         $periods = []; | ||||
| 
 | ||||
|         /** @var array $billPeriods */ | ||||
|         $billPeriods = config('firefly.bill_periods'); | ||||
|         foreach ($billPeriods as $current) { | ||||
|             $periods[$current] = (string)trans('firefly.repeat_freq_' . $current); | ||||
|             $periods[$current] = (string)trans('firefly.repeat_freq_'.$current); | ||||
|         } | ||||
|         $subTitle        = (string)trans('firefly.create_new_bill'); | ||||
|         $defaultCurrency = app('amount')->getDefaultCurrency(); | ||||
| @@ -92,17 +89,13 @@ class CreateController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Store a new bill. | ||||
|      * | ||||
|      * @param BillStoreRequest $request | ||||
|      * | ||||
|      * @return RedirectResponse | ||||
|      * | ||||
|      */ | ||||
|     public function store(BillStoreRequest $request): RedirectResponse | ||||
|     { | ||||
|         $billData = $request->getBillData(); | ||||
| 
 | ||||
|         $billData['active'] = true; | ||||
| 
 | ||||
|         try { | ||||
|             $bill = $this->repository->store($billData); | ||||
|         } catch (FireflyException $e) { | ||||
| @@ -114,7 +107,7 @@ class CreateController extends Controller | ||||
|         $request->session()->flash('success', (string)trans('firefly.stored_new_bill', ['name' => $bill->name])); | ||||
|         app('preferences')->mark(); | ||||
| 
 | ||||
|         /** @var array|null $files */ | ||||
|         /** @var null|array $files */ | ||||
|         $files = $request->hasFile('attachments') ? $request->file('attachments') : null; | ||||
|         if (null !== $files && !auth()->user()->hasRole('demo')) { | ||||
|             $this->attachments->saveAttachmentsForModel($bill, $files); | ||||
|   | ||||
| @@ -42,8 +42,6 @@ class DeleteController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * BillController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -65,8 +63,6 @@ class DeleteController extends Controller | ||||
|     /** | ||||
|      * Delete a bill. | ||||
|      * | ||||
|      * @param Bill $bill | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function delete(Bill $bill) | ||||
| @@ -81,10 +77,7 @@ class DeleteController extends Controller | ||||
|     /** | ||||
|      * Destroy a bill. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * @param Bill    $bill | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * @return Redirector|RedirectResponse | ||||
|      */ | ||||
|     public function destroy(Request $request, Bill $bill) | ||||
|     { | ||||
|   | ||||
| @@ -44,8 +44,6 @@ class EditController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * BillController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -66,19 +64,17 @@ class EditController extends Controller | ||||
|     /** | ||||
|      * Edit a bill. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * @param Bill    $bill | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function edit(Request $request, Bill $bill) | ||||
|     { | ||||
|         $periods = []; | ||||
| 
 | ||||
|         /** @var array $billPeriods */ | ||||
|         $billPeriods = config('firefly.bill_periods'); | ||||
| 
 | ||||
|         foreach ($billPeriods as $current) { | ||||
|             $periods[$current] = (string)trans('firefly.' . $current); | ||||
|             $periods[$current] = (string)trans('firefly.'.$current); | ||||
|         } | ||||
| 
 | ||||
|         $subTitle = (string)trans('firefly.edit_bill', ['name' => $bill->name]); | ||||
| @@ -114,11 +110,6 @@ class EditController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Update a bill. | ||||
|      * | ||||
|      * @param BillUpdateRequest $request | ||||
|      * @param Bill              $bill | ||||
|      * | ||||
|      * @return RedirectResponse | ||||
|      */ | ||||
|     public function update(BillUpdateRequest $request, Bill $bill): RedirectResponse | ||||
|     { | ||||
| @@ -128,7 +119,7 @@ class EditController extends Controller | ||||
|         $request->session()->flash('success', (string)trans('firefly.updated_bill', ['name' => $bill->name])); | ||||
|         app('preferences')->mark(); | ||||
| 
 | ||||
|         /** @var array|null $files */ | ||||
|         /** @var null|array $files */ | ||||
|         $files = $request->hasFile('attachments') ? $request->file('attachments') : null; | ||||
|         if (null !== $files && !auth()->user()->hasRole('demo')) { | ||||
|             $this->attachments->saveAttachmentsForModel($bill, $files); | ||||
|   | ||||
| @@ -50,8 +50,6 @@ class IndexController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * BillController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -71,7 +69,7 @@ class IndexController extends Controller | ||||
|     /** | ||||
|      * Show all bills. | ||||
|      */ | ||||
|     public function index(): View | Application | Factory | \Illuminate\Contracts\Foundation\Application | ||||
|     public function index(): Application|Factory|\Illuminate\Contracts\Foundation\Application|View | ||||
|     { | ||||
|         $this->cleanupObjectGroups(); | ||||
|         $this->repository->correctOrder(); | ||||
| @@ -85,7 +83,7 @@ class IndexController extends Controller | ||||
|         // sub one day from temp start so the last paid date is one day before it should be.
 | ||||
|         $tempStart = clone $start; | ||||
|         // 2023-06-23 do not sub one day from temp start, fix is in BillTransformer::payDates instead
 | ||||
|         //$tempStart->subDay();
 | ||||
|         // $tempStart->subDay();
 | ||||
|         $parameters->set('start', $tempStart); | ||||
|         $parameters->set('end', $end); | ||||
| 
 | ||||
| @@ -99,11 +97,12 @@ class IndexController extends Controller | ||||
|         // make bill groups:
 | ||||
|         $bills = [ | ||||
|             0 => [ // the index is the order, not the ID.
 | ||||
|                    'object_group_id'    => 0, | ||||
|                    'object_group_title' => (string)trans('firefly.default_group_title_name'), | ||||
|                    'bills'              => [], | ||||
|                 'object_group_id'    => 0, | ||||
|                 'object_group_title' => (string)trans('firefly.default_group_title_name'), | ||||
|                 'bills'              => [], | ||||
|             ], | ||||
|         ]; | ||||
| 
 | ||||
|         /** @var Bill $bill */ | ||||
|         foreach ($collection as $bill) { | ||||
|             $array      = $transformer->transform($bill); | ||||
| @@ -138,9 +137,24 @@ class IndexController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param array $bills | ||||
|      * | ||||
|      * @return array | ||||
|      * Set the order of a bill. | ||||
|      */ | ||||
|     public function setOrder(Request $request, Bill $bill): JsonResponse | ||||
|     { | ||||
|         $objectGroupTitle = (string)$request->get('objectGroupTitle'); | ||||
|         $newOrder         = (int)$request->get('order'); | ||||
|         $this->repository->setOrder($bill, $newOrder); | ||||
|         if ('' !== $objectGroupTitle) { | ||||
|             $this->repository->setObjectGroup($bill, $objectGroupTitle); | ||||
|         } | ||||
|         if ('' === $objectGroupTitle) { | ||||
|             $this->repository->removeObjectGroup($bill); | ||||
|         } | ||||
| 
 | ||||
|         return response()->json(['data' => 'OK']); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @throws FireflyException | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
| @@ -180,15 +194,10 @@ class IndexController extends Controller | ||||
|                 $sums[$groupOrder][$currencyId]['per_period'] = bcadd($sums[$groupOrder][$currencyId]['per_period'], $this->amountPerPeriod($bill, $range)); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return $sums; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param array  $bill | ||||
|      * @param string $range | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     private function amountPerPeriod(array $bill, string $range): string | ||||
|     { | ||||
|         $avg = bcdiv(bcadd((string)$bill['amount_min'], (string)$bill['amount_max']), '2'); | ||||
| @@ -230,17 +239,13 @@ class IndexController extends Controller | ||||
|         return $perPeriod; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param array $sums | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     private function getTotals(array $sums): array | ||||
|     { | ||||
|         $totals = []; | ||||
|         if (count($sums) < 2) { | ||||
|             return []; | ||||
|         } | ||||
| 
 | ||||
|         /** | ||||
|          * @var array $array | ||||
|          */ | ||||
| @@ -267,27 +272,4 @@ class IndexController extends Controller | ||||
| 
 | ||||
|         return $totals; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Set the order of a bill. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * @param Bill    $bill | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function setOrder(Request $request, Bill $bill): JsonResponse | ||||
|     { | ||||
|         $objectGroupTitle = (string)$request->get('objectGroupTitle'); | ||||
|         $newOrder         = (int)$request->get('order'); | ||||
|         $this->repository->setOrder($bill, $newOrder); | ||||
|         if ('' !== $objectGroupTitle) { | ||||
|             $this->repository->setObjectGroup($bill, $objectGroupTitle); | ||||
|         } | ||||
|         if ('' === $objectGroupTitle) { | ||||
|             $this->repository->removeObjectGroup($bill); | ||||
|         } | ||||
| 
 | ||||
|         return response()->json(['data' => 'OK']); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -54,8 +54,6 @@ class ShowController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * BillController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -77,10 +75,7 @@ class ShowController extends Controller | ||||
|     /** | ||||
|      * Rescan bills for transactions. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * @param Bill    $bill | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * @return Redirector|RedirectResponse | ||||
|      */ | ||||
|     public function rescan(Request $request, Bill $bill) | ||||
|     { | ||||
| @@ -117,10 +112,8 @@ class ShowController extends Controller | ||||
|     /** | ||||
|      * Show a bill. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * @param Bill    $bill | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
|      */ | ||||
| @@ -129,8 +122,10 @@ class ShowController extends Controller | ||||
|         // add info about rules:
 | ||||
|         $rules    = $this->repository->getRulesForBill($bill); | ||||
|         $subTitle = $bill->name; | ||||
| 
 | ||||
|         /** @var Carbon $start */ | ||||
|         $start = session('start'); | ||||
| 
 | ||||
|         /** @var Carbon $end */ | ||||
|         $end            = session('end'); | ||||
|         $year           = $start->year; | ||||
| @@ -159,11 +154,11 @@ class ShowController extends Controller | ||||
|         $object                     = $manager->createData($resource)->toArray(); | ||||
|         $object['data']['currency'] = $bill->transactionCurrency; | ||||
| 
 | ||||
| 
 | ||||
|         /** @var GroupCollectorInterface $collector */ | ||||
|         $collector = app(GroupCollectorInterface::class); | ||||
|         $collector->setBill($bill)->setLimit($pageSize)->setPage($page)->withBudgetInformation() | ||||
|                   ->withCategoryInformation()->withAccountInformation(); | ||||
|             ->withCategoryInformation()->withAccountInformation() | ||||
|         ; | ||||
|         $groups = $collector->getPaginatedGroups(); | ||||
|         $groups->setPath(route('bills.show', [$bill->id])); | ||||
| 
 | ||||
| @@ -171,7 +166,6 @@ class ShowController extends Controller | ||||
|         $collection  = $this->repository->getAttachments($bill); | ||||
|         $attachments = new Collection(); | ||||
| 
 | ||||
| 
 | ||||
|         if ($collection->count() > 0) { | ||||
|             /** @var AttachmentTransformer $transformer */ | ||||
|             $transformer = app(AttachmentTransformer::class); | ||||
| @@ -182,7 +176,6 @@ class ShowController extends Controller | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         return view('bills.show', compact('attachments', 'groups', 'rules', 'yearAverage', 'overallAverage', 'year', 'object', 'bill', 'subTitle')); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -43,7 +43,6 @@ use Illuminate\Support\Collection; | ||||
| use Illuminate\View\View; | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * Class BudgetLimitController | ||||
|  */ | ||||
| class BudgetLimitController extends Controller | ||||
| @@ -76,10 +75,6 @@ class BudgetLimitController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Budget $budget | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function create(Budget $budget, Carbon $start, Carbon $end) | ||||
| @@ -106,9 +101,7 @@ class BudgetLimitController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param BudgetLimit $budgetLimit | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * @return Redirector|RedirectResponse | ||||
|      */ | ||||
|     public function delete(BudgetLimit $budgetLimit) | ||||
|     { | ||||
| @@ -121,12 +114,9 @@ class BudgetLimitController extends Controller | ||||
|     /** | ||||
|      * TODO why redirect AND json response? | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return RedirectResponse|JsonResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function store(Request $request): RedirectResponse | JsonResponse | ||||
|     public function store(Request $request): JsonResponse|RedirectResponse | ||||
|     { | ||||
|         app('log')->debug('Going to store new budget-limit.', $request->all()); | ||||
|         // first search for existing one and update it if necessary.
 | ||||
| @@ -159,6 +149,7 @@ class BudgetLimitController extends Controller | ||||
|             if (null !== $limit) { | ||||
|                 $this->blRepository->destroyBudgetLimit($limit); | ||||
|             } | ||||
| 
 | ||||
|             // return empty=ish array:
 | ||||
|             return response()->json([]); | ||||
|         } | ||||
| @@ -205,12 +196,6 @@ class BudgetLimitController extends Controller | ||||
|         return redirect(route('budgets.index')); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Request     $request | ||||
|      * @param BudgetLimit $budgetLimit | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function update(Request $request, BudgetLimit $budgetLimit): JsonResponse | ||||
|     { | ||||
|         $amount = (string)$request->get('amount'); | ||||
| @@ -229,6 +214,7 @@ class BudgetLimitController extends Controller | ||||
|                 'left_per_day_formatted'  => app('amount')->formatAnything($currency, '0'), | ||||
|                 'transaction_currency_id' => $currency->id, | ||||
|             ]; | ||||
| 
 | ||||
|             return response()->json($array); | ||||
|         } | ||||
|         if ((int)$amount > 268435456) { // 268 million, intentional integer
 | ||||
|   | ||||
| @@ -44,8 +44,6 @@ class CreateController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * CreateController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -65,8 +63,6 @@ class CreateController extends Controller | ||||
|     /** | ||||
|      * Form to create a budget. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function create(Request $request) | ||||
| @@ -110,9 +106,6 @@ class CreateController extends Controller | ||||
|     /** | ||||
|      * Stores a budget. | ||||
|      * | ||||
|      * @param BudgetFormStoreRequest $request | ||||
|      * | ||||
|      * @return RedirectResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function store(BudgetFormStoreRequest $request): RedirectResponse | ||||
| @@ -125,7 +118,7 @@ class CreateController extends Controller | ||||
|         app('preferences')->mark(); | ||||
| 
 | ||||
|         // store attachment(s):
 | ||||
|         /** @var array|null $files */ | ||||
|         /** @var null|array $files */ | ||||
|         $files = $request->hasFile('attachments') ? $request->file('attachments') : null; | ||||
|         if (null !== $files && !auth()->user()->hasRole('demo')) { | ||||
|             $this->attachments->saveAttachmentsForModel($budget, $files); | ||||
|   | ||||
| @@ -33,7 +33,6 @@ use Illuminate\Routing\Redirector; | ||||
| use Illuminate\View\View; | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * Class DeleteController | ||||
|  */ | ||||
| class DeleteController extends Controller | ||||
| @@ -43,8 +42,6 @@ class DeleteController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * DeleteController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -64,8 +61,6 @@ class DeleteController extends Controller | ||||
|     /** | ||||
|      * Deletes a budget. | ||||
|      * | ||||
|      * @param Budget $budget | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function delete(Budget $budget) | ||||
| @@ -81,10 +76,7 @@ class DeleteController extends Controller | ||||
|     /** | ||||
|      * Destroys a budget. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * @param Budget  $budget | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * @return Redirector|RedirectResponse | ||||
|      */ | ||||
|     public function destroy(Request $request, Budget $budget) | ||||
|     { | ||||
|   | ||||
| @@ -35,7 +35,6 @@ use Illuminate\Http\Request; | ||||
| use Illuminate\View\View; | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * Class EditController | ||||
|  */ | ||||
| class EditController extends Controller | ||||
| @@ -45,8 +44,6 @@ class EditController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * EditController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -67,9 +64,6 @@ class EditController extends Controller | ||||
|     /** | ||||
|      * Budget edit form. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * @param Budget  $budget | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function edit(Request $request, Budget $budget) | ||||
| @@ -121,11 +115,6 @@ class EditController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Budget update routine. | ||||
|      * | ||||
|      * @param BudgetFormUpdateRequest $request | ||||
|      * @param Budget                  $budget | ||||
|      * | ||||
|      * @return RedirectResponse | ||||
|      */ | ||||
|     public function update(BudgetFormUpdateRequest $request, Budget $budget): RedirectResponse | ||||
|     { | ||||
| @@ -139,7 +128,7 @@ class EditController extends Controller | ||||
|         $redirect = redirect($this->getPreviousUrl('budgets.edit.url')); | ||||
| 
 | ||||
|         // store new attachment(s):
 | ||||
|         /** @var array|null $files */ | ||||
|         /** @var null|array $files */ | ||||
|         $files = $request->hasFile('attachments') ? $request->file('attachments') : null; | ||||
|         if (null !== $files && !auth()->user()->hasRole('demo')) { | ||||
|             $this->attachments->saveAttachmentsForModel($budget, $files); | ||||
|   | ||||
| @@ -41,12 +41,10 @@ use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Support\Collection; | ||||
| use Illuminate\View\View; | ||||
| use JsonException; | ||||
| use Psr\Container\ContainerExceptionInterface; | ||||
| use Psr\Container\NotFoundExceptionInterface; | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * Class IndexController | ||||
|  */ | ||||
| class IndexController extends Controller | ||||
| @@ -61,8 +59,6 @@ class IndexController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * IndexController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -87,12 +83,10 @@ class IndexController extends Controller | ||||
|     /** | ||||
|      * Show all budgets. | ||||
|      * | ||||
|      * @param Carbon|null $start | ||||
|      * @param Carbon|null $end | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * @throws JsonException | ||||
|      * @throws \JsonException | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
|      */ | ||||
| @@ -115,7 +109,6 @@ class IndexController extends Controller | ||||
|             $end   ??= session('end', today(config('app.timezone'))->endOfMonth()); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         $defaultCurrency = app('amount')->getDefaultCurrency(); | ||||
|         $currencies      = $this->currencyRepository->get(); | ||||
|         $budgeted        = '0'; | ||||
| @@ -135,7 +128,7 @@ class IndexController extends Controller | ||||
| 
 | ||||
|         // get budgeted for default currency:
 | ||||
|         if (0 === count($availableBudgets)) { | ||||
|             $budgeted = $this->blRepository->budgeted($start, $end, $defaultCurrency, ); | ||||
|             $budgeted = $this->blRepository->budgeted($start, $end, $defaultCurrency); | ||||
|             $spentArr = $this->opsRepository->sumExpenses($start, $end, null, null, $defaultCurrency); | ||||
|             $spent    = $spentArr[$defaultCurrency->id]['sum'] ?? '0'; | ||||
|             unset($spentArr); | ||||
| @@ -171,17 +164,30 @@ class IndexController extends Controller | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function reorder(Request $request, BudgetRepositoryInterface $repository): JsonResponse | ||||
|     { | ||||
|         $this->abRepository->cleanup(); | ||||
|         $budgetIds = $request->get('budgetIds'); | ||||
| 
 | ||||
|         foreach ($budgetIds as $index => $budgetId) { | ||||
|             $budgetId = (int)$budgetId; | ||||
|             $budget   = $repository->find($budgetId); | ||||
|             if (null !== $budget) { | ||||
|                 app('log')->debug(sprintf('Set budget #%d ("%s") to position %d', $budget->id, $budget->name, $index + 1)); | ||||
|                 $repository->setBudgetOrder($budget, $index + 1); | ||||
|             } | ||||
|         } | ||||
|         app('preferences')->mark(); | ||||
| 
 | ||||
|         return response()->json(['OK']); | ||||
|     } | ||||
| 
 | ||||
|     private function getAllAvailableBudgets(Carbon $start, Carbon $end): array | ||||
|     { | ||||
|         // get all available budgets.
 | ||||
|         $ab               = $this->abRepository->get($start, $end); | ||||
|         $availableBudgets = []; | ||||
| 
 | ||||
|         // for each, complement with spent amount:
 | ||||
|         /** @var AvailableBudget $entry */ | ||||
|         foreach ($ab as $entry) { | ||||
| @@ -194,7 +200,7 @@ class IndexController extends Controller | ||||
|             $array['spent'] = $spentArr[$entry->transaction_currency_id]['sum'] ?? '0'; | ||||
| 
 | ||||
|             // budgeted in period:
 | ||||
|             $budgeted           = $this->blRepository->budgeted($entry->start_date, $entry->end_date, $entry->transactionCurrency, ); | ||||
|             $budgeted           = $this->blRepository->budgeted($entry->start_date, $entry->end_date, $entry->transactionCurrency); | ||||
|             $array['budgeted']  = $budgeted; | ||||
|             $availableBudgets[] = $array; | ||||
|             unset($spentArr); | ||||
| @@ -203,14 +209,6 @@ class IndexController extends Controller | ||||
|         return $availableBudgets; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Carbon              $start | ||||
|      * @param Carbon              $end | ||||
|      * @param Collection          $currencies | ||||
|      * @param TransactionCurrency $defaultCurrency | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     private function getAllBudgets(Carbon $start, Carbon $end, Collection $currencies, TransactionCurrency $defaultCurrency): array | ||||
|     { | ||||
|         // get all budgets, and paginate them into $budgets.
 | ||||
| @@ -229,6 +227,7 @@ class IndexController extends Controller | ||||
|             $array['attachments'] = $this->repository->getAttachments($current); | ||||
|             $array['auto_budget'] = $this->repository->getAutoBudget($current); | ||||
|             $budgetLimits         = $this->blRepository->getBudgetLimits($current, $start, $end); | ||||
| 
 | ||||
|             /** @var BudgetLimit $limit */ | ||||
|             foreach ($budgetLimits as $limit) { | ||||
|                 app('log')->debug(sprintf('Working on budget limit #%d', $limit->id)); | ||||
| @@ -264,11 +263,6 @@ class IndexController extends Controller | ||||
|         return $budgets; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param array $budgets | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     private function getSums(array $budgets): array | ||||
|     { | ||||
|         $sums = [ | ||||
| @@ -284,11 +278,11 @@ class IndexController extends Controller | ||||
|                 $currencyId                           = $spent['currency_id']; | ||||
|                 $sums['spent'][$currencyId] | ||||
|                                                       ??= [ | ||||
|                     'amount'                  => '0', | ||||
|                     'currency_id'             => $spent['currency_id'], | ||||
|                     'currency_symbol'         => $spent['currency_symbol'], | ||||
|                     'currency_decimal_places' => $spent['currency_decimal_places'], | ||||
|                 ]; | ||||
|                                                           'amount'                  => '0', | ||||
|                                                           'currency_id'             => $spent['currency_id'], | ||||
|                                                           'currency_symbol'         => $spent['currency_symbol'], | ||||
|                                                           'currency_decimal_places' => $spent['currency_decimal_places'], | ||||
|                                                       ]; | ||||
|                 $sums['spent'][$currencyId]['amount'] = bcadd($sums['spent'][$currencyId]['amount'], $spent['spent']); | ||||
|             } | ||||
| 
 | ||||
| @@ -297,23 +291,24 @@ class IndexController extends Controller | ||||
|                 $currencyId                              = $budgeted['currency_id']; | ||||
|                 $sums['budgeted'][$currencyId] | ||||
|                                                          ??= [ | ||||
|                     'amount'                  => '0', | ||||
|                     'currency_id'             => $budgeted['currency_id'], | ||||
|                     'currency_symbol'         => $budgeted['currency_symbol'], | ||||
|                     'currency_decimal_places' => $budgeted['currency_decimal_places'], | ||||
|                 ]; | ||||
|                                                              'amount'                  => '0', | ||||
|                                                              'currency_id'             => $budgeted['currency_id'], | ||||
|                                                              'currency_symbol'         => $budgeted['currency_symbol'], | ||||
|                                                              'currency_decimal_places' => $budgeted['currency_decimal_places'], | ||||
|                                                          ]; | ||||
|                 $sums['budgeted'][$currencyId]['amount'] = bcadd($sums['budgeted'][$currencyId]['amount'], $budgeted['amount']); | ||||
| 
 | ||||
|                 // also calculate how much left from budgeted:
 | ||||
|                 $sums['left'][$currencyId] | ||||
|                     ??= [ | ||||
|                     'amount'                  => '0', | ||||
|                     'currency_id'             => $budgeted['currency_id'], | ||||
|                     'currency_symbol'         => $budgeted['currency_symbol'], | ||||
|                     'currency_decimal_places' => $budgeted['currency_decimal_places'], | ||||
|                 ]; | ||||
|                         'amount'                  => '0', | ||||
|                         'currency_id'             => $budgeted['currency_id'], | ||||
|                         'currency_symbol'         => $budgeted['currency_symbol'], | ||||
|                         'currency_decimal_places' => $budgeted['currency_decimal_places'], | ||||
|                     ]; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // final calculation for 'left':
 | ||||
|         /** | ||||
|          * @var int $currencyId | ||||
| @@ -326,28 +321,4 @@ class IndexController extends Controller | ||||
| 
 | ||||
|         return $sums; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Request                   $request | ||||
|      * @param BudgetRepositoryInterface $repository | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function reorder(Request $request, BudgetRepositoryInterface $repository): JsonResponse | ||||
|     { | ||||
|         $this->abRepository->cleanup(); | ||||
|         $budgetIds = $request->get('budgetIds'); | ||||
| 
 | ||||
|         foreach ($budgetIds as $index => $budgetId) { | ||||
|             $budgetId = (int)$budgetId; | ||||
|             $budget   = $repository->find($budgetId); | ||||
|             if (null !== $budget) { | ||||
|                 app('log')->debug(sprintf('Set budget #%d ("%s") to position %d', $budget->id, $budget->name, $index + 1)); | ||||
|                 $repository->setBudgetOrder($budget, $index + 1); | ||||
|             } | ||||
|         } | ||||
|         app('preferences')->mark(); | ||||
| 
 | ||||
|         return response()->json(['OK']); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -41,7 +41,6 @@ use Psr\Container\ContainerExceptionInterface; | ||||
| use Psr\Container\NotFoundExceptionInterface; | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * Class ShowController | ||||
|  */ | ||||
| class ShowController extends Controller | ||||
| @@ -54,8 +53,6 @@ class ShowController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * ShowController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -76,20 +73,17 @@ class ShowController extends Controller | ||||
|     /** | ||||
|      * Show transactions without a budget. | ||||
|      * | ||||
|      * @param Request     $request | ||||
|      * @param Carbon|null $start | ||||
|      * @param Carbon|null $end | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
|      */ | ||||
|     public function noBudget(Request $request, Carbon $start = null, Carbon $end = null) | ||||
|     { | ||||
|         /** @var Carbon $start */ | ||||
|         // @var Carbon $start
 | ||||
|         $start ??= session('start'); | ||||
|         /** @var Carbon $end */ | ||||
|         // @var Carbon $end
 | ||||
|         $end      ??= session('end'); | ||||
|         $subTitle = trans( | ||||
|             'firefly.without_budget_between', | ||||
| @@ -106,7 +100,8 @@ class ShowController extends Controller | ||||
|         /** @var GroupCollectorInterface $collector */ | ||||
|         $collector = app(GroupCollectorInterface::class); | ||||
|         $collector->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])->setLimit($pageSize)->setPage($page) | ||||
|                   ->withoutBudget()->withAccountInformation()->withCategoryInformation(); | ||||
|             ->withoutBudget()->withAccountInformation()->withCategoryInformation() | ||||
|         ; | ||||
|         $groups = $collector->getPaginatedGroups(); | ||||
|         $groups->setPath(route('budgets.no-budget')); | ||||
| 
 | ||||
| @@ -116,9 +111,8 @@ class ShowController extends Controller | ||||
|     /** | ||||
|      * Shows ALL transactions without a budget. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
|      */ | ||||
| @@ -134,7 +128,8 @@ class ShowController extends Controller | ||||
|         /** @var GroupCollectorInterface $collector */ | ||||
|         $collector = app(GroupCollectorInterface::class); | ||||
|         $collector->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])->setLimit($pageSize)->setPage($page) | ||||
|                   ->withoutBudget()->withAccountInformation()->withCategoryInformation(); | ||||
|             ->withoutBudget()->withAccountInformation()->withCategoryInformation() | ||||
|         ; | ||||
|         $groups = $collector->getPaginatedGroups(); | ||||
|         $groups->setPath(route('budgets.no-budget-all')); | ||||
| 
 | ||||
| @@ -144,10 +139,8 @@ class ShowController extends Controller | ||||
|     /** | ||||
|      * Show a single budget. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * @param Budget  $budget | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
|      */ | ||||
| @@ -166,8 +159,9 @@ class ShowController extends Controller | ||||
|         /** @var GroupCollectorInterface $collector */ | ||||
|         $collector = app(GroupCollectorInterface::class); | ||||
|         $collector->setRange($allStart, $allEnd)->setBudget($budget) | ||||
|                   ->withAccountInformation() | ||||
|                   ->setLimit($pageSize)->setPage($page)->withBudgetInformation()->withCategoryInformation(); | ||||
|             ->withAccountInformation() | ||||
|             ->setLimit($pageSize)->setPage($page)->withBudgetInformation()->withCategoryInformation() | ||||
|         ; | ||||
|         $groups = $collector->getPaginatedGroups(); | ||||
|         $groups->setPath(route('budgets.show', [$budget->id])); | ||||
| 
 | ||||
| @@ -179,11 +173,8 @@ class ShowController extends Controller | ||||
|     /** | ||||
|      * Show a single budget by a budget limit. | ||||
|      * | ||||
|      * @param Request     $request | ||||
|      * @param Budget      $budget | ||||
|      * @param BudgetLimit $budgetLimit | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
| @@ -211,9 +202,11 @@ class ShowController extends Controller | ||||
|         $collector = app(GroupCollectorInterface::class); | ||||
| 
 | ||||
|         $collector->setRange($budgetLimit->start_date, $budgetLimit->end_date)->withAccountInformation() | ||||
|                   ->setBudget($budget)->setLimit($pageSize)->setPage($page)->withBudgetInformation()->withCategoryInformation(); | ||||
|             ->setBudget($budget)->setLimit($pageSize)->setPage($page)->withBudgetInformation()->withCategoryInformation() | ||||
|         ; | ||||
|         $groups = $collector->getPaginatedGroups(); | ||||
|         $groups->setPath(route('budgets.show.limit', [$budget->id, $budgetLimit->id])); | ||||
| 
 | ||||
|         /** @var Carbon $start */ | ||||
|         $start       = session('first', today(config('app.timezone'))->startOfYear()); | ||||
|         $end         = today(config('app.timezone')); | ||||
|   | ||||
| @@ -44,8 +44,6 @@ class CreateController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * CategoryController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -66,8 +64,6 @@ class CreateController extends Controller | ||||
|     /** | ||||
|      * Create category. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function create(Request $request) | ||||
| @@ -84,9 +80,8 @@ class CreateController extends Controller | ||||
|     /** | ||||
|      * Store new category. | ||||
|      * | ||||
|      * @param CategoryFormRequest $request | ||||
|      * @return $this|Redirector|RedirectResponse | ||||
|      * | ||||
|      * @return $this|RedirectResponse|Redirector | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function store(CategoryFormRequest $request) | ||||
| @@ -98,7 +93,7 @@ class CreateController extends Controller | ||||
|         app('preferences')->mark(); | ||||
| 
 | ||||
|         // store attachment(s):
 | ||||
|         /** @var array|null $files */ | ||||
|         /** @var null|array $files */ | ||||
|         $files = $request->hasFile('attachments') ? $request->file('attachments') : null; | ||||
|         if (null !== $files && !auth()->user()->hasRole('demo')) { | ||||
|             $this->attachments->saveAttachmentsForModel($category, $files); | ||||
|   | ||||
| @@ -42,8 +42,6 @@ class DeleteController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * CategoryController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -63,8 +61,6 @@ class DeleteController extends Controller | ||||
|     /** | ||||
|      * Delete a category. | ||||
|      * | ||||
|      * @param Category $category | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function delete(Category $category) | ||||
| @@ -80,10 +76,7 @@ class DeleteController extends Controller | ||||
|     /** | ||||
|      * Destroy a category. | ||||
|      * | ||||
|      * @param Request  $request | ||||
|      * @param Category $category | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * @return Redirector|RedirectResponse | ||||
|      */ | ||||
|     public function destroy(Request $request, Category $category) | ||||
|     { | ||||
|   | ||||
| @@ -44,8 +44,6 @@ class EditController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * CategoryController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -66,9 +64,6 @@ class EditController extends Controller | ||||
|     /** | ||||
|      * Edit a category. | ||||
|      * | ||||
|      * @param Request  $request | ||||
|      * @param Category $category | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function edit(Request $request, Category $category) | ||||
| @@ -91,10 +86,7 @@ class EditController extends Controller | ||||
|     /** | ||||
|      * Update category. | ||||
|      * | ||||
|      * @param CategoryFormRequest $request | ||||
|      * @param Category            $category | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * @return Redirector|RedirectResponse | ||||
|      */ | ||||
|     public function update(CategoryFormRequest $request, Category $category) | ||||
|     { | ||||
| @@ -105,7 +97,7 @@ class EditController extends Controller | ||||
|         app('preferences')->mark(); | ||||
| 
 | ||||
|         // store new attachment(s):
 | ||||
|         /** @var array|null $files */ | ||||
|         /** @var null|array $files */ | ||||
|         $files = $request->hasFile('attachments') ? $request->file('attachments') : null; | ||||
|         if (null !== $files && !auth()->user()->hasRole('demo')) { | ||||
|             $this->attachments->saveAttachmentsForModel($category, $files); | ||||
|   | ||||
| @@ -44,8 +44,6 @@ class IndexController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * CategoryController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -65,9 +63,8 @@ class IndexController extends Controller | ||||
|     /** | ||||
|      * Show all categories. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
|      */ | ||||
|   | ||||
| @@ -38,7 +38,6 @@ use Psr\Container\ContainerExceptionInterface; | ||||
| use Psr\Container\NotFoundExceptionInterface; | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * Class NoCategoryController | ||||
|  */ | ||||
| class NoCategoryController extends Controller | ||||
| @@ -49,8 +48,6 @@ class NoCategoryController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * CategoryController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -71,11 +68,8 @@ class NoCategoryController extends Controller | ||||
|     /** | ||||
|      * Show transactions without a category. | ||||
|      * | ||||
|      * @param Request     $request | ||||
|      * @param Carbon|null $start | ||||
|      * @param Carbon|null $end | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
| @@ -83,9 +77,9 @@ class NoCategoryController extends Controller | ||||
|     public function show(Request $request, Carbon $start = null, Carbon $end = null) | ||||
|     { | ||||
|         app('log')->debug('Start of noCategory()'); | ||||
|         /** @var Carbon $start */ | ||||
|         // @var Carbon $start
 | ||||
|         $start ??= session('start'); | ||||
|         /** @var Carbon $end */ | ||||
|         // @var Carbon $end
 | ||||
|         $end      ??= session('end'); | ||||
|         $page     = (int)$request->get('page'); | ||||
|         $pageSize = (int)app('preferences')->get('listPageSize', 50)->data; | ||||
| @@ -101,9 +95,10 @@ class NoCategoryController extends Controller | ||||
|         /** @var GroupCollectorInterface $collector */ | ||||
|         $collector = app(GroupCollectorInterface::class); | ||||
|         $collector->setRange($start, $end) | ||||
|                   ->setLimit($pageSize)->setPage($page)->withoutCategory() | ||||
|                   ->withAccountInformation()->withBudgetInformation() | ||||
|                   ->setTypes([TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER]); | ||||
|             ->setLimit($pageSize)->setPage($page)->withoutCategory() | ||||
|             ->withAccountInformation()->withBudgetInformation() | ||||
|             ->setTypes([TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER]) | ||||
|         ; | ||||
|         $groups = $collector->getPaginatedGroups(); | ||||
|         $groups->setPath(route('categories.no-category', [$start->format('Y-m-d'), $end->format('Y-m-d')])); | ||||
| 
 | ||||
| @@ -113,9 +108,8 @@ class NoCategoryController extends Controller | ||||
|     /** | ||||
|      * Show all transactions without a category. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
|      */ | ||||
| @@ -138,8 +132,9 @@ class NoCategoryController extends Controller | ||||
|         /** @var GroupCollectorInterface $collector */ | ||||
|         $collector = app(GroupCollectorInterface::class); | ||||
|         $collector->setRange($start, $end)->setLimit($pageSize)->setPage($page)->withoutCategory() | ||||
|                   ->withAccountInformation()->withBudgetInformation() | ||||
|                   ->setTypes([TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER]); | ||||
|             ->withAccountInformation()->withBudgetInformation() | ||||
|             ->setTypes([TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER]) | ||||
|         ; | ||||
|         $groups = $collector->getPaginatedGroups(); | ||||
|         $groups->setPath(route('categories.no-category.all')); | ||||
| 
 | ||||
|   | ||||
| @@ -38,9 +38,7 @@ use Psr\Container\ContainerExceptionInterface; | ||||
| use Psr\Container\NotFoundExceptionInterface; | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * Class ShowController | ||||
|  * | ||||
|  */ | ||||
| class ShowController extends Controller | ||||
| { | ||||
| @@ -51,8 +49,6 @@ class ShowController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * CategoryController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -73,21 +69,17 @@ class ShowController extends Controller | ||||
|     /** | ||||
|      * Show a single category. | ||||
|      * | ||||
|      * @param Request     $request | ||||
|      * @param Category    $category | ||||
|      * @param Carbon|null $start | ||||
|      * @param Carbon|null $end | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
|      */ | ||||
|     public function show(Request $request, Category $category, Carbon $start = null, Carbon $end = null) | ||||
|     { | ||||
|         /** @var Carbon $start */ | ||||
|         // @var Carbon $start
 | ||||
|         $start ??= session('start', today(config('app.timezone'))->startOfMonth()); | ||||
|         /** @var Carbon $end */ | ||||
|         // @var Carbon $end
 | ||||
|         $end          ??= session('end', today(config('app.timezone'))->endOfMonth()); | ||||
|         $subTitleIcon = 'fa-bookmark'; | ||||
|         $page         = (int)$request->get('page'); | ||||
| @@ -108,8 +100,9 @@ class ShowController extends Controller | ||||
|         /** @var GroupCollectorInterface $collector */ | ||||
|         $collector = app(GroupCollectorInterface::class); | ||||
|         $collector->setRange($start, $end)->setLimit($pageSize)->setPage($page) | ||||
|                   ->withAccountInformation() | ||||
|                   ->setCategory($category)->withBudgetInformation()->withCategoryInformation(); | ||||
|             ->withAccountInformation() | ||||
|             ->setCategory($category)->withBudgetInformation()->withCategoryInformation() | ||||
|         ; | ||||
| 
 | ||||
|         $groups = $collector->getPaginatedGroups(); | ||||
|         $groups->setPath($path); | ||||
| @@ -120,10 +113,8 @@ class ShowController extends Controller | ||||
|     /** | ||||
|      * Show all transactions within a category. | ||||
|      * | ||||
|      * @param Request  $request | ||||
|      * @param Category $category | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
|      */ | ||||
| @@ -139,6 +130,7 @@ class ShowController extends Controller | ||||
| 
 | ||||
|         $subTitle = (string)trans('firefly.all_journals_for_category', ['name' => $category->name]); | ||||
|         $first    = $this->repository->firstUseDate($category); | ||||
| 
 | ||||
|         /** @var Carbon $start */ | ||||
|         $start       = $first ?? today(config('app.timezone')); | ||||
|         $end         = today(config('app.timezone')); | ||||
| @@ -148,8 +140,9 @@ class ShowController extends Controller | ||||
|         /** @var GroupCollectorInterface $collector */ | ||||
|         $collector = app(GroupCollectorInterface::class); | ||||
|         $collector->setRange($start, $end)->setLimit($pageSize)->setPage($page) | ||||
|                   ->withAccountInformation() | ||||
|                   ->setCategory($category)->withBudgetInformation()->withCategoryInformation(); | ||||
|             ->withAccountInformation() | ||||
|             ->setCategory($category)->withBudgetInformation()->withCategoryInformation() | ||||
|         ; | ||||
| 
 | ||||
|         $groups = $collector->getPaginatedGroups(); | ||||
|         $groups->setPath($path); | ||||
|   | ||||
| @@ -40,13 +40,11 @@ use FireflyIII\Support\Http\Controllers\ChartGeneration; | ||||
| use FireflyIII\Support\Http\Controllers\DateCalculation; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Support\Collection; | ||||
| use JsonException; | ||||
| use Psr\Container\ContainerExceptionInterface; | ||||
| use Psr\Container\NotFoundExceptionInterface; | ||||
| 
 | ||||
| /** | ||||
|  * Class AccountController. | ||||
|  * | ||||
|  */ | ||||
| class AccountController extends Controller | ||||
| { | ||||
| @@ -60,8 +58,6 @@ class AccountController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * AccountController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -83,13 +79,13 @@ class AccountController extends Controller | ||||
|      * | ||||
|      * This chart is (multi) currency aware. | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws JsonException | ||||
|      * @throws \JsonException | ||||
|      */ | ||||
|     public function expenseAccounts(): JsonResponse | ||||
|     { | ||||
|         /** @var Carbon $start */ | ||||
|         $start = clone session('start', today(config('app.timezone'))->startOfMonth()); | ||||
| 
 | ||||
|         /** @var Carbon $end */ | ||||
|         $end   = clone session('end', today(config('app.timezone'))->endOfMonth()); | ||||
|         $cache = new CacheProperties(); | ||||
| @@ -150,12 +146,12 @@ class AccountController extends Controller | ||||
|         foreach ($currencies as $currencyId => $currency) { | ||||
|             $dataSet | ||||
|                                     = [ | ||||
|                 'label'           => (string)trans('firefly.spent'), | ||||
|                 'type'            => 'bar', | ||||
|                 'currency_symbol' => $currency->symbol, | ||||
|                 'currency_code'   => $currency->code, | ||||
|                 'entries'         => $this->expandNames($tempData), | ||||
|             ]; | ||||
|                                         'label'           => (string)trans('firefly.spent'), | ||||
|                                         'type'            => 'bar', | ||||
|                                         'currency_symbol' => $currency->symbol, | ||||
|                                         'currency_code'   => $currency->code, | ||||
|                                         'entries'         => $this->expandNames($tempData), | ||||
|                                     ]; | ||||
|             $chartData[$currencyId] = $dataSet; | ||||
|         } | ||||
| 
 | ||||
| @@ -174,11 +170,6 @@ class AccountController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Expenses per budget for all time, as shown on account overview. | ||||
|      * | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * @param Account                    $account | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function expenseBudgetAll(AccountRepositoryInterface $repository, Account $account): JsonResponse | ||||
|     { | ||||
| @@ -190,12 +181,6 @@ class AccountController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Expenses per budget, as shown on account overview. | ||||
|      * | ||||
|      * @param Account $account | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function expenseBudget(Account $account, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
| @@ -207,6 +192,7 @@ class AccountController extends Controller | ||||
|         if ($cache->has()) { | ||||
|             return response()->json($cache->get()); | ||||
|         } | ||||
| 
 | ||||
|         /** @var GroupCollectorInterface $collector */ | ||||
|         $collector = app(GroupCollectorInterface::class); | ||||
|         $collector->setAccounts(new Collection([$account]))->setRange($start, $end)->withBudgetInformation()->setTypes([TransactionType::WITHDRAWAL]); | ||||
| @@ -214,6 +200,7 @@ class AccountController extends Controller | ||||
|         $chartData = []; | ||||
|         $result    = []; | ||||
|         $budgetIds = []; | ||||
| 
 | ||||
|         /** @var array $journal */ | ||||
|         foreach ($journals as $journal) { | ||||
|             $budgetId    = (int)$journal['budget_id']; | ||||
| @@ -248,11 +235,6 @@ class AccountController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Expenses grouped by category for account. | ||||
|      * | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * @param Account                    $account | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function expenseCategoryAll(AccountRepositoryInterface $repository, Account $account): JsonResponse | ||||
|     { | ||||
| @@ -264,12 +246,6 @@ class AccountController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Expenses per category for one single account. | ||||
|      * | ||||
|      * @param Account $account | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function expenseCategory(Account $account, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
| @@ -321,11 +297,8 @@ class AccountController extends Controller | ||||
|     /** | ||||
|      * Shows the balances for all the user's frontpage accounts. | ||||
|      * | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      * @throws JsonException | ||||
|      * @throws \JsonException | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
|      */ | ||||
| @@ -349,11 +322,6 @@ class AccountController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Shows the income grouped by category for an account, in all time. | ||||
|      * | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * @param Account                    $account | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function incomeCategoryAll(AccountRepositoryInterface $repository, Account $account): JsonResponse | ||||
|     { | ||||
| @@ -365,12 +333,6 @@ class AccountController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Shows all income per account for each category. | ||||
|      * | ||||
|      * @param Account $account | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function incomeCategory(Account $account, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
| @@ -391,6 +353,7 @@ class AccountController extends Controller | ||||
|         $journals  = $collector->getExtractedJournals(); | ||||
|         $result    = []; | ||||
|         $chartData = []; | ||||
| 
 | ||||
|         /** @var array $journal */ | ||||
|         foreach ($journals as $journal) { | ||||
|             $key = sprintf('%d-%d', $journal['category_id'], $journal['currency_id']); | ||||
| @@ -422,14 +385,8 @@ class AccountController extends Controller | ||||
|     /** | ||||
|      * Shows overview of account during a single period. | ||||
|      * | ||||
|      * @param Account $account | ||||
|      * @param Carbon  $start | ||||
|      * | ||||
|      * @param Carbon  $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      * @throws JsonException | ||||
|      * @throws \JsonException | ||||
|      */ | ||||
|     public function period(Account $account, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
| @@ -460,78 +417,13 @@ class AccountController extends Controller | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Carbon              $start | ||||
|      * @param Carbon              $end | ||||
|      * @param Account             $account | ||||
|      * @param TransactionCurrency $currency | ||||
|      * | ||||
|      * @return array | ||||
|      * @throws FireflyException | ||||
|      * @throws JsonException | ||||
|      */ | ||||
|     private function periodByCurrency(Carbon $start, Carbon $end, Account $account, TransactionCurrency $currency): array | ||||
|     { | ||||
|         app('log')->debug(sprintf('Now in periodByCurrency("%s", "%s", %s, "%s")', $start->format('Y-m-d'), $end->format('Y-m-d'), $account->id, $currency->code)); | ||||
|         $locale  = app('steam')->getLocale(); | ||||
|         $step    = $this->calculateStep($start, $end); | ||||
|         $result  = [ | ||||
|             'label'           => sprintf('%s (%s)', $account->name, $currency->symbol), | ||||
|             'currency_symbol' => $currency->symbol, | ||||
|             'currency_code'   => $currency->code, | ||||
|         ]; | ||||
|         $entries = []; | ||||
|         $current = clone $start; | ||||
|         app('log')->debug(sprintf('Step is %s', $step)); | ||||
| 
 | ||||
|         // fix for issue https://github.com/firefly-iii/firefly-iii/issues/8041
 | ||||
|         // have to make sure this chart is always based on the balance at the END of the period.
 | ||||
|         // This period depends on the size of the chart
 | ||||
|         $current = app('navigation')->endOfX($current, $step, null); | ||||
|         app('log')->debug(sprintf('$current date is %s', $current->format('Y-m-d'))); | ||||
|         if ('1D' === $step) { | ||||
|             // per day the entire period, balance for every day.
 | ||||
|             $format   = (string)trans('config.month_and_day_js', [], $locale); | ||||
|             $range    = app('steam')->balanceInRange($account, $start, $end, $currency); | ||||
|             $previous = array_values($range)[0]; | ||||
|             while ($end >= $current) { | ||||
|                 $theDate         = $current->format('Y-m-d'); | ||||
|                 $balance         = $range[$theDate] ?? $previous; | ||||
|                 $label           = $current->isoFormat($format); | ||||
|                 $entries[$label] = (float)$balance; | ||||
|                 $previous        = $balance; | ||||
|                 $current->addDay(); | ||||
|             } | ||||
|         } | ||||
|         if ('1W' === $step || '1M' === $step || '1Y' === $step) { | ||||
|             while ($end >= $current) { | ||||
|                 app('log')->debug(sprintf('Current is: %s', $current->format('Y-m-d'))); | ||||
|                 $balance         = (float)app('steam')->balance($account, $current, $currency); | ||||
|                 $label           = app('navigation')->periodShow($current, $step); | ||||
|                 $entries[$label] = $balance; | ||||
|                 $current         = app('navigation')->addPeriod($current, $step, 0); | ||||
|                 // here too, to fix #8041, the data is corrected to the end of the period.
 | ||||
|                 $current = app('navigation')->endOfX($current, $step, null); | ||||
|             } | ||||
|         } | ||||
|         $result['entries'] = $entries; | ||||
| 
 | ||||
|         return $result; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Shows the balances for a given set of dates and accounts. | ||||
|      * | ||||
|      * TODO this chart is not multi currency aware. | ||||
|      * | ||||
|      * @param Collection $accounts | ||||
|      * | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      * @throws JsonException | ||||
|      * @throws \JsonException | ||||
|      */ | ||||
|     public function report(Collection $accounts, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
| @@ -543,13 +435,13 @@ class AccountController extends Controller | ||||
|      * | ||||
|      * This chart is multi-currency aware. | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws JsonException | ||||
|      * @throws \JsonException | ||||
|      */ | ||||
|     public function revenueAccounts(): JsonResponse | ||||
|     { | ||||
|         /** @var Carbon $start */ | ||||
|         $start = clone session('start', today(config('app.timezone'))->startOfMonth()); | ||||
| 
 | ||||
|         /** @var Carbon $end */ | ||||
|         $end   = clone session('end', today(config('app.timezone'))->endOfMonth()); | ||||
|         $cache = new CacheProperties(); | ||||
| @@ -610,12 +502,12 @@ class AccountController extends Controller | ||||
|         foreach ($currencies as $currencyId => $currency) { | ||||
|             $dataSet | ||||
|                                     = [ | ||||
|                 'label'           => (string)trans('firefly.earned'), | ||||
|                 'type'            => 'bar', | ||||
|                 'currency_symbol' => $currency->symbol, | ||||
|                 'currency_code'   => $currency->code, | ||||
|                 'entries'         => $this->expandNames($tempData), | ||||
|             ]; | ||||
|                                         'label'           => (string)trans('firefly.earned'), | ||||
|                                         'type'            => 'bar', | ||||
|                                         'currency_symbol' => $currency->symbol, | ||||
|                                         'currency_code'   => $currency->code, | ||||
|                                         'entries'         => $this->expandNames($tempData), | ||||
|                                     ]; | ||||
|             $chartData[$currencyId] = $dataSet; | ||||
|         } | ||||
| 
 | ||||
| @@ -631,4 +523,57 @@ class AccountController extends Controller | ||||
| 
 | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @throws FireflyException | ||||
|      * @throws \JsonException | ||||
|      */ | ||||
|     private function periodByCurrency(Carbon $start, Carbon $end, Account $account, TransactionCurrency $currency): array | ||||
|     { | ||||
|         app('log')->debug(sprintf('Now in periodByCurrency("%s", "%s", %s, "%s")', $start->format('Y-m-d'), $end->format('Y-m-d'), $account->id, $currency->code)); | ||||
|         $locale  = app('steam')->getLocale(); | ||||
|         $step    = $this->calculateStep($start, $end); | ||||
|         $result  = [ | ||||
|             'label'           => sprintf('%s (%s)', $account->name, $currency->symbol), | ||||
|             'currency_symbol' => $currency->symbol, | ||||
|             'currency_code'   => $currency->code, | ||||
|         ]; | ||||
|         $entries = []; | ||||
|         $current = clone $start; | ||||
|         app('log')->debug(sprintf('Step is %s', $step)); | ||||
| 
 | ||||
|         // fix for issue https://github.com/firefly-iii/firefly-iii/issues/8041
 | ||||
|         // have to make sure this chart is always based on the balance at the END of the period.
 | ||||
|         // This period depends on the size of the chart
 | ||||
|         $current = app('navigation')->endOfX($current, $step, null); | ||||
|         app('log')->debug(sprintf('$current date is %s', $current->format('Y-m-d'))); | ||||
|         if ('1D' === $step) { | ||||
|             // per day the entire period, balance for every day.
 | ||||
|             $format   = (string)trans('config.month_and_day_js', [], $locale); | ||||
|             $range    = app('steam')->balanceInRange($account, $start, $end, $currency); | ||||
|             $previous = array_values($range)[0]; | ||||
|             while ($end >= $current) { | ||||
|                 $theDate         = $current->format('Y-m-d'); | ||||
|                 $balance         = $range[$theDate] ?? $previous; | ||||
|                 $label           = $current->isoFormat($format); | ||||
|                 $entries[$label] = (float)$balance; | ||||
|                 $previous        = $balance; | ||||
|                 $current->addDay(); | ||||
|             } | ||||
|         } | ||||
|         if ('1W' === $step || '1M' === $step || '1Y' === $step) { | ||||
|             while ($end >= $current) { | ||||
|                 app('log')->debug(sprintf('Current is: %s', $current->format('Y-m-d'))); | ||||
|                 $balance         = (float)app('steam')->balance($account, $current, $currency); | ||||
|                 $label           = app('navigation')->periodShow($current, $step); | ||||
|                 $entries[$label] = $balance; | ||||
|                 $current         = app('navigation')->addPeriod($current, $step, 0); | ||||
|                 // here too, to fix #8041, the data is corrected to the end of the period.
 | ||||
|                 $current = app('navigation')->endOfX($current, $step, null); | ||||
|             } | ||||
|         } | ||||
|         $result['entries'] = $entries; | ||||
| 
 | ||||
|         return $result; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -41,8 +41,6 @@ class BillController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * BillController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -52,10 +50,6 @@ class BillController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Shows all bills and whether or not they've been paid this month (pie chart). | ||||
|      * | ||||
|      * @param BillRepositoryInterface $repository | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function frontpage(BillRepositoryInterface $repository): JsonResponse | ||||
|     { | ||||
| @@ -85,6 +79,7 @@ class BillController extends Controller | ||||
|                 'currency_code'   => $info['code'], | ||||
|             ]; | ||||
|         } | ||||
| 
 | ||||
|         /** | ||||
|          * @var array $info | ||||
|          */ | ||||
| @@ -107,9 +102,6 @@ class BillController extends Controller | ||||
|     /** | ||||
|      * Shows overview for a single bill. | ||||
|      * | ||||
|      * @param Bill $bill | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function single(Bill $bill): JsonResponse | ||||
| @@ -179,7 +171,6 @@ class BillController extends Controller | ||||
|                 $amount = bcmul($journal['foreign_amount'], '-1'); | ||||
|             } | ||||
| 
 | ||||
| 
 | ||||
|             $chartData[2]['entries'][$date] = bcadd($chartData[2]['entries'][$date], $amount);  // amount of journal
 | ||||
|         } | ||||
| 
 | ||||
|   | ||||
| @@ -45,7 +45,6 @@ use Illuminate\Support\Collection; | ||||
| 
 | ||||
| /** | ||||
|  * Class BudgetController. | ||||
|  * | ||||
|  */ | ||||
| class BudgetController extends Controller | ||||
| { | ||||
| @@ -60,8 +59,6 @@ class BudgetController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * BudgetController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -82,15 +79,12 @@ class BudgetController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Shows overview of a single budget. | ||||
|      * | ||||
|      * @param Budget $budget | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function budget(Budget $budget): JsonResponse | ||||
|     { | ||||
|         /** @var Carbon $start */ | ||||
|         $start = $this->repository->firstUseDate($budget) ?? session('start', today(config('app.timezone'))); | ||||
| 
 | ||||
|         /** @var Carbon $end */ | ||||
|         $end   = session('end', today(config('app.timezone'))); | ||||
|         $cache = new CacheProperties(); | ||||
| @@ -148,11 +142,6 @@ class BudgetController extends Controller | ||||
|     /** | ||||
|      * Shows the amount left in a specific budget limit. | ||||
|      * | ||||
|      * @param Budget      $budget | ||||
|      * @param BudgetLimit $budgetLimit | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function budgetLimit(Budget $budget, BudgetLimit $budgetLimit): JsonResponse | ||||
| @@ -199,11 +188,6 @@ class BudgetController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Shows how much is spent per asset account. | ||||
|      * | ||||
|      * @param Budget           $budget | ||||
|      * @param BudgetLimit|null $budgetLimit | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function expenseAsset(Budget $budget, ?BudgetLimit $budgetLimit = null): JsonResponse | ||||
|     { | ||||
| @@ -253,10 +237,10 @@ class BudgetController extends Controller | ||||
|             $title   = sprintf('%s (%s)', $names[$assetId] ?? '(empty)', $info['currency_name']); | ||||
|             $chartData[$title] | ||||
|                      = [ | ||||
|                 'amount'          => $info['amount'], | ||||
|                 'currency_symbol' => $info['currency_symbol'], | ||||
|                 'currency_code'   => $info['currency_code'], | ||||
|             ]; | ||||
|                          'amount'          => $info['amount'], | ||||
|                          'currency_symbol' => $info['currency_symbol'], | ||||
|                          'currency_code'   => $info['currency_code'], | ||||
|                      ]; | ||||
|         } | ||||
| 
 | ||||
|         $data = $this->generator->multiCurrencyPieChart($chartData); | ||||
| @@ -267,11 +251,6 @@ class BudgetController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Shows how much is spent per category. | ||||
|      * | ||||
|      * @param Budget           $budget | ||||
|      * @param BudgetLimit|null $budgetLimit | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function expenseCategory(Budget $budget, ?BudgetLimit $budgetLimit = null): JsonResponse | ||||
|     { | ||||
| @@ -330,12 +309,6 @@ class BudgetController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Shows how much is spent per expense account. | ||||
|      * | ||||
|      * | ||||
|      * @param Budget           $budget | ||||
|      * @param BudgetLimit|null $budgetLimit | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function expenseExpense(Budget $budget, ?BudgetLimit $budgetLimit = null): JsonResponse | ||||
|     { | ||||
| @@ -364,6 +337,7 @@ class BudgetController extends Controller | ||||
|         $journals  = $collector->getExtractedJournals(); | ||||
|         $result    = []; | ||||
|         $chartData = []; | ||||
| 
 | ||||
|         /** @var array $journal */ | ||||
|         foreach ($journals as $journal) { | ||||
|             $key                    = sprintf('%d-%d', $journal['destination_account_id'], $journal['currency_id']); | ||||
| @@ -397,8 +371,6 @@ class BudgetController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Shows a budget list with spent/left/overspent. | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function frontpage(): JsonResponse | ||||
|     { | ||||
| @@ -430,15 +402,8 @@ class BudgetController extends Controller | ||||
|      * Shows a budget overview chart (spent and budgeted). | ||||
|      * | ||||
|      * Suppress warning because this method will be replaced by API calls. | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.ExcessiveParameterList) | ||||
|      * | ||||
|      * @param Budget              $budget | ||||
|      * @param TransactionCurrency $currency | ||||
|      * @param Collection          $accounts | ||||
|      * @param Carbon              $start | ||||
|      * @param Carbon              $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function period(Budget $budget, TransactionCurrency $currency, Collection $accounts, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
| @@ -507,13 +472,6 @@ class BudgetController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Shows a chart for transactions without a budget. | ||||
|      * | ||||
|      * @param TransactionCurrency $currency | ||||
|      * @param Collection          $accounts | ||||
|      * @param Carbon              $start | ||||
|      * @param Carbon              $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function periodNoBudget(TransactionCurrency $currency, Collection $accounts, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -37,7 +37,6 @@ use Illuminate\Support\Collection; | ||||
|  * Separate controller because many helper functions are shared. | ||||
|  * | ||||
|  * Class BudgetReportController | ||||
|  * | ||||
|  */ | ||||
| class BudgetReportController extends Controller | ||||
| { | ||||
| @@ -52,8 +51,6 @@ class BudgetReportController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * BudgetReportController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -70,13 +67,6 @@ class BudgetReportController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Chart that groups the expenses by budget. | ||||
|      * | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $budgets | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function budgetExpense(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
| @@ -106,13 +96,6 @@ class BudgetReportController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Chart that groups the expenses by budget. | ||||
|      * | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $budgets | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function categoryExpense(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
| @@ -143,13 +126,6 @@ class BudgetReportController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Chart that groups expenses by the account. | ||||
|      * | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $budgets | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function destinationAccountExpense(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
| @@ -180,13 +156,6 @@ class BudgetReportController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Main overview of a budget in the budget report. | ||||
|      * | ||||
|      * @param Collection $accounts | ||||
|      * @param Budget     $budget | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function mainChart(Collection $accounts, Budget $budget, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
| @@ -226,38 +195,8 @@ class BudgetReportController extends Controller | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     private function makeEntries(Carbon $start, Carbon $end): array | ||||
|     { | ||||
|         $return         = []; | ||||
|         $format         = app('navigation')->preferredCarbonLocalizedFormat($start, $end); | ||||
|         $preferredRange = app('navigation')->preferredRangeFormat($start, $end); | ||||
|         $currentStart   = clone $start; | ||||
|         while ($currentStart <= $end) { | ||||
|             $currentEnd   = app('navigation')->endOfPeriod($currentStart, $preferredRange); | ||||
|             $key          = $currentStart->isoFormat($format); | ||||
|             $return[$key] = '0'; | ||||
|             $currentStart = clone $currentEnd; | ||||
|             $currentStart->addDay()->startOfDay(); | ||||
|         } | ||||
| 
 | ||||
|         return $return; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Chart that groups expenses by the account. | ||||
|      * | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $budgets | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function sourceAccountExpense(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
| @@ -285,4 +224,21 @@ class BudgetReportController extends Controller | ||||
| 
 | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     private function makeEntries(Carbon $start, Carbon $end): array | ||||
|     { | ||||
|         $return         = []; | ||||
|         $format         = app('navigation')->preferredCarbonLocalizedFormat($start, $end); | ||||
|         $preferredRange = app('navigation')->preferredRangeFormat($start, $end); | ||||
|         $currentStart   = clone $start; | ||||
|         while ($currentStart <= $end) { | ||||
|             $currentEnd   = app('navigation')->endOfPeriod($currentStart, $preferredRange); | ||||
|             $key          = $currentStart->isoFormat($format); | ||||
|             $return[$key] = '0'; | ||||
|             $currentStart = clone $currentEnd; | ||||
|             $currentStart->addDay()->startOfDay(); | ||||
|         } | ||||
| 
 | ||||
|         return $return; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -56,8 +56,6 @@ class CategoryController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * CategoryController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -70,9 +68,6 @@ class CategoryController extends Controller | ||||
|      * Show an overview for a category for all time, per month/week/year. | ||||
|      * TODO test method, for category refactor. | ||||
|      * | ||||
|      * @param Category $category | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
| @@ -86,6 +81,7 @@ class CategoryController extends Controller | ||||
|         if ($cache->has()) { | ||||
|             return response()->json($cache->get()); | ||||
|         } | ||||
| 
 | ||||
|         /** @var CategoryRepositoryInterface $repository */ | ||||
|         $repository = app(CategoryRepositoryInterface::class); | ||||
|         $start      = $repository->firstUseDate($category) ?? $this->getDate(); | ||||
| @@ -102,19 +98,9 @@ class CategoryController extends Controller | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @return Carbon | ||||
|      */ | ||||
|     private function getDate(): Carbon | ||||
|     { | ||||
|         return today(config('app.timezone')); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Shows the category chart on the front page. | ||||
|      * TODO test method for category refactor. | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function frontPage(): JsonResponse | ||||
|     { | ||||
| @@ -140,13 +126,6 @@ class CategoryController extends Controller | ||||
|     /** | ||||
|      * Chart report. | ||||
|      * TODO test method for category refactor. | ||||
|      * | ||||
|      * @param Category   $category | ||||
|      * @param Collection $accounts | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function reportPeriod(Category $category, Collection $accounts, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
| @@ -166,15 +145,70 @@ class CategoryController extends Controller | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Chart for period for transactions without a category. | ||||
|      * TODO test me. | ||||
|      */ | ||||
|     public function reportPeriodNoCategory(Collection $accounts, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
|         $cache = new CacheProperties(); | ||||
|         $cache->addProperty($start); | ||||
|         $cache->addProperty($end); | ||||
|         $cache->addProperty('chart.category.period.no-cat'); | ||||
|         $cache->addProperty($accounts->pluck('id')->toArray()); | ||||
|         if ($cache->has()) { | ||||
|             return response()->json($cache->get()); | ||||
|         } | ||||
|         $data = $this->reportPeriodChart($accounts, $start, $end, null); | ||||
| 
 | ||||
|         $cache->store($data); | ||||
| 
 | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Chart for a specific period. | ||||
|      * TODO test me, for category refactor. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
|      */ | ||||
|     public function specificPeriod(Category $category, Carbon $date): JsonResponse | ||||
|     { | ||||
|         $range = app('navigation')->getViewRange(false); | ||||
|         $start = app('navigation')->startOfPeriod($date, $range); | ||||
|         $end   = session()->get('end'); | ||||
|         if ($end < $start) { | ||||
|             [$end, $start] = [$start, $end]; | ||||
|         } | ||||
| 
 | ||||
|         $cache = new CacheProperties(); | ||||
|         $cache->addProperty($start); | ||||
|         $cache->addProperty($end); | ||||
|         $cache->addProperty($category->id); | ||||
|         $cache->addProperty('chart.category.period-chart'); | ||||
|         if ($cache->has()) { | ||||
|             return response()->json($cache->get()); | ||||
|         } | ||||
| 
 | ||||
|         /** @var WholePeriodChartGenerator $chartGenerator */ | ||||
|         $chartGenerator = app(WholePeriodChartGenerator::class); | ||||
|         $chartData      = $chartGenerator->generate($category, $start, $end); | ||||
|         $data           = $this->generator->multiSet($chartData); | ||||
| 
 | ||||
|         $cache->store($data); | ||||
| 
 | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     private function getDate(): Carbon | ||||
|     { | ||||
|         return today(config('app.timezone')); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Generate report chart for either with or without category. | ||||
|      * | ||||
|      * @param Collection    $accounts | ||||
|      * @param Carbon        $start | ||||
|      * @param Carbon        $end | ||||
|      * @param Category|null $category | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     private function reportPeriodChart(Collection $accounts, Carbon $start, Carbon $end, ?Category $category): array | ||||
|     { | ||||
| @@ -211,19 +245,19 @@ class CategoryController extends Controller | ||||
|             $inKey        = sprintf('%d-in', $currencyId); | ||||
|             $chartData[$outKey] | ||||
|                           = [ | ||||
|                 'label'           => sprintf('%s (%s)', (string)trans('firefly.spent'), $currencyInfo['currency_name']), | ||||
|                 'entries'         => [], | ||||
|                 'type'            => 'bar', | ||||
|                 'backgroundColor' => 'rgba(219, 68, 55, 0.5)', // red
 | ||||
|             ]; | ||||
|                               'label'           => sprintf('%s (%s)', (string)trans('firefly.spent'), $currencyInfo['currency_name']), | ||||
|                               'entries'         => [], | ||||
|                               'type'            => 'bar', | ||||
|                               'backgroundColor' => 'rgba(219, 68, 55, 0.5)', // red
 | ||||
|                           ]; | ||||
| 
 | ||||
|             $chartData[$inKey] | ||||
|                 = [ | ||||
|                 'label'           => sprintf('%s (%s)', (string)trans('firefly.earned'), $currencyInfo['currency_name']), | ||||
|                 'entries'         => [], | ||||
|                 'type'            => 'bar', | ||||
|                 'backgroundColor' => 'rgba(0, 141, 76, 0.5)', // green
 | ||||
|             ]; | ||||
|                     'label'           => sprintf('%s (%s)', (string)trans('firefly.earned'), $currencyInfo['currency_name']), | ||||
|                     'entries'         => [], | ||||
|                     'type'            => 'bar', | ||||
|                     'backgroundColor' => 'rgba(0, 141, 76, 0.5)', // green
 | ||||
|                 ]; | ||||
|             // loop empty periods:
 | ||||
|             foreach (array_keys($periods) as $period) { | ||||
|                 $label                                 = $periods[$period]; | ||||
| @@ -251,71 +285,4 @@ class CategoryController extends Controller | ||||
| 
 | ||||
|         return $this->generator->multiSet($chartData); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Chart for period for transactions without a category. | ||||
|      * TODO test me. | ||||
|      * | ||||
|      * @param Collection $accounts | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function reportPeriodNoCategory(Collection $accounts, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
|         $cache = new CacheProperties(); | ||||
|         $cache->addProperty($start); | ||||
|         $cache->addProperty($end); | ||||
|         $cache->addProperty('chart.category.period.no-cat'); | ||||
|         $cache->addProperty($accounts->pluck('id')->toArray()); | ||||
|         if ($cache->has()) { | ||||
|             return response()->json($cache->get()); | ||||
|         } | ||||
|         $data = $this->reportPeriodChart($accounts, $start, $end, null); | ||||
| 
 | ||||
|         $cache->store($data); | ||||
| 
 | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Chart for a specific period. | ||||
|      * TODO test me, for category refactor. | ||||
|      * | ||||
|      * @param Category $category | ||||
|      * @param Carbon   $date | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
|      */ | ||||
|     public function specificPeriod(Category $category, Carbon $date): JsonResponse | ||||
|     { | ||||
|         $range = app('navigation')->getViewRange(false); | ||||
|         $start = app('navigation')->startOfPeriod($date, $range); | ||||
|         $end   = session()->get('end'); | ||||
|         if ($end < $start) { | ||||
|             [$end, $start] = [$start, $end]; | ||||
|         } | ||||
| 
 | ||||
|         $cache = new CacheProperties(); | ||||
|         $cache->addProperty($start); | ||||
|         $cache->addProperty($end); | ||||
|         $cache->addProperty($category->id); | ||||
|         $cache->addProperty('chart.category.period-chart'); | ||||
|         if ($cache->has()) { | ||||
|             return response()->json($cache->get()); | ||||
|         } | ||||
| 
 | ||||
|         /** @var WholePeriodChartGenerator $chartGenerator */ | ||||
|         $chartGenerator = app(WholePeriodChartGenerator::class); | ||||
|         $chartData      = $chartGenerator->generate($category, $start, $end); | ||||
|         $data           = $this->generator->multiSet($chartData); | ||||
| 
 | ||||
|         $cache->store($data); | ||||
| 
 | ||||
|         return response()->json($data); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -45,13 +45,12 @@ class CategoryReportController extends Controller | ||||
| 
 | ||||
|     /** @var GeneratorInterface Chart generation methods. */ | ||||
|     private $generator; | ||||
| 
 | ||||
|     /** @var OperationsRepositoryInterface */ | ||||
|     private $opsRepository; | ||||
| 
 | ||||
|     /** | ||||
|      * CategoryReportController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -66,14 +65,6 @@ class CategoryReportController extends Controller | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $categories | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function budgetExpense(Collection $accounts, Collection $categories, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
|         $result = []; | ||||
| @@ -102,14 +93,6 @@ class CategoryReportController extends Controller | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $categories | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function categoryExpense(Collection $accounts, Collection $categories, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
|         $result = []; | ||||
| @@ -137,14 +120,6 @@ class CategoryReportController extends Controller | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $categories | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function categoryIncome(Collection $accounts, Collection $categories, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
|         $result = []; | ||||
| @@ -172,14 +147,6 @@ class CategoryReportController extends Controller | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $categories | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function destinationExpense(Collection $accounts, Collection $categories, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
|         $result = []; | ||||
| @@ -208,14 +175,6 @@ class CategoryReportController extends Controller | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $categories | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function destinationIncome(Collection $accounts, Collection $categories, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
|         $result = []; | ||||
| @@ -244,15 +203,6 @@ class CategoryReportController extends Controller | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Category   $category | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * | ||||
|      */ | ||||
|     public function mainChart(Collection $accounts, Category $category, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
|         $chartData = []; | ||||
| @@ -319,39 +269,6 @@ class CategoryReportController extends Controller | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * TODO duplicate function
 | ||||
|      * | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     private function makeEntries(Carbon $start, Carbon $end): array | ||||
|     { | ||||
|         $return         = []; | ||||
|         $format         = app('navigation')->preferredCarbonLocalizedFormat($start, $end); | ||||
|         $preferredRange = app('navigation')->preferredRangeFormat($start, $end); | ||||
|         $currentStart   = clone $start; | ||||
|         while ($currentStart <= $end) { | ||||
|             $currentEnd   = app('navigation')->endOfPeriod($currentStart, $preferredRange); | ||||
|             $key          = $currentStart->isoFormat($format); | ||||
|             $return[$key] = '0'; | ||||
|             $currentStart = clone $currentEnd; | ||||
|             $currentStart->addDay()->startOfDay(); | ||||
|         } | ||||
| 
 | ||||
|         return $return; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $categories | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function sourceExpense(Collection $accounts, Collection $categories, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
|         $result = []; | ||||
| @@ -380,14 +297,6 @@ class CategoryReportController extends Controller | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $categories | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function sourceIncome(Collection $accounts, Collection $categories, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
|         $result = []; | ||||
| @@ -415,4 +324,24 @@ class CategoryReportController extends Controller | ||||
| 
 | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * TODO duplicate function
 | ||||
|      */ | ||||
|     private function makeEntries(Carbon $start, Carbon $end): array | ||||
|     { | ||||
|         $return         = []; | ||||
|         $format         = app('navigation')->preferredCarbonLocalizedFormat($start, $end); | ||||
|         $preferredRange = app('navigation')->preferredRangeFormat($start, $end); | ||||
|         $currentStart   = clone $start; | ||||
|         while ($currentStart <= $end) { | ||||
|             $currentEnd   = app('navigation')->endOfPeriod($currentStart, $preferredRange); | ||||
|             $key          = $currentStart->isoFormat($format); | ||||
|             $return[$key] = '0'; | ||||
|             $currentStart = clone $currentEnd; | ||||
|             $currentStart->addDay()->startOfDay(); | ||||
|         } | ||||
| 
 | ||||
|         return $return; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -33,13 +33,13 @@ use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Support\Collection; | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * Class DoubleReportController | ||||
|  */ | ||||
| class DoubleReportController extends Controller | ||||
| { | ||||
|     /** @var GeneratorInterface Chart generation methods. */ | ||||
|     private $generator; | ||||
| 
 | ||||
|     /** @var OperationsRepositoryInterface */ | ||||
|     private $opsRepository; | ||||
| 
 | ||||
| @@ -48,8 +48,6 @@ class DoubleReportController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * CategoryReportController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -65,14 +63,6 @@ class DoubleReportController extends Controller | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $others | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function budgetExpense(Collection $accounts, Collection $others, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
|         $result   = []; | ||||
| @@ -100,14 +90,6 @@ class DoubleReportController extends Controller | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $others | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function categoryExpense(Collection $accounts, Collection $others, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
|         $result   = []; | ||||
| @@ -135,14 +117,6 @@ class DoubleReportController extends Controller | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $others | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function categoryIncome(Collection $accounts, Collection $others, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
|         $result   = []; | ||||
| @@ -170,15 +144,6 @@ class DoubleReportController extends Controller | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Account    $account | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * | ||||
|      */ | ||||
|     public function mainChart(Collection $accounts, Account $account, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
|         $chartData = []; | ||||
| @@ -247,64 +212,6 @@ class DoubleReportController extends Controller | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * TODO duplicate function
 | ||||
|      * | ||||
|      * @param Collection  $accounts | ||||
|      * @param int         $id | ||||
|      * @param string      $name | ||||
|      * @param null|string $iban | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     private function getCounterpartName(Collection $accounts, int $id, string $name, ?string $iban): string | ||||
|     { | ||||
|         /** @var Account $account */ | ||||
|         foreach ($accounts as $account) { | ||||
|             if ($account->name === $name && $account->id !== $id) { | ||||
|                 return $account->name; | ||||
|             } | ||||
|             if (null !== $account->iban && $account->iban === $iban && $account->id !== $id) { | ||||
|                 return $account->iban; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return $name; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * TODO duplicate function
 | ||||
|      * | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     private function makeEntries(Carbon $start, Carbon $end): array | ||||
|     { | ||||
|         $return         = []; | ||||
|         $format         = app('navigation')->preferredCarbonLocalizedFormat($start, $end); | ||||
|         $preferredRange = app('navigation')->preferredRangeFormat($start, $end); | ||||
|         $currentStart   = clone $start; | ||||
|         while ($currentStart <= $end) { | ||||
|             $currentEnd   = app('navigation')->endOfPeriod($currentStart, $preferredRange); | ||||
|             $key          = $currentStart->isoFormat($format); | ||||
|             $return[$key] = '0'; | ||||
|             $currentStart = clone $currentEnd; | ||||
|             $currentStart->addDay()->startOfDay(); | ||||
|         } | ||||
| 
 | ||||
|         return $return; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $others | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function tagExpense(Collection $accounts, Collection $others, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
|         $result           = []; | ||||
| @@ -331,6 +238,60 @@ class DoubleReportController extends Controller | ||||
|                     $amount                   = app('steam')->positive($journal['amount']); | ||||
|                     $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount); | ||||
|                 } | ||||
| 
 | ||||
|                 // loop each tag:
 | ||||
|                 /** @var array $tag */ | ||||
|                 foreach ($journal['tags'] as $tag) { | ||||
|                     if (in_array($journalId, $includedJournals, true)) { | ||||
|                         continue; | ||||
|                     } | ||||
|                     $includedJournals[] = $journalId; | ||||
|                     // do something
 | ||||
|                     $tagName                  = $tag['name']; | ||||
|                     $title                    = sprintf('%s (%s)', $tagName, $currency['currency_name']); | ||||
|                     $result[$title]           ??= [ | ||||
|                         'amount'          => '0', | ||||
|                         'currency_symbol' => $currency['currency_symbol'], | ||||
|                         'currency_code'   => $currency['currency_code'], | ||||
|                     ]; | ||||
|                     $amount                   = app('steam')->positive($journal['amount']); | ||||
|                     $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         $data = $this->generator->multiCurrencyPieChart($result); | ||||
| 
 | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     public function tagIncome(Collection $accounts, Collection $others, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
|         $result           = []; | ||||
|         $joined           = $this->repository->expandWithDoubles($others); | ||||
|         $accounts         = $accounts->merge($joined); | ||||
|         $income           = $this->opsRepository->listIncome($start, $end, $accounts); | ||||
|         $includedJournals = []; | ||||
|         // loop income.
 | ||||
|         foreach ($income as $currency) { | ||||
|             foreach ($currency['transaction_journals'] as $journal) { | ||||
|                 $journalId = $journal['transaction_journal_id']; | ||||
| 
 | ||||
|                 // no tags? also deserves a sport
 | ||||
|                 if (0 === count($journal['tags'])) { | ||||
|                     $includedJournals[] = $journalId; | ||||
|                     // do something
 | ||||
|                     $tagName                  = trans('firefly.no_tags'); | ||||
|                     $title                    = sprintf('%s (%s)', $tagName, $currency['currency_name']); | ||||
|                     $result[$title]           ??= [ | ||||
|                         'amount'          => '0', | ||||
|                         'currency_symbol' => $currency['currency_symbol'], | ||||
|                         'currency_code'   => $currency['currency_code'], | ||||
|                     ]; | ||||
|                     $amount                   = app('steam')->positive($journal['amount']); | ||||
|                     $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount); | ||||
|                 } | ||||
| 
 | ||||
|                 // loop each tag:
 | ||||
|                 /** @var array $tag */ | ||||
|                 foreach ($journal['tags'] as $tag) { | ||||
| @@ -358,62 +319,40 @@ class DoubleReportController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $others | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * TODO duplicate function
 | ||||
|      */ | ||||
|     public function tagIncome(Collection $accounts, Collection $others, Carbon $start, Carbon $end): JsonResponse | ||||
|     private function getCounterpartName(Collection $accounts, int $id, string $name, ?string $iban): string | ||||
|     { | ||||
|         $result           = []; | ||||
|         $joined           = $this->repository->expandWithDoubles($others); | ||||
|         $accounts         = $accounts->merge($joined); | ||||
|         $income           = $this->opsRepository->listIncome($start, $end, $accounts); | ||||
|         $includedJournals = []; | ||||
|         // loop income.
 | ||||
|         foreach ($income as $currency) { | ||||
|             foreach ($currency['transaction_journals'] as $journal) { | ||||
|                 $journalId = $journal['transaction_journal_id']; | ||||
| 
 | ||||
|                 // no tags? also deserves a sport
 | ||||
|                 if (0 === count($journal['tags'])) { | ||||
|                     $includedJournals[] = $journalId; | ||||
|                     // do something
 | ||||
|                     $tagName                  = trans('firefly.no_tags'); | ||||
|                     $title                    = sprintf('%s (%s)', $tagName, $currency['currency_name']); | ||||
|                     $result[$title]           ??= [ | ||||
|                         'amount'          => '0', | ||||
|                         'currency_symbol' => $currency['currency_symbol'], | ||||
|                         'currency_code'   => $currency['currency_code'], | ||||
|                     ]; | ||||
|                     $amount                   = app('steam')->positive($journal['amount']); | ||||
|                     $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount); | ||||
|                 } | ||||
|                 // loop each tag:
 | ||||
|                 /** @var array $tag */ | ||||
|                 foreach ($journal['tags'] as $tag) { | ||||
|                     if (in_array($journalId, $includedJournals, true)) { | ||||
|                         continue; | ||||
|                     } | ||||
|                     $includedJournals[] = $journalId; | ||||
|                     // do something
 | ||||
|                     $tagName                  = $tag['name']; | ||||
|                     $title                    = sprintf('%s (%s)', $tagName, $currency['currency_name']); | ||||
|                     $result[$title]           ??= [ | ||||
|                         'amount'          => '0', | ||||
|                         'currency_symbol' => $currency['currency_symbol'], | ||||
|                         'currency_code'   => $currency['currency_code'], | ||||
|                     ]; | ||||
|                     $amount                   = app('steam')->positive($journal['amount']); | ||||
|                     $result[$title]['amount'] = bcadd($result[$title]['amount'], $amount); | ||||
|                 } | ||||
|         /** @var Account $account */ | ||||
|         foreach ($accounts as $account) { | ||||
|             if ($account->name === $name && $account->id !== $id) { | ||||
|                 return $account->name; | ||||
|             } | ||||
|             if (null !== $account->iban && $account->iban === $iban && $account->id !== $id) { | ||||
|                 return $account->iban; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         $data = $this->generator->multiCurrencyPieChart($result); | ||||
|         return $name; | ||||
|     } | ||||
| 
 | ||||
|         return response()->json($data); | ||||
|     /** | ||||
|      * TODO duplicate function
 | ||||
|      */ | ||||
|     private function makeEntries(Carbon $start, Carbon $end): array | ||||
|     { | ||||
|         $return         = []; | ||||
|         $format         = app('navigation')->preferredCarbonLocalizedFormat($start, $end); | ||||
|         $preferredRange = app('navigation')->preferredRangeFormat($start, $end); | ||||
|         $currentStart   = clone $start; | ||||
|         while ($currentStart <= $end) { | ||||
|             $currentEnd   = app('navigation')->endOfPeriod($currentStart, $preferredRange); | ||||
|             $key          = $currentStart->isoFormat($format); | ||||
|             $return[$key] = '0'; | ||||
|             $currentStart = clone $currentEnd; | ||||
|             $currentStart->addDay()->startOfDay(); | ||||
|         } | ||||
| 
 | ||||
|         return $return; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -33,7 +33,6 @@ use FireflyIII\Support\Http\Controllers\AugumentData; | ||||
| use FireflyIII\Support\Http\Controllers\TransactionCalculation; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Support\Collection; | ||||
| use JsonException; | ||||
| 
 | ||||
| /** | ||||
|  * Separate controller because many helper functions are shared. | ||||
| @@ -47,13 +46,12 @@ class ExpenseReportController extends Controller | ||||
| 
 | ||||
|     /** @var AccountRepositoryInterface The account repository */ | ||||
|     protected $accountRepository; | ||||
| 
 | ||||
|     /** @var GeneratorInterface Chart generation methods. */ | ||||
|     protected $generator; | ||||
| 
 | ||||
|     /** | ||||
|      * ExpenseReportController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -73,13 +71,7 @@ class ExpenseReportController extends Controller | ||||
|      * | ||||
|      * TODO this chart is not multi currency aware. | ||||
|      * | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $expense | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws JsonException | ||||
|      * @throws \JsonException | ||||
|      */ | ||||
|     public function mainChart(Collection $accounts, Collection $expense, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
| @@ -113,27 +105,27 @@ class ExpenseReportController extends Controller | ||||
|             // first is always expense account:
 | ||||
|             /** @var Account $exp */ | ||||
|             $exp                          = $combination->first(); | ||||
|             $chartData[$exp->id . '-in']  = [ | ||||
|             $chartData[$exp->id.'-in']  = [ | ||||
|                 'label'   => sprintf('%s (%s)', $name, (string)trans('firefly.income')), | ||||
|                 'type'    => 'bar', | ||||
|                 'yAxisID' => 'y-axis-0', | ||||
|                 'entries' => [], | ||||
|             ]; | ||||
|             $chartData[$exp->id . '-out'] = [ | ||||
|             $chartData[$exp->id.'-out'] = [ | ||||
|                 'label'   => sprintf('%s (%s)', $name, (string)trans('firefly.expenses')), | ||||
|                 'type'    => 'bar', | ||||
|                 'yAxisID' => 'y-axis-0', | ||||
|                 'entries' => [], | ||||
|             ]; | ||||
|             // total in, total out:
 | ||||
|             $chartData[$exp->id . '-total-in']  = [ | ||||
|             $chartData[$exp->id.'-total-in']  = [ | ||||
|                 'label'   => sprintf('%s (%s)', $name, (string)trans('firefly.sum_of_income')), | ||||
|                 'type'    => 'line', | ||||
|                 'fill'    => false, | ||||
|                 'yAxisID' => 'y-axis-1', | ||||
|                 'entries' => [], | ||||
|             ]; | ||||
|             $chartData[$exp->id . '-total-out'] = [ | ||||
|             $chartData[$exp->id.'-total-out'] = [ | ||||
|                 'label'   => sprintf('%s (%s)', $name, (string)trans('firefly.sum_of_expenses')), | ||||
|                 'type'    => 'line', | ||||
|                 'fill'    => false, | ||||
| @@ -147,7 +139,7 @@ class ExpenseReportController extends Controller | ||||
| 
 | ||||
|         while ($currentStart < $end) { | ||||
|             $currentEnd = clone $currentStart; | ||||
|             $currentEnd = $currentEnd->$function(); // @phpstan-ignore-line
 | ||||
|             $currentEnd = $currentEnd->{$function}(); // @phpstan-ignore-line
 | ||||
| 
 | ||||
|             // get expenses grouped by opposing name:
 | ||||
|             $expenses = $this->groupByName($this->getExpensesForOpposing($accounts, $all, $currentStart, $currentEnd)); | ||||
| @@ -158,10 +150,10 @@ class ExpenseReportController extends Controller | ||||
|                 // first is always expense account:
 | ||||
|                 /** @var Account $exp */ | ||||
|                 $exp            = $combination->first(); | ||||
|                 $labelIn        = $exp->id . '-in'; | ||||
|                 $labelOut       = $exp->id . '-out'; | ||||
|                 $labelSumIn     = $exp->id . '-total-in'; | ||||
|                 $labelSumOut    = $exp->id . '-total-out'; | ||||
|                 $labelIn        = $exp->id.'-in'; | ||||
|                 $labelOut       = $exp->id.'-out'; | ||||
|                 $labelSumIn     = $exp->id.'-total-in'; | ||||
|                 $labelSumOut    = $exp->id.'-total-out'; | ||||
|                 $currentIncome  = bcmul($income[$name] ?? '0', '-1'); | ||||
|                 $currentExpense = $expenses[$name] ?? '0'; | ||||
| 
 | ||||
| @@ -177,6 +169,7 @@ class ExpenseReportController extends Controller | ||||
|                 $chartData[$labelSumIn]['entries'][$label]  = $sumOfIncome[$exp->id]; | ||||
|                 $chartData[$labelSumOut]['entries'][$label] = $sumOfExpense[$exp->id]; | ||||
|             } | ||||
| 
 | ||||
|             /** @var Carbon $currentStart */ | ||||
|             $currentStart = clone $currentEnd; | ||||
|             $currentStart->addDay(); | ||||
|   | ||||
| @@ -46,8 +46,6 @@ class PiggyBankController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * PiggyBankController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -61,10 +59,6 @@ class PiggyBankController extends Controller | ||||
|      * | ||||
|      * TODO this chart is not multi currency aware. | ||||
|      * | ||||
|      * @param PiggyBankRepositoryInterface $repository | ||||
|      * @param PiggyBank                    $piggyBank | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function history(PiggyBankRepositoryInterface $repository, PiggyBank $piggyBank): JsonResponse | ||||
| @@ -83,7 +77,7 @@ class PiggyBankController extends Controller | ||||
|         // get first event or start date of piggy bank or today
 | ||||
|         $startDate = $piggyBank->startdate ?? today(config('app.timezone')); | ||||
| 
 | ||||
|         /** @var PiggyBankEvent|null $firstEvent */ | ||||
|         /** @var null|PiggyBankEvent $firstEvent */ | ||||
|         $firstEvent = $set->first(); | ||||
|         $firstDate  = null === $firstEvent ? new Carbon() : $firstEvent->date; | ||||
| 
 | ||||
|   | ||||
| @@ -36,7 +36,6 @@ use FireflyIII\Support\Http\Controllers\BasicDataSupport; | ||||
| use FireflyIII\Support\Http\Controllers\ChartGeneration; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Support\Collection; | ||||
| use JsonException; | ||||
| 
 | ||||
| /** | ||||
|  * Class ReportController. | ||||
| @@ -51,8 +50,6 @@ class ReportController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * ReportController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -64,12 +61,6 @@ class ReportController extends Controller | ||||
|     /** | ||||
|      * This chart, by default, is shown on the multi-year and year report pages, | ||||
|      * which means that giving it a 2 week "period" should be enough granularity. | ||||
|      * | ||||
|      * @param Collection $accounts | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function netWorth(Collection $accounts, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
| @@ -85,6 +76,7 @@ class ReportController extends Controller | ||||
|         $locale    = app('steam')->getLocale(); | ||||
|         $current   = clone $start; | ||||
|         $chartData = []; | ||||
| 
 | ||||
|         /** @var NetWorthInterface $helper */ | ||||
|         $helper = app(NetWorthInterface::class); | ||||
|         $helper->setUser(auth()->user()); | ||||
| @@ -120,7 +112,7 @@ class ReportController extends Controller | ||||
|                 $label      = $current->isoFormat((string)trans('config.month_and_day_js', [], $locale)); | ||||
|                 if (!array_key_exists($currencyId, $chartData)) { | ||||
|                     $chartData[$currencyId] = [ | ||||
|                         'label'           => 'Net worth in ' . $netWorthItem['currency_name'], | ||||
|                         'label'           => 'Net worth in '.$netWorthItem['currency_name'], | ||||
|                         'type'            => 'line', | ||||
|                         'currency_symbol' => $netWorthItem['currency_symbol'], | ||||
|                         'currency_code'   => $netWorthItem['currency_code'], | ||||
| @@ -141,12 +133,7 @@ class ReportController extends Controller | ||||
|     /** | ||||
|      * Shows income and expense, debit/credit: operations. | ||||
|      * | ||||
|      * @param Collection $accounts | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws JsonException | ||||
|      * @throws \JsonException | ||||
|      */ | ||||
|     public function operations(Collection $accounts, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
| @@ -168,8 +155,8 @@ class ReportController extends Controller | ||||
|         // get journals for entire period:
 | ||||
|         $data      = []; | ||||
|         $chartData = [ | ||||
| 
 | ||||
|         ]; | ||||
| 
 | ||||
|         /** @var GroupCollectorInterface $collector */ | ||||
|         $collector = app(GroupCollectorInterface::class); | ||||
|         $collector->setRange($start, $end)->withAccountInformation(); | ||||
| @@ -202,9 +189,8 @@ class ReportController extends Controller | ||||
|             // transfer or reconcile or opening balance, and these accounts are the destination.
 | ||||
|             if ( | ||||
|                 TransactionType::DEPOSIT === $journal['transaction_type_type'] | ||||
|                 || | ||||
| 
 | ||||
|                 ( | ||||
|                 || ( | ||||
|                     ( | ||||
|                         TransactionType::TRANSFER === $journal['transaction_type_type'] | ||||
|                         || TransactionType::RECONCILIATION === $journal['transaction_type_type'] | ||||
| @@ -238,15 +224,14 @@ class ReportController extends Controller | ||||
|                 'currency_symbol' => $currency['currency_symbol'], | ||||
|                 'currency_code'   => $currency['currency_code'], | ||||
|                 'entries'         => [], | ||||
| 
 | ||||
|             ]; | ||||
|             // loop all possible periods between $start and $end
 | ||||
|             $currentStart = clone $start; | ||||
|             while ($currentStart <= $end) { | ||||
|                 $key                        = $currentStart->format($format); | ||||
|                 $title                      = $currentStart->isoFormat($titleFormat); | ||||
|                 $income['entries'][$title]  = app('steam')->bcround(($currency[$key]['earned'] ?? '0'), $currency['currency_decimal_places']); | ||||
|                 $expense['entries'][$title] = app('steam')->bcround(($currency[$key]['spent'] ?? '0'), $currency['currency_decimal_places']); | ||||
|                 $income['entries'][$title]  = app('steam')->bcround($currency[$key]['earned'] ?? '0', $currency['currency_decimal_places']); | ||||
|                 $expense['entries'][$title] = app('steam')->bcround($currency[$key]['spent'] ?? '0', $currency['currency_decimal_places']); | ||||
|                 $currentStart               = app('navigation')->addPeriod($currentStart, $preferredRange, 0); | ||||
|             } | ||||
| 
 | ||||
|   | ||||
| @@ -49,8 +49,6 @@ class TagReportController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * TagReportController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -67,14 +65,6 @@ class TagReportController extends Controller | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $tags | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function budgetExpense(Collection $accounts, Collection $tags, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
|         $result = []; | ||||
| @@ -103,14 +93,6 @@ class TagReportController extends Controller | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $tags | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function categoryExpense(Collection $accounts, Collection $tags, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
|         $result = []; | ||||
| @@ -139,14 +121,6 @@ class TagReportController extends Controller | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $tags | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function categoryIncome(Collection $accounts, Collection $tags, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
|         $result = []; | ||||
| @@ -175,14 +149,6 @@ class TagReportController extends Controller | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $tags | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function destinationExpense(Collection $accounts, Collection $tags, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
|         $result = []; | ||||
| @@ -211,14 +177,6 @@ class TagReportController extends Controller | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $tags | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function destinationIncome(Collection $accounts, Collection $tags, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
|         $result = []; | ||||
| @@ -249,14 +207,6 @@ class TagReportController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Generate main tag overview chart. | ||||
|      * | ||||
|      * @param Collection $accounts | ||||
|      * @param Tag        $tag | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * | ||||
|      */ | ||||
|     public function mainChart(Collection $accounts, Tag $tag, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
| @@ -324,39 +274,6 @@ class TagReportController extends Controller | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * TODO duplicate function
 | ||||
|      * | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     private function makeEntries(Carbon $start, Carbon $end): array | ||||
|     { | ||||
|         $return         = []; | ||||
|         $format         = app('navigation')->preferredCarbonLocalizedFormat($start, $end); | ||||
|         $preferredRange = app('navigation')->preferredRangeFormat($start, $end); | ||||
|         $currentStart   = clone $start; | ||||
|         while ($currentStart <= $end) { | ||||
|             $currentEnd   = app('navigation')->endOfPeriod($currentStart, $preferredRange); | ||||
|             $key          = $currentStart->isoFormat($format); | ||||
|             $return[$key] = '0'; | ||||
|             $currentStart = clone $currentEnd; | ||||
|             $currentStart->addDay()->startOfDay(); | ||||
|         } | ||||
| 
 | ||||
|         return $return; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $tags | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function sourceExpense(Collection $accounts, Collection $tags, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
|         $result = []; | ||||
| @@ -385,14 +302,6 @@ class TagReportController extends Controller | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $tags | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function sourceIncome(Collection $accounts, Collection $tags, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
|         $result = []; | ||||
| @@ -421,14 +330,6 @@ class TagReportController extends Controller | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $tags | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function tagExpense(Collection $accounts, Collection $tags, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
|         $result = []; | ||||
| @@ -455,14 +356,6 @@ class TagReportController extends Controller | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $tags | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function tagIncome(Collection $accounts, Collection $tags, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
|         $result = []; | ||||
| @@ -488,4 +381,24 @@ class TagReportController extends Controller | ||||
| 
 | ||||
|         return response()->json($data); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * TODO duplicate function
 | ||||
|      */ | ||||
|     private function makeEntries(Carbon $start, Carbon $end): array | ||||
|     { | ||||
|         $return         = []; | ||||
|         $format         = app('navigation')->preferredCarbonLocalizedFormat($start, $end); | ||||
|         $preferredRange = app('navigation')->preferredRangeFormat($start, $end); | ||||
|         $currentStart   = clone $start; | ||||
|         while ($currentStart <= $end) { | ||||
|             $currentEnd   = app('navigation')->endOfPeriod($currentStart, $preferredRange); | ||||
|             $key          = $currentStart->isoFormat($format); | ||||
|             $return[$key] = '0'; | ||||
|             $currentStart = clone $currentEnd; | ||||
|             $currentStart->addDay()->startOfDay(); | ||||
|         } | ||||
| 
 | ||||
|         return $return; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -50,9 +50,6 @@ class TransactionController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function budgets(Carbon $start, Carbon $end) | ||||
| @@ -64,6 +61,7 @@ class TransactionController extends Controller | ||||
|         if ($cache->has()) { | ||||
|             return response()->json($cache->get()); | ||||
|         } | ||||
| 
 | ||||
|         /** @var GroupCollectorInterface $collector */ | ||||
|         $collector = app(GroupCollectorInterface::class); | ||||
|         $collector->setRange($start, $end); | ||||
| @@ -92,10 +90,6 @@ class TransactionController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param string $objectType | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function categories(string $objectType, Carbon $start, Carbon $end) | ||||
| @@ -108,6 +102,7 @@ class TransactionController extends Controller | ||||
|         if ($cache->has()) { | ||||
|             return response()->json($cache->get()); | ||||
|         } | ||||
| 
 | ||||
|         /** @var GroupCollectorInterface $collector */ | ||||
|         $collector = app(GroupCollectorInterface::class); | ||||
|         $collector->setRange($start, $end); | ||||
| @@ -145,10 +140,6 @@ class TransactionController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param string $objectType | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function destinationAccounts(string $objectType, Carbon $start, Carbon $end) | ||||
| @@ -161,6 +152,7 @@ class TransactionController extends Controller | ||||
|         if ($cache->has()) { | ||||
|             return response()->json($cache->get()); | ||||
|         } | ||||
| 
 | ||||
|         /** @var GroupCollectorInterface $collector */ | ||||
|         $collector = app(GroupCollectorInterface::class); | ||||
|         $collector->setRange($start, $end); | ||||
| @@ -198,10 +190,6 @@ class TransactionController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param string $objectType | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function sourceAccounts(string $objectType, Carbon $start, Carbon $end) | ||||
| @@ -214,6 +202,7 @@ class TransactionController extends Controller | ||||
|         if ($cache->has()) { | ||||
|             return response()->json($cache->get()); | ||||
|         } | ||||
| 
 | ||||
|         /** @var GroupCollectorInterface $collector */ | ||||
|         $collector = app(GroupCollectorInterface::class); | ||||
|         $collector->setRange($start, $end); | ||||
|   | ||||
| @@ -29,11 +29,9 @@ use Illuminate\Foundation\Auth\Access\AuthorizesRequests; | ||||
| use Illuminate\Foundation\Bus\DispatchesJobs; | ||||
| use Illuminate\Foundation\Validation\ValidatesRequests; | ||||
| use Illuminate\Routing\Controller as BaseController; | ||||
| use Route; | ||||
| 
 | ||||
| /** | ||||
|  * Class Controller. | ||||
|  * | ||||
|  */ | ||||
| abstract class Controller extends BaseController | ||||
| { | ||||
| @@ -50,8 +48,6 @@ abstract class Controller extends BaseController | ||||
| 
 | ||||
|     /** | ||||
|      * Controller constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -112,7 +108,7 @@ abstract class Controller extends BaseController | ||||
|                     app('view')->share('locale', $locale); | ||||
|                     app('view')->share('shownDemo', $shownDemo); | ||||
|                     app('view')->share('current_route_name', $page); | ||||
|                     app('view')->share('original_route_name', Route::currentRouteName()); | ||||
|                     app('view')->share('original_route_name', \Route::currentRouteName()); | ||||
|                 } | ||||
|                 app('view')->share('darkMode', $darkMode); | ||||
| 
 | ||||
|   | ||||
| @@ -24,7 +24,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Http\Controllers; | ||||
| 
 | ||||
| use Carbon\Carbon; | ||||
| use DB; | ||||
| use Exception; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Http\Middleware\IsDemoUser; | ||||
| @@ -42,11 +41,9 @@ use Illuminate\View\View; | ||||
| use Monolog\Handler\RotatingFileHandler; | ||||
| use Psr\Container\ContainerExceptionInterface; | ||||
| use Psr\Container\NotFoundExceptionInterface; | ||||
| use const PHP_SAPI; | ||||
| 
 | ||||
| /** | ||||
|  * Class DebugController | ||||
|  * | ||||
|  */ | ||||
| class DebugController extends Controller | ||||
| { | ||||
| @@ -54,8 +51,6 @@ class DebugController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * DebugController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -78,15 +73,15 @@ class DebugController extends Controller | ||||
|         Log::critical('This is a test message at the CRITICAL level.'); | ||||
|         Log::alert('This is a test message at the ALERT level.'); | ||||
|         Log::emergency('This is a test message at the EMERGENCY level.'); | ||||
| 
 | ||||
|         throw new FireflyException('A very simple test error.'); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Clear log and session. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * @return Redirector|RedirectResponse | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function flush(Request $request) | ||||
| @@ -101,9 +96,10 @@ class DebugController extends Controller | ||||
|         app('log')->debug('Call route:clear...'); | ||||
|         Artisan::call('route:clear'); | ||||
|         app('log')->debug('Call twig:clean...'); | ||||
| 
 | ||||
|         try { | ||||
|             Artisan::call('twig:clean'); | ||||
|         } catch (Exception $e) {  // intentional generic exception
 | ||||
|         } catch (\Exception $e) {  // intentional generic exception
 | ||||
|             throw new FireflyException($e->getMessage(), 0, $e); | ||||
|         } | ||||
| 
 | ||||
| @@ -117,6 +113,7 @@ class DebugController extends Controller | ||||
|      * Show debug info. | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function index() | ||||
| @@ -140,15 +137,27 @@ class DebugController extends Controller | ||||
|         } | ||||
|         if ('' !== $logContent) { | ||||
|             // last few lines
 | ||||
|             $logContent = 'Truncated from this point <----|' . substr((string)$logContent, -16384); | ||||
|             $logContent = 'Truncated from this point <----|'.substr((string)$logContent, -16384); | ||||
|         } | ||||
| 
 | ||||
|         return view('debug', compact('table', 'now', 'logContent')); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @return string | ||||
|      * Flash all types of messages. | ||||
|      * | ||||
|      * @return Redirector|RedirectResponse | ||||
|      */ | ||||
|     public function testFlash(Request $request) | ||||
|     { | ||||
|         $request->session()->flash('success', 'This is a success message.'); | ||||
|         $request->session()->flash('info', 'This is an info message.'); | ||||
|         $request->session()->flash('warning', 'This is a warning.'); | ||||
|         $request->session()->flash('error', 'This is an error!'); | ||||
| 
 | ||||
|         return redirect(route('home')); | ||||
|     } | ||||
| 
 | ||||
|     private function generateTable(): string | ||||
|     { | ||||
|         // system information:
 | ||||
| @@ -160,20 +169,18 @@ class DebugController extends Controller | ||||
|         return (string)view('partials.debug-table', compact('system', 'docker', 'app', 'user')); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     private function getSystemInformation(): array | ||||
|     { | ||||
|         $maxFileSize   = app('steam')->phpBytes((string)ini_get('upload_max_filesize')); | ||||
|         $maxPostSize   = app('steam')->phpBytes((string)ini_get('post_max_size')); | ||||
|         $drivers       = DB::availableDrivers(); | ||||
|         $currentDriver = DB::getDriverName(); | ||||
|         $drivers       = \DB::availableDrivers(); | ||||
|         $currentDriver = \DB::getDriverName(); | ||||
| 
 | ||||
|         return [ | ||||
|             'db_version'      => app('fireflyconfig')->get('db_version', 1)->data, | ||||
|             'php_version'     => PHP_VERSION, | ||||
|             'php_os'          => PHP_OS, | ||||
|             'interface'       => PHP_SAPI, | ||||
|             'interface'       => \PHP_SAPI, | ||||
|             'bcscale'         => bcscale(), | ||||
|             'display_errors'  => ini_get('display_errors'), | ||||
|             'error_reporting' => $this->errorReporting((int)ini_get('error_reporting')), | ||||
| @@ -183,9 +190,6 @@ class DebugController extends Controller | ||||
|         ]; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     private function getBuildInfo(): array | ||||
|     { | ||||
|         $return = [ | ||||
| @@ -194,21 +198,22 @@ class DebugController extends Controller | ||||
|             'build_date'      => '(unknown)', | ||||
|             'base_build'      => '(unknown)', | ||||
|             'base_build_date' => '(unknown)', | ||||
| 
 | ||||
|         ]; | ||||
| 
 | ||||
|         try { | ||||
|             if (file_exists('/var/www/counter-main.txt')) { | ||||
|                 $return['build'] = trim((string)file_get_contents('/var/www/counter-main.txt')); | ||||
|             } | ||||
|         } catch (Exception $e) { // @phpstan-ignore-line
 | ||||
|         } catch (\Exception $e) { // @phpstan-ignore-line
 | ||||
|             app('log')->debug('Could not check build counter, but thats ok.'); | ||||
|             app('log')->warning($e->getMessage()); | ||||
|         } | ||||
| 
 | ||||
|         try { | ||||
|             if (file_exists('/var/www/build-date-main.txt')) { | ||||
|                 $return['build_date'] = trim((string)file_get_contents('/var/www/build-date-main.txt')); | ||||
|             } | ||||
|         } catch (Exception $e) { // @phpstan-ignore-line
 | ||||
|         } catch (\Exception $e) { // @phpstan-ignore-line
 | ||||
|             app('log')->debug('Could not check build date, but thats ok.'); | ||||
|             app('log')->warning($e->getMessage()); | ||||
|         } | ||||
| @@ -218,12 +223,10 @@ class DebugController extends Controller | ||||
|         if ('' !== (string)env('BASE_IMAGE_DATE')) { | ||||
|             $return['base_build_date'] = env('BASE_IMAGE_DATE'); | ||||
|         } | ||||
| 
 | ||||
|         return $return; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @return array | ||||
|      */ | ||||
|     private function getAppInfo(): array | ||||
|     { | ||||
|         $userGuard = config('auth.defaults.guard'); | ||||
| @@ -243,8 +246,8 @@ class DebugController extends Controller | ||||
|             'audit_log_channel'  => envNonEmpty('AUDIT_LOG_CHANNEL', '(empty)'), | ||||
|             'default_language'   => (string)config('firefly.default_language'), | ||||
|             'default_locale'     => (string)config('firefly.default_locale'), | ||||
|             'remote_header'      => $userGuard === 'remote_user_guard' ? config('auth.guard_header') : 'N/A', | ||||
|             'remote_mail_header' => $userGuard === 'remote_user_guard' ? config('auth.guard_email') : 'N/A', | ||||
|             'remote_header'      => 'remote_user_guard' === $userGuard ? config('auth.guard_header') : 'N/A', | ||||
|             'remote_mail_header' => 'remote_user_guard' === $userGuard ? config('auth.guard_email') : 'N/A', | ||||
|             'stateful_domains'   => implode(', ', config('sanctum.stateful')), | ||||
| 
 | ||||
|             // the dates for the cron job are based on the recurring cron job's times.
 | ||||
| @@ -257,7 +260,6 @@ class DebugController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @return array | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
|      */ | ||||
| @@ -292,12 +294,10 @@ class DebugController extends Controller | ||||
|         ]; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @return string | ||||
|      */ | ||||
|     private function getUserFlags(): string | ||||
|     { | ||||
|         $flags = []; | ||||
| 
 | ||||
|         /** @var User $user */ | ||||
|         $user = auth()->user(); | ||||
| 
 | ||||
| @@ -338,24 +338,7 @@ class DebugController extends Controller | ||||
|         if ($user->bills()->count() > 0) { | ||||
|             $flags[] = '<span title="Has subscriptions">:email:</span>'; | ||||
|         } | ||||
| 
 | ||||
|         return implode(' ', $flags); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Flash all types of messages. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      */ | ||||
|     public function testFlash(Request $request) | ||||
|     { | ||||
|         $request->session()->flash('success', 'This is a success message.'); | ||||
|         $request->session()->flash('info', 'This is an info message.'); | ||||
|         $request->session()->flash('warning', 'This is a warning.'); | ||||
|         $request->session()->flash('error', 'This is an error!'); | ||||
| 
 | ||||
|         return redirect(route('home')); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|   | ||||
| @@ -44,8 +44,6 @@ class IndexController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * IndexController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -65,7 +63,6 @@ class IndexController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @return LaravelResponse | ||||
|      * @throws FireflyException | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
| @@ -90,19 +87,21 @@ class IndexController extends Controller | ||||
| 
 | ||||
|         $name   = sprintf('%s_transaction_export.csv', date('Y_m_d')); | ||||
|         $quoted = sprintf('"%s"', addcslashes($name, '"\\')); | ||||
| 
 | ||||
|         // headers for CSV file.
 | ||||
|         /** @var LaravelResponse $response */ | ||||
|         $response = response($result['transactions']); | ||||
|         $response | ||||
|             ->header('Content-Description', 'File Transfer') | ||||
|             ->header('Content-Type', 'text/x-csv') | ||||
|             ->header('Content-Disposition', 'attachment; filename=' . $quoted) | ||||
|             //->header('Content-Transfer-Encoding', 'binary')
 | ||||
|             ->header('Content-Disposition', 'attachment; filename='.$quoted) | ||||
|             // ->header('Content-Transfer-Encoding', 'binary')
 | ||||
|             ->header('Connection', 'Keep-Alive') | ||||
|             ->header('Expires', '0') | ||||
|             ->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0') | ||||
|             ->header('Pragma', 'public') | ||||
|             ->header('Content-Length', (string)strlen($result['transactions'])); | ||||
|             ->header('Content-Length', (string)strlen($result['transactions'])) | ||||
|         ; | ||||
| 
 | ||||
|         // return CSV file made from 'transactions' array.
 | ||||
|         return $response; | ||||
|   | ||||
| @@ -25,7 +25,6 @@ namespace FireflyIII\Http\Controllers; | ||||
| 
 | ||||
| use Carbon\Carbon; | ||||
| use Carbon\Exceptions\InvalidFormatException; | ||||
| use Exception; | ||||
| use FireflyIII\Events\RequestedVersionCheckStatus; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Helpers\Collector\GroupCollectorInterface; | ||||
| @@ -46,8 +45,6 @@ class HomeController extends Controller | ||||
| { | ||||
|     /** | ||||
|      * HomeController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -60,15 +57,13 @@ class HomeController extends Controller | ||||
|     /** | ||||
|      * Change index date range. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws Exception | ||||
|      * @throws \Exception | ||||
|      */ | ||||
|     public function dateRange(Request $request): JsonResponse | ||||
|     { | ||||
|         $stringStart = ''; | ||||
|         $stringEnd   = ''; | ||||
| 
 | ||||
|         try { | ||||
|             $stringStart = e((string)$request->get('start')); | ||||
|             $start       = Carbon::createFromFormat('Y-m-d', $stringStart); | ||||
| @@ -76,6 +71,7 @@ class HomeController extends Controller | ||||
|             app('log')->error(sprintf('Start: could not parse date string "%s" so ignore it.', $stringStart)); | ||||
|             $start = Carbon::now()->startOfMonth(); | ||||
|         } | ||||
| 
 | ||||
|         try { | ||||
|             $stringEnd = e((string)$request->get('end')); | ||||
|             $end       = Carbon::createFromFormat('Y-m-d', $stringEnd); | ||||
| @@ -120,9 +116,6 @@ class HomeController extends Controller | ||||
|     /** | ||||
|      * Show index. | ||||
|      * | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * | ||||
|      * @return mixed | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function index(AccountRepositoryInterface $repository): mixed | ||||
| @@ -142,9 +135,9 @@ class HomeController extends Controller | ||||
|             $frontPageArray = []; | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         /** @var Carbon $start */ | ||||
|         $start = session('start', today(config('app.timezone'))->startOfMonth()); | ||||
| 
 | ||||
|         /** @var Carbon $end */ | ||||
|         $end      = session('end', today(config('app.timezone'))->endOfMonth()); | ||||
|         $accounts = $repository->getAccountsById($frontPageArray); | ||||
|   | ||||
| @@ -33,7 +33,6 @@ use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface; | ||||
| use FireflyIII\Support\Http\Controllers\GetConfigurationData; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Http\Response; | ||||
| use JsonException; | ||||
| use Psr\Container\ContainerExceptionInterface; | ||||
| use Psr\Container\NotFoundExceptionInterface; | ||||
| 
 | ||||
| @@ -47,9 +46,6 @@ class JavascriptController extends Controller | ||||
|     /** | ||||
|      * Show info about accounts. | ||||
|      * | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * | ||||
|      * @return Response | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
|      */ | ||||
| @@ -72,20 +68,18 @@ class JavascriptController extends Controller | ||||
| 
 | ||||
|         return response() | ||||
|             ->view('javascript.accounts', $data) | ||||
|             ->header('Content-Type', 'text/javascript'); | ||||
|             ->header('Content-Type', 'text/javascript') | ||||
|         ; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get info about currencies. | ||||
|      * | ||||
|      * @param CurrencyRepositoryInterface $repository | ||||
|      * | ||||
|      * @return Response | ||||
|      */ | ||||
|     public function currencies(CurrencyRepositoryInterface $repository): Response | ||||
|     { | ||||
|         $currencies = $repository->get(); | ||||
|         $data       = ['currencies' => []]; | ||||
| 
 | ||||
|         /** @var TransactionCurrency $currency */ | ||||
|         foreach ($currencies as $currency) { | ||||
|             $currencyId                      = $currency->id; | ||||
| @@ -95,18 +89,15 @@ class JavascriptController extends Controller | ||||
| 
 | ||||
|         return response() | ||||
|             ->view('javascript.currencies', $data) | ||||
|             ->header('Content-Type', 'text/javascript'); | ||||
|             ->header('Content-Type', 'text/javascript') | ||||
|         ; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Show some common variables to be used in scripts. | ||||
|      * | ||||
|      * @param Request                    $request | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * | ||||
|      * @return Response | ||||
|      * @throws FireflyException | ||||
|      * @throws JsonException | ||||
|      * @throws \JsonException | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
|      */ | ||||
| @@ -139,18 +130,18 @@ class JavascriptController extends Controller | ||||
| 
 | ||||
|         return response() | ||||
|             ->view('javascript.variables', $data) | ||||
|             ->header('Content-Type', 'text/javascript'); | ||||
|             ->header('Content-Type', 'text/javascript') | ||||
|         ; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Bit of a hack but OK. | ||||
|      * | ||||
|      * @return Response | ||||
|      */ | ||||
|     public function variablesV2(): Response | ||||
|     { | ||||
|         /** @var Carbon $start */ | ||||
|         $start = clone session('start', today(config('app.timezone'))->startOfMonth()); | ||||
| 
 | ||||
|         /** @var Carbon $end */ | ||||
|         $end = clone session('end', today(config('app.timezone'))->endOfMonth()); | ||||
| 
 | ||||
|   | ||||
| @@ -28,6 +28,4 @@ use FireflyIII\Http\Controllers\Controller; | ||||
| /** | ||||
|  * Class AutoCompleteController. | ||||
|  */ | ||||
| class AutoCompleteController extends Controller | ||||
| { | ||||
| } | ||||
| class AutoCompleteController extends Controller {} | ||||
|   | ||||
| @@ -48,19 +48,21 @@ class BoxController extends Controller | ||||
|      * 0) If the user has available amount this period and has overspent: overspent box. | ||||
|      * 1) If the user has available amount this period and has NOT overspent: left to spend box. | ||||
|      * 2) if the user has no available amount set this period: spent per day | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function available(): JsonResponse | ||||
|     { | ||||
|         app('log')->debug('Now in available()'); | ||||
| 
 | ||||
|         /** @var OperationsRepositoryInterface $opsRepository */ | ||||
|         $opsRepository = app(OperationsRepositoryInterface::class); | ||||
| 
 | ||||
|         /** @var AvailableBudgetRepositoryInterface $abRepository */ | ||||
|         $abRepository = app(AvailableBudgetRepositoryInterface::class); | ||||
|         $abRepository->cleanup(); | ||||
| 
 | ||||
|         /** @var Carbon $start */ | ||||
|         $start = session('start', today(config('app.timezone'))->startOfMonth()); | ||||
| 
 | ||||
|         /** @var Carbon $end */ | ||||
|         $end      = session('end', today(config('app.timezone'))->endOfMonth()); | ||||
|         $today    = today(config('app.timezone')); | ||||
| @@ -92,6 +94,7 @@ class BoxController extends Controller | ||||
|                         $availableBudget->end_date->format('Y-m-d'), | ||||
|                         $availableBudget->amount | ||||
|                     )); | ||||
| 
 | ||||
|                     return $availableBudget; | ||||
|                 } | ||||
| 
 | ||||
| @@ -139,21 +142,19 @@ class BoxController extends Controller | ||||
| 
 | ||||
|         $cache->store($return); | ||||
|         app('log')->debug('Now done with available()'); | ||||
| 
 | ||||
|         return response()->json($return); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Current total balance. | ||||
|      * | ||||
|      * @param CurrencyRepositoryInterface $repository | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function balance(CurrencyRepositoryInterface $repository): JsonResponse | ||||
|     { | ||||
|         // Cache result, return cache if present.
 | ||||
|         /** @var Carbon $start */ | ||||
|         $start = session('start', today(config('app.timezone'))->startOfMonth()); | ||||
| 
 | ||||
|         /** @var Carbon $end */ | ||||
|         $end   = session('end', today(config('app.timezone'))->endOfMonth()); | ||||
|         $cache = new CacheProperties(); | ||||
| @@ -173,8 +174,10 @@ class BoxController extends Controller | ||||
|         /** @var GroupCollectorInterface $collector */ | ||||
|         $collector = app(GroupCollectorInterface::class); | ||||
|         $collector->setRange($start, $end) | ||||
|                   ->setTypes([TransactionType::DEPOSIT]); | ||||
|             ->setTypes([TransactionType::DEPOSIT]) | ||||
|         ; | ||||
|         $set = $collector->getExtractedJournals(); | ||||
| 
 | ||||
|         /** @var array $journal */ | ||||
|         foreach ($set as $journal) { | ||||
|             $currencyId           = (int)$journal['currency_id']; | ||||
| @@ -189,8 +192,10 @@ class BoxController extends Controller | ||||
|         /** @var GroupCollectorInterface $collector */ | ||||
|         $collector = app(GroupCollectorInterface::class); | ||||
|         $collector->setRange($start, $end) | ||||
|                   ->setTypes([TransactionType::WITHDRAWAL]); | ||||
|             ->setTypes([TransactionType::WITHDRAWAL]) | ||||
|         ; | ||||
|         $set = $collector->getExtractedJournals(); | ||||
| 
 | ||||
|         /** @var array $journal */ | ||||
|         foreach ($set as $journal) { | ||||
|             $currencyId            = (int)$journal['currency_id']; | ||||
| @@ -229,8 +234,6 @@ class BoxController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Total user net worth. | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function netWorth(): JsonResponse | ||||
|     { | ||||
|   | ||||
| @@ -46,8 +46,6 @@ class BudgetController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * IndexController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -67,13 +65,6 @@ class BudgetController extends Controller | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param TransactionCurrency $currency | ||||
|      * @param Carbon              $start | ||||
|      * @param Carbon              $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function getBudgetInformation(TransactionCurrency $currency, Carbon $start, Carbon $end): JsonResponse | ||||
|     { | ||||
|         $budgeted        = $this->blRepository->budgeted($start, $end, $currency); | ||||
|   | ||||
| @@ -28,7 +28,6 @@ use FireflyIII\Http\Controllers\Controller; | ||||
| use FireflyIII\Models\PiggyBank; | ||||
| use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Throwable; | ||||
| 
 | ||||
| /** | ||||
|  * Class FrontpageController. | ||||
| @@ -38,15 +37,13 @@ class FrontpageController extends Controller | ||||
|     /** | ||||
|      * Piggy bank pie chart. | ||||
|      * | ||||
|      * @param PiggyBankRepositoryInterface $repository | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function piggyBanks(PiggyBankRepositoryInterface $repository): JsonResponse | ||||
|     { | ||||
|         $set  = $repository->getPiggyBanks(); | ||||
|         $info = []; | ||||
| 
 | ||||
|         /** @var PiggyBank $piggyBank */ | ||||
|         foreach ($set as $piggyBank) { | ||||
|             $amount = $repository->getCurrentAmount($piggyBank); | ||||
| @@ -72,10 +69,11 @@ class FrontpageController extends Controller | ||||
|         if (0 !== count($info)) { | ||||
|             try { | ||||
|                 $html = view('json.piggy-banks', compact('info'))->render(); | ||||
|             } catch (Throwable $e) { | ||||
|             } catch (\Throwable $e) { | ||||
|                 app('log')->error(sprintf('Cannot render json.piggy-banks: %s', $e->getMessage())); | ||||
|                 app('log')->error($e->getTraceAsString()); | ||||
|                 $html = 'Could not render view.'; | ||||
| 
 | ||||
|                 throw new FireflyException($html, 0, $e); | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -37,11 +37,6 @@ class IntroController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Returns the introduction wizard for a page. | ||||
|      * | ||||
|      * @param string      $route | ||||
|      * @param string|null $specificPage | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function getIntroSteps(string $route, string $specificPage = null): JsonResponse | ||||
|     { | ||||
| @@ -72,10 +67,6 @@ class IntroController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Returns true if there is a general outro step. | ||||
|      * | ||||
|      * @param string $route | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function hasOutroStep(string $route): bool | ||||
|     { | ||||
| @@ -98,19 +89,15 @@ class IntroController extends Controller | ||||
|     /** | ||||
|      * Enable the boxes for a specific page again. | ||||
|      * | ||||
|      * @param string      $route | ||||
|      * @param string|null $specialPage | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function postEnable(string $route, string $specialPage = null): JsonResponse | ||||
|     { | ||||
|         $specialPage ??= ''; | ||||
|         $route       = str_replace('.', '_', $route); | ||||
|         $key         = 'shown_demo_' . $route; | ||||
|         $key         = 'shown_demo_'.$route; | ||||
|         if ('' !== $specialPage) { | ||||
|             $key .= '_' . $specialPage; | ||||
|             $key .= '_'.$specialPage; | ||||
|         } | ||||
|         app('log')->debug(sprintf('Going to mark the following route as NOT done: %s with special "%s" (%s)', $route, $specialPage, $key)); | ||||
|         app('preferences')->set($key, false); | ||||
| @@ -122,18 +109,14 @@ class IntroController extends Controller | ||||
|     /** | ||||
|      * Set that you saw them. | ||||
|      * | ||||
|      * @param string      $route | ||||
|      * @param string|null $specialPage | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function postFinished(string $route, string $specialPage = null): JsonResponse | ||||
|     { | ||||
|         $specialPage ??= ''; | ||||
|         $key         = 'shown_demo_' . $route; | ||||
|         $key         = 'shown_demo_'.$route; | ||||
|         if ('' !== $specialPage) { | ||||
|             $key .= '_' . $specialPage; | ||||
|             $key .= '_'.$specialPage; | ||||
|         } | ||||
|         app('log')->debug(sprintf('Going to mark the following route as done: %s with special "%s" (%s)', $route, $specialPage, $key)); | ||||
|         app('preferences')->set($key, true); | ||||
|   | ||||
| @@ -34,11 +34,8 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Support\Collection; | ||||
| use JsonException; | ||||
| use Throwable; | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * Class ReconcileController | ||||
|  */ | ||||
| class ReconcileController extends Controller | ||||
| @@ -47,8 +44,6 @@ class ReconcileController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * ReconcileController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -69,14 +64,8 @@ class ReconcileController extends Controller | ||||
|     /** | ||||
|      * Overview of reconciliation. | ||||
|      * | ||||
|      * @param Request      $request | ||||
|      * @param Account|null $account | ||||
|      * @param Carbon|null  $start | ||||
|      * @param Carbon|null  $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      * @throws JsonException | ||||
|      * @throws \JsonException | ||||
|      */ | ||||
|     public function overview(Request $request, Account $account = null, Carbon $start = null, Carbon $end = null): JsonResponse | ||||
|     { | ||||
| @@ -99,7 +88,7 @@ class ReconcileController extends Controller | ||||
|         $clearedJournals = []; | ||||
|         $clearedIds      = $request->get('cleared') ?? []; | ||||
|         $journals        = []; | ||||
|         /* Collect all submitted journals */ | ||||
|         // Collect all submitted journals
 | ||||
|         if (count($selectedIds) > 0) { | ||||
|             /** @var GroupCollectorInterface $collector */ | ||||
|             $collector = app(GroupCollectorInterface::class); | ||||
| @@ -107,7 +96,7 @@ class ReconcileController extends Controller | ||||
|             $journals = $collector->getExtractedJournals(); | ||||
|         } | ||||
| 
 | ||||
|         /* Collect all journals already reconciled */ | ||||
|         // Collect all journals already reconciled
 | ||||
|         if (count($clearedIds) > 0) { | ||||
|             /** @var GroupCollectorInterface $collector */ | ||||
|             $collector = app(GroupCollectorInterface::class); | ||||
| @@ -116,6 +105,7 @@ class ReconcileController extends Controller | ||||
|         } | ||||
| 
 | ||||
|         app('log')->debug('Start transaction loop'); | ||||
| 
 | ||||
|         /** @var array $journal */ | ||||
|         foreach ($journals as $journal) { | ||||
|             $amount = $this->processJournal($account, $accountCurrency, $journal, $amount); | ||||
| @@ -154,10 +144,11 @@ class ReconcileController extends Controller | ||||
|                     'selectedIds' | ||||
|                 ) | ||||
|             )->render(); | ||||
|         } catch (Throwable $e) { | ||||
|         } catch (\Throwable $e) { | ||||
|             app('log')->debug(sprintf('View error: %s', $e->getMessage())); | ||||
|             app('log')->error($e->getTraceAsString()); | ||||
|             $view = sprintf('Could not render accounts.reconcile.overview: %s', $e->getMessage()); | ||||
| 
 | ||||
|             throw new FireflyException($view, 0, $e); | ||||
|         } | ||||
| 
 | ||||
| @@ -169,56 +160,13 @@ class ReconcileController extends Controller | ||||
|         return response()->json($return); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Account             $account | ||||
|      * @param TransactionCurrency $currency | ||||
|      * @param array               $journal | ||||
|      * @param string              $amount | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     private function processJournal(Account $account, TransactionCurrency $currency, array $journal, string $amount): string | ||||
|     { | ||||
|         $toAdd = '0'; | ||||
|         app('log')->debug(sprintf('User submitted %s #%d: "%s"', $journal['transaction_type_type'], $journal['transaction_journal_id'], $journal['description'])); | ||||
| 
 | ||||
|         // not much magic below we need to cover using tests.
 | ||||
| 
 | ||||
|         if ($account->id === $journal['source_account_id']) { | ||||
|             if ($currency->id === $journal['currency_id']) { | ||||
|                 $toAdd = $journal['amount']; | ||||
|             } | ||||
|             if (null !== $journal['foreign_currency_id'] && $journal['foreign_currency_id'] === $currency->id) { | ||||
|                 $toAdd = $journal['foreign_amount']; | ||||
|             } | ||||
|         } | ||||
|         if ($account->id === $journal['destination_account_id']) { | ||||
|             if ($currency->id === $journal['currency_id']) { | ||||
|                 $toAdd = bcmul($journal['amount'], '-1'); | ||||
|             } | ||||
|             if (null !== $journal['foreign_currency_id'] && $journal['foreign_currency_id'] === $currency->id) { | ||||
|                 $toAdd = bcmul($journal['foreign_amount'], '-1'); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         app('log')->debug(sprintf('Going to add %s to %s', $toAdd, $amount)); | ||||
|         $amount = bcadd($amount, $toAdd); | ||||
|         app('log')->debug(sprintf('Result is %s', $amount)); | ||||
| 
 | ||||
|         return $amount; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Returns a list of transactions in a modal. | ||||
|      * | ||||
|      * @param Account     $account | ||||
|      * @param Carbon|null $start | ||||
|      * @param Carbon|null $end | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * @throws JsonException | ||||
|      * @throws \JsonException | ||||
|      */ | ||||
|     public function transactions(Account $account, Carbon $start = null, Carbon $end = null) | ||||
|     { | ||||
| @@ -246,8 +194,9 @@ class ReconcileController extends Controller | ||||
|         $collector = app(GroupCollectorInterface::class); | ||||
| 
 | ||||
|         $collector->setAccounts(new Collection([$account])) | ||||
|                   ->setRange($selectionStart, $selectionEnd) | ||||
|                   ->withBudgetInformation()->withCategoryInformation()->withAccountInformation(); | ||||
|             ->setRange($selectionStart, $selectionEnd) | ||||
|             ->withBudgetInformation()->withCategoryInformation()->withAccountInformation() | ||||
|         ; | ||||
|         $array    = $collector->getExtractedJournals(); | ||||
|         $journals = $this->processTransactions($account, $array); | ||||
| 
 | ||||
| @@ -256,27 +205,55 @@ class ReconcileController extends Controller | ||||
|                 'accounts.reconcile.transactions', | ||||
|                 compact('account', 'journals', 'currency', 'start', 'end', 'selectionStart', 'selectionEnd') | ||||
|             )->render(); | ||||
|         } catch (Throwable $e) { | ||||
|         } catch (\Throwable $e) { | ||||
|             app('log')->debug(sprintf('Could not render: %s', $e->getMessage())); | ||||
|             app('log')->error($e->getTraceAsString()); | ||||
|             $html = sprintf('Could not render accounts.reconcile.transactions: %s', $e->getMessage()); | ||||
| 
 | ||||
|             throw new FireflyException($html, 0, $e); | ||||
|         } | ||||
| 
 | ||||
|         return response()->json(['html' => $html, 'startBalance' => $startBalance, 'endBalance' => $endBalance]); | ||||
|     } | ||||
| 
 | ||||
|     private function processJournal(Account $account, TransactionCurrency $currency, array $journal, string $amount): string | ||||
|     { | ||||
|         $toAdd = '0'; | ||||
|         app('log')->debug(sprintf('User submitted %s #%d: "%s"', $journal['transaction_type_type'], $journal['transaction_journal_id'], $journal['description'])); | ||||
| 
 | ||||
|         // not much magic below we need to cover using tests.
 | ||||
| 
 | ||||
|         if ($account->id === $journal['source_account_id']) { | ||||
|             if ($currency->id === $journal['currency_id']) { | ||||
|                 $toAdd = $journal['amount']; | ||||
|             } | ||||
|             if (null !== $journal['foreign_currency_id'] && $journal['foreign_currency_id'] === $currency->id) { | ||||
|                 $toAdd = $journal['foreign_amount']; | ||||
|             } | ||||
|         } | ||||
|         if ($account->id === $journal['destination_account_id']) { | ||||
|             if ($currency->id === $journal['currency_id']) { | ||||
|                 $toAdd = bcmul($journal['amount'], '-1'); | ||||
|             } | ||||
|             if (null !== $journal['foreign_currency_id'] && $journal['foreign_currency_id'] === $currency->id) { | ||||
|                 $toAdd = bcmul($journal['foreign_amount'], '-1'); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         app('log')->debug(sprintf('Going to add %s to %s', $toAdd, $amount)); | ||||
|         $amount = bcadd($amount, $toAdd); | ||||
|         app('log')->debug(sprintf('Result is %s', $amount)); | ||||
| 
 | ||||
|         return $amount; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * "fix" amounts to make it easier on the reconciliation overview: | ||||
|      * | ||||
|      * @param Account $account | ||||
|      * @param array   $array | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     private function processTransactions(Account $account, array $array): array | ||||
|     { | ||||
|         $journals = []; | ||||
| 
 | ||||
|         /** @var array $journal */ | ||||
|         foreach ($array as $journal) { | ||||
|             $inverse = false; | ||||
| @@ -302,7 +279,6 @@ class ReconcileController extends Controller | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
| 
 | ||||
|             $journals[] = $journal; | ||||
|         } | ||||
| 
 | ||||
|   | ||||
| @@ -41,8 +41,6 @@ class RecurrenceController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * RecurrenceController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -61,10 +59,6 @@ class RecurrenceController extends Controller | ||||
|     /** | ||||
|      * Shows all events for a repetition. Used in calendar. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function events(Request $request): JsonResponse | ||||
| @@ -126,7 +120,7 @@ class RecurrenceController extends Controller | ||||
|         foreach ($occurrences as $current) { | ||||
|             if ($current->gte($start)) { | ||||
|                 $event    = [ | ||||
|                     'id'        => $repetitionType . $firstDate->format('Ymd'), | ||||
|                     'id'        => $repetitionType.$firstDate->format('Ymd'), | ||||
|                     'title'     => 'X', | ||||
|                     'allDay'    => true, | ||||
|                     'start'     => $current->format('Y-m-d'), | ||||
| @@ -143,15 +137,12 @@ class RecurrenceController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Suggests repetition moments. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function suggest(Request $request): JsonResponse | ||||
|     { | ||||
|         $string = '' === (string)$request->get('date') ? date('Y-m-d') : (string)$request->get('date'); | ||||
|         $today  = today(config('app.timezone'))->startOfDay(); | ||||
| 
 | ||||
|         try { | ||||
|             $date = Carbon::createFromFormat('Y-m-d', $string, config('app.timezone')); | ||||
|         } catch (InvalidFormatException $e) { | ||||
|   | ||||
| @@ -27,7 +27,6 @@ use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Http\Controllers\Controller; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Throwable; | ||||
| 
 | ||||
| /** | ||||
|  * Class RuleController | ||||
| @@ -37,9 +36,6 @@ class RuleController extends Controller | ||||
|     /** | ||||
|      * Render HTML form for rule action. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function action(Request $request): JsonResponse | ||||
| @@ -48,14 +44,16 @@ class RuleController extends Controller | ||||
|         $keys    = array_keys(config('firefly.rule-actions')); | ||||
|         $actions = []; | ||||
|         foreach ($keys as $key) { | ||||
|             $actions[$key] = (string)trans('firefly.rule_action_' . $key . '_choice'); | ||||
|             $actions[$key] = (string)trans('firefly.rule_action_'.$key.'_choice'); | ||||
|         } | ||||
| 
 | ||||
|         try { | ||||
|             $view = view('rules.partials.action', compact('actions', 'count'))->render(); | ||||
|         } catch (Throwable $e) { | ||||
|         } catch (\Throwable $e) { | ||||
|             app('log')->error(sprintf('Cannot render rules.partials.action: %s', $e->getMessage())); | ||||
|             app('log')->error($e->getTraceAsString()); | ||||
|             $view = 'Could not render view.'; | ||||
| 
 | ||||
|             throw new FireflyException($view, 0, $e); | ||||
|         } | ||||
| 
 | ||||
| @@ -65,9 +63,6 @@ class RuleController extends Controller | ||||
|     /** | ||||
|      * Render HTML for rule trigger. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function trigger(Request $request): JsonResponse | ||||
| @@ -84,10 +79,11 @@ class RuleController extends Controller | ||||
| 
 | ||||
|         try { | ||||
|             $view = view('rules.partials.trigger', compact('triggers', 'count'))->render(); | ||||
|         } catch (Throwable $e) { | ||||
|         } catch (\Throwable $e) { | ||||
|             app('log')->error(sprintf('Cannot render rules.partials.trigger: %s', $e->getMessage())); | ||||
|             app('log')->error($e->getTraceAsString()); | ||||
|             $view = 'Could not render view.'; | ||||
| 
 | ||||
|             throw new FireflyException($view, 0, $e); | ||||
|         } | ||||
| 
 | ||||
|   | ||||
| @@ -62,7 +62,7 @@ class NewUserController extends Controller | ||||
|     /** | ||||
|      * Form the user gets when he has no data in the system. | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector|Factory|View | ||||
|      * @return Factory|Redirector|RedirectResponse|View | ||||
|      */ | ||||
|     public function index() | ||||
|     { | ||||
| @@ -84,10 +84,8 @@ class NewUserController extends Controller | ||||
|     /** | ||||
|      * Store his new settings. | ||||
|      * | ||||
|      * @param NewUserFormRequest          $request | ||||
|      * @param CurrencyRepositoryInterface $currencyRepository | ||||
|      * @return Redirector|RedirectResponse | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function submit(NewUserFormRequest $request, CurrencyRepositoryInterface $currencyRepository) | ||||
|   | ||||
| @@ -40,8 +40,6 @@ class DeleteController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * PiggyBankController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -62,8 +60,6 @@ class DeleteController extends Controller | ||||
|     /** | ||||
|      * Delete a piggy bank. | ||||
|      * | ||||
|      * @param ObjectGroup $objectGroup | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function delete(ObjectGroup $objectGroup) | ||||
| @@ -79,10 +75,6 @@ class DeleteController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Destroy the piggy bank. | ||||
|      * | ||||
|      * @param ObjectGroup $objectGroup | ||||
|      * | ||||
|      * @return RedirectResponse | ||||
|      */ | ||||
|     public function destroy(ObjectGroup $objectGroup): RedirectResponse | ||||
|     { | ||||
|   | ||||
| @@ -43,8 +43,6 @@ class EditController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * PiggyBankController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -65,8 +63,6 @@ class EditController extends Controller | ||||
|     /** | ||||
|      * Edit an object group. | ||||
|      * | ||||
|      * @param ObjectGroup $objectGroup | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function edit(ObjectGroup $objectGroup) | ||||
| @@ -85,10 +81,7 @@ class EditController extends Controller | ||||
|     /** | ||||
|      * Update a piggy bank. | ||||
|      * | ||||
|      * @param ObjectGroupFormRequest $request | ||||
|      * @param ObjectGroup            $objectGroup | ||||
|      * | ||||
|      * @return Application|RedirectResponse|Redirector | ||||
|      * @return Application|Redirector|RedirectResponse | ||||
|      */ | ||||
|     public function update(ObjectGroupFormRequest $request, ObjectGroup $objectGroup) | ||||
|     { | ||||
|   | ||||
| @@ -41,8 +41,6 @@ class IndexController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * IndexController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -74,9 +72,6 @@ class IndexController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Request     $request | ||||
|      * @param ObjectGroup $objectGroup | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function setOrder(Request $request, ObjectGroup $objectGroup) | ||||
|   | ||||
| @@ -44,8 +44,6 @@ class AmountController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * PiggyBankController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -67,8 +65,6 @@ class AmountController extends Controller | ||||
|     /** | ||||
|      * Add money to piggy bank. | ||||
|      * | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function add(PiggyBank $piggyBank) | ||||
| @@ -88,8 +84,6 @@ class AmountController extends Controller | ||||
|     /** | ||||
|      * Add money to piggy bank (for mobile devices). | ||||
|      * | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function addMobile(PiggyBank $piggyBank) | ||||
| @@ -111,11 +105,6 @@ class AmountController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Add money to piggy bank. | ||||
|      * | ||||
|      * @param Request   $request | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * | ||||
|      * @return RedirectResponse | ||||
|      */ | ||||
|     public function postAdd(Request $request, PiggyBank $piggyBank): RedirectResponse | ||||
|     { | ||||
| @@ -139,7 +128,7 @@ class AmountController extends Controller | ||||
|             return redirect(route('piggy-banks.index')); | ||||
|         } | ||||
| 
 | ||||
|         app('log')->error('Cannot add ' . $amount . ' because canAddAmount returned false.'); | ||||
|         app('log')->error('Cannot add '.$amount.' because canAddAmount returned false.'); | ||||
|         session()->flash( | ||||
|             'error', | ||||
|             (string)trans( | ||||
| @@ -153,11 +142,6 @@ class AmountController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Remove money from piggy bank. | ||||
|      * | ||||
|      * @param Request   $request | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * | ||||
|      * @return RedirectResponse | ||||
|      */ | ||||
|     public function postRemove(Request $request, PiggyBank $piggyBank): RedirectResponse | ||||
|     { | ||||
| @@ -196,8 +180,6 @@ class AmountController extends Controller | ||||
|     /** | ||||
|      * Remove money from piggy bank form. | ||||
|      * | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function remove(PiggyBank $piggyBank) | ||||
| @@ -211,8 +193,6 @@ class AmountController extends Controller | ||||
|     /** | ||||
|      * Remove money from piggy bank (for mobile devices). | ||||
|      * | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function removeMobile(PiggyBank $piggyBank) | ||||
|   | ||||
| @@ -44,8 +44,6 @@ class CreateController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * PiggyBankController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -86,9 +84,8 @@ class CreateController extends Controller | ||||
|     /** | ||||
|      * Store a new piggy bank. | ||||
|      * | ||||
|      * @param PiggyBankStoreRequest $request | ||||
|      * @return Redirector|RedirectResponse | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function store(PiggyBankStoreRequest $request) | ||||
| @@ -103,7 +100,7 @@ class CreateController extends Controller | ||||
|         app('preferences')->mark(); | ||||
| 
 | ||||
|         // store attachment(s):
 | ||||
|         /** @var array|null $files */ | ||||
|         /** @var null|array $files */ | ||||
|         $files = $request->hasFile('attachments') ? $request->file('attachments') : null; | ||||
|         if (null !== $files && !auth()->user()->hasRole('demo')) { | ||||
|             $this->attachments->saveAttachmentsForModel($piggyBank, $files); | ||||
|   | ||||
| @@ -40,8 +40,6 @@ class DeleteController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * PiggyBankController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -62,8 +60,6 @@ class DeleteController extends Controller | ||||
|     /** | ||||
|      * Delete a piggy bank. | ||||
|      * | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function delete(PiggyBank $piggyBank) | ||||
| @@ -78,10 +74,6 @@ class DeleteController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Destroy the piggy bank. | ||||
|      * | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * | ||||
|      * @return RedirectResponse | ||||
|      */ | ||||
|     public function destroy(PiggyBank $piggyBank): RedirectResponse | ||||
|     { | ||||
|   | ||||
| @@ -24,7 +24,6 @@ declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Http\Controllers\PiggyBank; | ||||
| 
 | ||||
| use Amount; | ||||
| use FireflyIII\Helpers\Attachments\AttachmentHelperInterface; | ||||
| use FireflyIII\Http\Controllers\Controller; | ||||
| use FireflyIII\Http\Requests\PiggyBankUpdateRequest; | ||||
| @@ -47,8 +46,6 @@ class EditController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * PiggyBankController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -62,6 +59,7 @@ class EditController extends Controller | ||||
|                 $this->attachments       = app(AttachmentHelperInterface::class); | ||||
|                 $this->piggyRepos        = app(PiggyBankRepositoryInterface::class); | ||||
|                 $this->accountRepository = app(AccountRepositoryInterface::class); | ||||
| 
 | ||||
|                 return $next($request); | ||||
|             } | ||||
|         ); | ||||
| @@ -70,8 +68,6 @@ class EditController extends Controller | ||||
|     /** | ||||
|      * Edit a piggy bank. | ||||
|      * | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function edit(PiggyBank $piggyBank) | ||||
| @@ -113,10 +109,7 @@ class EditController extends Controller | ||||
|     /** | ||||
|      * Update a piggy bank. | ||||
|      * | ||||
|      * @param PiggyBankUpdateRequest $request | ||||
|      * @param PiggyBank              $piggyBank | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * @return Redirector|RedirectResponse | ||||
|      */ | ||||
|     public function update(PiggyBankUpdateRequest $request, PiggyBank $piggyBank) | ||||
|     { | ||||
| @@ -127,7 +120,7 @@ class EditController extends Controller | ||||
|         app('preferences')->mark(); | ||||
| 
 | ||||
|         // store new attachment(s):
 | ||||
|         /** @var array|null $files */ | ||||
|         /** @var null|array $files */ | ||||
|         $files = $request->hasFile('attachments') ? $request->file('attachments') : null; | ||||
|         if (null !== $files && !auth()->user()->hasRole('demo')) { | ||||
|             $this->attachments->saveAttachmentsForModel($piggyBank, $files); | ||||
|   | ||||
| @@ -36,7 +36,6 @@ use Illuminate\Contracts\View\Factory; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\View\View; | ||||
| use JsonException; | ||||
| use Symfony\Component\HttpFoundation\ParameterBag; | ||||
| 
 | ||||
| /** | ||||
| @@ -50,8 +49,6 @@ class IndexController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * PiggyBankController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -75,8 +72,9 @@ class IndexController extends Controller | ||||
|      * TODO very complicated function. | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * @throws JsonException | ||||
|      * @throws \JsonException | ||||
|      */ | ||||
|     public function index() | ||||
|     { | ||||
| @@ -84,6 +82,7 @@ class IndexController extends Controller | ||||
|         $this->piggyRepos->resetOrder(); | ||||
|         $collection = $this->piggyRepos->getPiggyBanks(); | ||||
|         $accounts   = []; | ||||
| 
 | ||||
|         /** @var Carbon $end */ | ||||
|         $end = session('end', today(config('app.timezone'))->endOfMonth()); | ||||
| 
 | ||||
| @@ -101,6 +100,7 @@ class IndexController extends Controller | ||||
|         /** @var AccountTransformer $accountTransformer */ | ||||
|         $accountTransformer = app(AccountTransformer::class); | ||||
|         $accountTransformer->setParameters($parameters); | ||||
| 
 | ||||
|         /** @var PiggyBank $piggy */ | ||||
|         foreach ($collection as $piggy) { | ||||
|             $array      = $transformer->transform($piggy); | ||||
| @@ -143,10 +143,23 @@ class IndexController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param array $piggyBanks | ||||
|      * | ||||
|      * @return array | ||||
|      * Set the order of a piggy bank. | ||||
|      */ | ||||
|     public function setOrder(Request $request, PiggyBank $piggyBank): JsonResponse | ||||
|     { | ||||
|         $objectGroupTitle = (string)$request->get('objectGroupTitle'); | ||||
|         $newOrder         = (int)$request->get('order'); | ||||
|         $this->piggyRepos->setOrder($piggyBank, $newOrder); | ||||
|         if ('' !== $objectGroupTitle) { | ||||
|             $this->piggyRepos->setObjectGroup($piggyBank, $objectGroupTitle); | ||||
|         } | ||||
|         if ('' === $objectGroupTitle) { | ||||
|             $this->piggyRepos->removeObjectGroup($piggyBank); | ||||
|         } | ||||
| 
 | ||||
|         return response()->json(['data' => 'OK']); | ||||
|     } | ||||
| 
 | ||||
|     private function makeSums(array $piggyBanks): array | ||||
|     { | ||||
|         $sums = []; | ||||
| @@ -181,27 +194,4 @@ class IndexController extends Controller | ||||
| 
 | ||||
|         return $piggyBanks; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Set the order of a piggy bank. | ||||
|      * | ||||
|      * @param Request   $request | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function setOrder(Request $request, PiggyBank $piggyBank): JsonResponse | ||||
|     { | ||||
|         $objectGroupTitle = (string)$request->get('objectGroupTitle'); | ||||
|         $newOrder         = (int)$request->get('order'); | ||||
|         $this->piggyRepos->setOrder($piggyBank, $newOrder); | ||||
|         if ('' !== $objectGroupTitle) { | ||||
|             $this->piggyRepos->setObjectGroup($piggyBank, $objectGroupTitle); | ||||
|         } | ||||
|         if ('' === $objectGroupTitle) { | ||||
|             $this->piggyRepos->removeObjectGroup($piggyBank); | ||||
|         } | ||||
| 
 | ||||
|         return response()->json(['data' => 'OK']); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -32,7 +32,6 @@ use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; | ||||
| use FireflyIII\Transformers\PiggyBankTransformer; | ||||
| use Illuminate\Contracts\View\Factory; | ||||
| use Illuminate\View\View; | ||||
| use JsonException; | ||||
| use Symfony\Component\HttpFoundation\ParameterBag; | ||||
| 
 | ||||
| /** | ||||
| @@ -44,8 +43,6 @@ class ShowController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * PiggyBankController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -66,11 +63,10 @@ class ShowController extends Controller | ||||
|     /** | ||||
|      * Show a single piggy bank. | ||||
|      * | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * @throws JsonException | ||||
|      * @throws \JsonException | ||||
|      */ | ||||
|     public function show(PiggyBank $piggyBank) | ||||
|     { | ||||
|   | ||||
| @@ -31,7 +31,6 @@ use Illuminate\Http\Request; | ||||
| 
 | ||||
| /** | ||||
|  * Class ReportController. | ||||
|  * | ||||
|  */ | ||||
| class ReportController extends Controller | ||||
| { | ||||
| @@ -40,9 +39,6 @@ class ReportController extends Controller | ||||
|     /** | ||||
|      * Generate popup view. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function general(Request $request): JsonResponse | ||||
| @@ -61,6 +57,7 @@ class ReportController extends Controller | ||||
|             'category-entry'      => $this->categoryEntry($attributes), | ||||
|             'budget-entry'        => $this->budgetEntry($attributes), | ||||
|         }; | ||||
| 
 | ||||
|         return response()->json(['html' => $html]); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -34,7 +34,6 @@ use Illuminate\Http\RedirectResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Routing\Redirector; | ||||
| use Illuminate\View\View; | ||||
| use JsonException; | ||||
| use Psr\Container\ContainerExceptionInterface; | ||||
| use Psr\Container\NotFoundExceptionInterface; | ||||
| 
 | ||||
| @@ -45,8 +44,6 @@ class PreferencesController extends Controller | ||||
| { | ||||
|     /** | ||||
|      * PreferencesController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -65,9 +62,8 @@ class PreferencesController extends Controller | ||||
|     /** | ||||
|      * Show overview of preferences. | ||||
|      * | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
| @@ -79,6 +75,7 @@ class PreferencesController extends Controller | ||||
| 
 | ||||
|         // group accounts
 | ||||
|         $groupedAccounts = []; | ||||
| 
 | ||||
|         /** @var Account $account */ | ||||
|         foreach ($accounts as $account) { | ||||
|             $type = $account->accountType->type; | ||||
| @@ -130,7 +127,7 @@ class PreferencesController extends Controller | ||||
| 
 | ||||
|         try { | ||||
|             $locales = json_decode((string)file_get_contents(resource_path(sprintf('lang/%s/locales.json', $language))), true, 512, JSON_THROW_ON_ERROR); | ||||
|         } catch (JsonException $e) { | ||||
|         } catch (\JsonException $e) { | ||||
|             app('log')->error($e->getMessage()); | ||||
|             $locales = []; | ||||
|         } | ||||
| @@ -174,9 +171,8 @@ class PreferencesController extends Controller | ||||
|     /** | ||||
|      * Store new preferences. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * @return Redirector|RedirectResponse | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * @throws FireflyException | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
| @@ -211,7 +207,6 @@ class PreferencesController extends Controller | ||||
|         session()->forget('end'); | ||||
|         session()->forget('range'); | ||||
| 
 | ||||
| 
 | ||||
|         // slack URL:
 | ||||
|         if (!auth()->user()->hasRole('demo')) { | ||||
|             $url = (string)$request->get('slackUrl'); | ||||
| @@ -232,7 +227,6 @@ class PreferencesController extends Controller | ||||
|             app('preferences')->set('fiscalYearStart', $fiscalYearStart); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         // save page size:
 | ||||
|         app('preferences')->set('listPageSize', 50); | ||||
|         $listPageSize = (int)$request->get('listPageSize'); | ||||
|   | ||||
| @@ -24,8 +24,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Http\Controllers; | ||||
| 
 | ||||
| use Auth; | ||||
| use DB; | ||||
| use Exception; | ||||
| use FireflyIII\Events\UserChangedEmail; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Exceptions\ValidationException; | ||||
| @@ -38,8 +36,6 @@ use FireflyIII\Models\Preference; | ||||
| use FireflyIII\Repositories\User\UserRepositoryInterface; | ||||
| use FireflyIII\Support\Http\Controllers\CreateStuff; | ||||
| use FireflyIII\User; | ||||
| use Google2FA; | ||||
| use Hash; | ||||
| use Illuminate\Auth\AuthenticationException; | ||||
| use Illuminate\Contracts\Auth\Guard; | ||||
| use Illuminate\Contracts\Foundation\Application; | ||||
| @@ -61,7 +57,6 @@ use Psr\Container\NotFoundExceptionInterface; | ||||
|  * Class ProfileController. | ||||
|  * | ||||
|  * @method Guard guard() | ||||
|  * | ||||
|  */ | ||||
| class ProfileController extends Controller | ||||
| { | ||||
| @@ -71,8 +66,6 @@ class ProfileController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * ProfileController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -96,16 +89,13 @@ class ProfileController extends Controller | ||||
|     /** | ||||
|      * View that generates a 2FA code for the user. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return Factory|View|RedirectResponse | ||||
|      * @throws IncompatibleWithGoogleAuthenticatorException | ||||
|      * @throws InvalidCharactersException | ||||
|      * @throws SecretKeyTooShortException | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
|      */ | ||||
|     public function code(Request $request): Factory | View | RedirectResponse | ||||
|     public function code(Request $request): Factory|RedirectResponse|View | ||||
|     { | ||||
|         if (!$this->internalAuth) { | ||||
|             $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); | ||||
| @@ -119,7 +109,7 @@ class ProfileController extends Controller | ||||
|         // generate secret if not in session
 | ||||
|         if (null === $secretPreference) { | ||||
|             // generate secret + store + flash
 | ||||
|             $secret = Google2FA::generateSecretKey(); | ||||
|             $secret = \Google2FA::generateSecretKey(); | ||||
|             app('preferences')->set('temp-mfa-secret', $secret); | ||||
|         } | ||||
| 
 | ||||
| @@ -152,7 +142,7 @@ class ProfileController extends Controller | ||||
| 
 | ||||
|         $codes = implode("\r\n", $recoveryCodes); | ||||
| 
 | ||||
|         $image = Google2FA::getQRCodeInline($domain, auth()->user()->email, (string)$secret); | ||||
|         $image = \Google2FA::getQRCodeInline($domain, auth()->user()->email, (string)$secret); | ||||
| 
 | ||||
|         return view('profile.code', compact('image', 'secret', 'codes')); | ||||
|     } | ||||
| @@ -160,22 +150,19 @@ class ProfileController extends Controller | ||||
|     /** | ||||
|      * Screen to confirm email change. | ||||
|      * | ||||
|      * @param UserRepositoryInterface $repository | ||||
|      * @param string                  $token | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function confirmEmailChange(UserRepositoryInterface $repository, string $token): RedirectResponse | Redirector | ||||
|     public function confirmEmailChange(UserRepositoryInterface $repository, string $token): Redirector|RedirectResponse | ||||
|     { | ||||
|         if (!$this->internalAuth) { | ||||
|             throw new FireflyException(trans('firefly.external_user_mgt_disabled')); | ||||
|         } | ||||
| 
 | ||||
|         // find preference with this token value.
 | ||||
|         /** @var Collection $set */ | ||||
|         $set  = app('preferences')->findByName('email_change_confirm_token'); | ||||
|         $user = null; | ||||
| 
 | ||||
|         /** @var Preference $preference */ | ||||
|         foreach ($set as $preference) { | ||||
|             if ($preference->data === $token) { | ||||
| @@ -196,12 +183,8 @@ class ProfileController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Delete your account view. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return View|RedirectResponse | ||||
|      */ | ||||
|     public function deleteAccount(Request $request): View | RedirectResponse | ||||
|     public function deleteAccount(Request $request): RedirectResponse|View | ||||
|     { | ||||
|         if (!$this->internalAuth) { | ||||
|             $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); | ||||
| @@ -217,15 +200,15 @@ class ProfileController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Delete 2FA routine. | ||||
|      * | ||||
|      */ | ||||
|     public function deleteCode(Request $request): RedirectResponse | Redirector | ||||
|     public function deleteCode(Request $request): Redirector|RedirectResponse | ||||
|     { | ||||
|         if (!$this->internalAuth) { | ||||
|             $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); | ||||
| 
 | ||||
|             return redirect(route('profile.index')); | ||||
|         } | ||||
| 
 | ||||
|         /** @var UserRepositoryInterface $repository */ | ||||
|         $repository = app(UserRepositoryInterface::class); | ||||
| 
 | ||||
| @@ -245,9 +228,8 @@ class ProfileController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Enable 2FA screen. | ||||
|      * | ||||
|      */ | ||||
|     public function enable2FA(Request $request): RedirectResponse | Redirector | ||||
|     public function enable2FA(Request $request): Redirector|RedirectResponse | ||||
|     { | ||||
|         if (!$this->internalAuth) { | ||||
|             $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); | ||||
| @@ -274,17 +256,16 @@ class ProfileController extends Controller | ||||
|     /** | ||||
|      * Index for profile. | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * @throws FireflyException | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
|      */ | ||||
|     public function index(): Factory | View | ||||
|     public function index(): Factory|View | ||||
|     { | ||||
|         /** @var User $user */ | ||||
|         $user           = auth()->user(); | ||||
|         $isInternalAuth = $this->internalAuth; | ||||
|         $count          = DB::table('oauth_clients')->where('personal_access_client', true)->whereNull('user_id')->count(); | ||||
|         $count          = \DB::table('oauth_clients')->where('personal_access_client', true)->whereNull('user_id')->count(); | ||||
|         $subTitle       = $user->email; | ||||
|         $userId         = $user->id; | ||||
|         $enabled2FA     = null !== $user->mfa_secret; | ||||
| @@ -298,7 +279,7 @@ class ProfileController extends Controller | ||||
|         if (0 === $count) { | ||||
|             /** @var ClientRepository $repository */ | ||||
|             $repository = app(ClientRepository::class); | ||||
|             $repository->createPersonalAccessClient(null, config('app.name') . ' Personal Access Client', 'http://localhost'); | ||||
|             $repository->createPersonalAccessClient(null, config('app.name').' Personal Access Client', 'http://localhost'); | ||||
|         } | ||||
| 
 | ||||
|         $accessToken = app('preferences')->get('access_token'); | ||||
| @@ -313,10 +294,7 @@ class ProfileController extends Controller | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @return Factory|View|RedirectResponse | ||||
|      */ | ||||
|     public function logoutOtherSessions(): Factory | View | RedirectResponse | ||||
|     public function logoutOtherSessions(): Factory|RedirectResponse|View | ||||
|     { | ||||
|         if (!$this->internalAuth) { | ||||
|             session()->flash('info', (string)trans('firefly.external_auth_disabled')); | ||||
| @@ -328,12 +306,9 @@ class ProfileController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return Factory|View|RedirectResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function newBackupCodes(Request $request): Factory | View | RedirectResponse | ||||
|     public function newBackupCodes(Request $request): Factory|RedirectResponse|View | ||||
|     { | ||||
|         if (!$this->internalAuth) { | ||||
|             $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); | ||||
| @@ -344,10 +319,11 @@ class ProfileController extends Controller | ||||
|         // generate recovery codes:
 | ||||
|         $recovery      = app(Recovery::class); | ||||
|         $recoveryCodes = $recovery->lowercase() | ||||
|                                   ->setCount(8)     // Generate 8 codes
 | ||||
|                                   ->setBlocks(2)    // Every code must have 7 blocks
 | ||||
|                                   ->setChars(6)     // Each block must have 16 chars
 | ||||
|                                   ->toArray(); | ||||
|             ->setCount(8)     // Generate 8 codes
 | ||||
|             ->setBlocks(2)    // Every code must have 7 blocks
 | ||||
|             ->setChars(6)     // Each block must have 16 chars
 | ||||
|             ->toArray() | ||||
|         ; | ||||
|         $codes         = implode("\r\n", $recoveryCodes); | ||||
| 
 | ||||
|         app('preferences')->set('mfa_recovery', $recoveryCodes); | ||||
| @@ -358,13 +334,8 @@ class ProfileController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Submit the change email form. | ||||
|      * | ||||
|      * @param EmailFormRequest        $request | ||||
|      * @param UserRepositoryInterface $repository | ||||
|      * | ||||
|      * @return Factory|RedirectResponse|Redirector | ||||
|      */ | ||||
|     public function postChangeEmail(EmailFormRequest $request, UserRepositoryInterface $repository): Factory | RedirectResponse | Redirector | ||||
|     public function postChangeEmail(EmailFormRequest $request, UserRepositoryInterface $repository): Factory|Redirector|RedirectResponse | ||||
|     { | ||||
|         if (!$this->internalAuth) { | ||||
|             $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); | ||||
| @@ -384,7 +355,7 @@ class ProfileController extends Controller | ||||
|         $existing = $repository->findByEmail($newEmail); | ||||
|         if (null !== $existing) { | ||||
|             // force user logout.
 | ||||
|             Auth::guard()->logout(); // @phpstan-ignore-line (does not recognize function)
 | ||||
|             \Auth::guard()->logout(); // @phpstan-ignore-line (does not recognize function)
 | ||||
|             $request->session()->invalidate(); | ||||
| 
 | ||||
|             session()->flash('success', (string)trans('firefly.email_changed')); | ||||
| @@ -398,7 +369,7 @@ class ProfileController extends Controller | ||||
|         event(new UserChangedEmail($user, $newEmail, $oldEmail)); | ||||
| 
 | ||||
|         // force user logout.
 | ||||
|         Auth::guard()->logout(); // @phpstan-ignore-line (does not recognize function)
 | ||||
|         \Auth::guard()->logout(); // @phpstan-ignore-line (does not recognize function)
 | ||||
|         $request->session()->invalidate(); | ||||
|         session()->flash('success', (string)trans('firefly.email_changed')); | ||||
| 
 | ||||
| @@ -407,12 +378,8 @@ class ProfileController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Change your email address. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return Factory|RedirectResponse|View | ||||
|      */ | ||||
|     public function changeEmail(Request $request): Factory | RedirectResponse | View | ||||
|     public function changeEmail(Request $request): Factory|RedirectResponse|View | ||||
|     { | ||||
|         if (!$this->internalAuth) { | ||||
|             $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); | ||||
| @@ -431,10 +398,7 @@ class ProfileController extends Controller | ||||
|     /** | ||||
|      * Submit change password form. | ||||
|      * | ||||
|      * @param ProfileFormRequest      $request | ||||
|      * @param UserRepositoryInterface $repository | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * @return Redirector|RedirectResponse | ||||
|      */ | ||||
|     public function postChangePassword(ProfileFormRequest $request, UserRepositoryInterface $repository) | ||||
|     { | ||||
| @@ -447,8 +411,10 @@ class ProfileController extends Controller | ||||
|         // the request has already validated both new passwords must be equal.
 | ||||
|         $current = $request->get('current_password'); | ||||
|         $new     = $request->get('new_password'); | ||||
| 
 | ||||
|         /** @var User $user */ | ||||
|         $user = auth()->user(); | ||||
| 
 | ||||
|         try { | ||||
|             $this->validatePassword($user, $current, $new); | ||||
|         } catch (ValidationException $e) { | ||||
| @@ -466,9 +432,7 @@ class ProfileController extends Controller | ||||
|     /** | ||||
|      * Change your password. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return Factory|RedirectResponse|Redirector|View | ||||
|      * @return Factory|Redirector|RedirectResponse|View | ||||
|      */ | ||||
|     public function changePassword(Request $request) | ||||
|     { | ||||
| @@ -488,9 +452,8 @@ class ProfileController extends Controller | ||||
|     /** | ||||
|      * Submit 2FA for the first time. | ||||
|      * | ||||
|      * @param TokenFormRequest $request | ||||
|      * @return Redirector|RedirectResponse | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * @throws FireflyException | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
| @@ -505,6 +468,7 @@ class ProfileController extends Controller | ||||
| 
 | ||||
|         /** @var User $user */ | ||||
|         $user = auth()->user(); | ||||
| 
 | ||||
|         /** @var UserRepositoryInterface $repository */ | ||||
|         $repository = app(UserRepositoryInterface::class); | ||||
|         $secret     = app('preferences')->get('temp-mfa-secret')?->data; | ||||
| @@ -532,7 +496,7 @@ class ProfileController extends Controller | ||||
| 
 | ||||
|         // make sure MFA is logged out.
 | ||||
|         if ('testing' !== config('app.env')) { | ||||
|             Google2FA::logout(); | ||||
|             \Google2FA::logout(); | ||||
|         } | ||||
| 
 | ||||
|         // drop all info from session:
 | ||||
| @@ -542,9 +506,142 @@ class ProfileController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * TODO duplicate code. | ||||
|      * Submit delete account. | ||||
|      * | ||||
|      * @param string $mfaCode | ||||
|      * @return Redirector|RedirectResponse | ||||
|      */ | ||||
|     public function postDeleteAccount(UserRepositoryInterface $repository, DeleteAccountFormRequest $request) | ||||
|     { | ||||
|         if (!$this->internalAuth) { | ||||
|             $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); | ||||
| 
 | ||||
|             return redirect(route('profile.index')); | ||||
|         } | ||||
| 
 | ||||
|         if (!\Hash::check($request->get('password'), auth()->user()->password)) { | ||||
|             session()->flash('error', (string)trans('firefly.invalid_password')); | ||||
| 
 | ||||
|             return redirect(route('profile.delete-account')); | ||||
|         } | ||||
| 
 | ||||
|         /** @var User $user */ | ||||
|         $user = auth()->user(); | ||||
|         app('log')->info(sprintf('User #%d has opted to delete their account', auth()->user()->id)); | ||||
|         // make repository delete user:
 | ||||
|         auth()->logout(); | ||||
|         session()->flush(); | ||||
|         $repository->destroy($user); | ||||
| 
 | ||||
|         return redirect(route('index')); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @return Application|Redirector|RedirectResponse | ||||
|      * | ||||
|      * @throws AuthenticationException | ||||
|      */ | ||||
|     public function postLogoutOtherSessions(Request $request) | ||||
|     { | ||||
|         if (!$this->internalAuth) { | ||||
|             session()->flash('info', (string)trans('firefly.external_auth_disabled')); | ||||
| 
 | ||||
|             return redirect(route('profile.index')); | ||||
|         } | ||||
|         $creds = [ | ||||
|             'email'    => auth()->user()->email, | ||||
|             'password' => $request->get('password'), | ||||
|         ]; | ||||
|         if (\Auth::once($creds)) { | ||||
|             \Auth::logoutOtherDevices($request->get('password')); | ||||
|             session()->flash('info', (string)trans('firefly.other_sessions_logged_out')); | ||||
| 
 | ||||
|             return redirect(route('profile.index')); | ||||
|         } | ||||
|         session()->flash('error', (string)trans('auth.failed')); | ||||
| 
 | ||||
|         return redirect(route('profile.index')); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Regenerate access token. | ||||
|      * | ||||
|      * @return Redirector|RedirectResponse | ||||
|      * | ||||
|      * @throws \Exception | ||||
|      */ | ||||
|     public function regenerate(Request $request) | ||||
|     { | ||||
|         if (!$this->internalAuth) { | ||||
|             $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); | ||||
| 
 | ||||
|             return redirect(route('profile.index')); | ||||
|         } | ||||
| 
 | ||||
|         /** @var User $user */ | ||||
|         $user  = auth()->user(); | ||||
|         $token = $user->generateAccessToken(); | ||||
|         app('preferences')->set('access_token', $token); | ||||
|         session()->flash('success', (string)trans('firefly.token_regenerated')); | ||||
| 
 | ||||
|         return redirect(route('profile.index')); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Undo change of user email address. | ||||
|      * | ||||
|      * @return Redirector|RedirectResponse | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function undoEmailChange(UserRepositoryInterface $repository, string $token, string $hash) | ||||
|     { | ||||
|         if (!$this->internalAuth) { | ||||
|             throw new FireflyException(trans('firefly.external_user_mgt_disabled')); | ||||
|         } | ||||
| 
 | ||||
|         // find preference with this token value.
 | ||||
|         $set  = app('preferences')->findByName('email_change_undo_token'); | ||||
|         $user = null; | ||||
| 
 | ||||
|         /** @var Preference $preference */ | ||||
|         foreach ($set as $preference) { | ||||
|             if ($preference->data === $token) { | ||||
|                 $user = $preference->user; | ||||
|             } | ||||
|         } | ||||
|         if (null === $user) { | ||||
|             throw new FireflyException('Invalid token.'); | ||||
|         } | ||||
| 
 | ||||
|         // found user.which email address to return to?
 | ||||
|         $set = app('preferences')->beginsWith($user, 'previous_email_'); | ||||
| 
 | ||||
|         /** @var string $match */ | ||||
|         $match = null; | ||||
|         foreach ($set as $entry) { | ||||
|             $hashed = hash('sha256', sprintf('%s%s', (string)config('app.key'), $entry->data)); | ||||
|             if ($hashed === $hash) { | ||||
|                 $match = $entry->data; | ||||
| 
 | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|         if (null === $match) { | ||||
|             throw new FireflyException('Invalid token.'); | ||||
|         } | ||||
|         // change user back
 | ||||
|         // now actually update user:
 | ||||
|         $repository->changeEmail($user, $match); | ||||
|         $repository->unblockUser($user); | ||||
| 
 | ||||
|         // return to login.
 | ||||
|         session()->flash('success', (string)trans('firefly.login_with_old_email')); | ||||
| 
 | ||||
|         return redirect(route('login')); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * TODO duplicate code. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * @throws ContainerExceptionInterface | ||||
| @@ -585,144 +682,4 @@ class ProfileController extends Controller | ||||
|         } | ||||
|         app('preferences')->set('mfa_history', $newHistory); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Submit delete account. | ||||
|      * | ||||
|      * @param UserRepositoryInterface  $repository | ||||
|      * @param DeleteAccountFormRequest $request | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      */ | ||||
|     public function postDeleteAccount(UserRepositoryInterface $repository, DeleteAccountFormRequest $request) | ||||
|     { | ||||
|         if (!$this->internalAuth) { | ||||
|             $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); | ||||
| 
 | ||||
|             return redirect(route('profile.index')); | ||||
|         } | ||||
| 
 | ||||
|         if (!Hash::check($request->get('password'), auth()->user()->password)) { | ||||
|             session()->flash('error', (string)trans('firefly.invalid_password')); | ||||
| 
 | ||||
|             return redirect(route('profile.delete-account')); | ||||
|         } | ||||
|         /** @var User $user */ | ||||
|         $user = auth()->user(); | ||||
|         app('log')->info(sprintf('User #%d has opted to delete their account', auth()->user()->id)); | ||||
|         // make repository delete user:
 | ||||
|         auth()->logout(); | ||||
|         session()->flush(); | ||||
|         $repository->destroy($user); | ||||
| 
 | ||||
|         return redirect(route('index')); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return Application|RedirectResponse|Redirector | ||||
|      * @throws AuthenticationException | ||||
|      */ | ||||
|     public function postLogoutOtherSessions(Request $request) | ||||
|     { | ||||
|         if (!$this->internalAuth) { | ||||
|             session()->flash('info', (string)trans('firefly.external_auth_disabled')); | ||||
| 
 | ||||
|             return redirect(route('profile.index')); | ||||
|         } | ||||
|         $creds = [ | ||||
|             'email'    => auth()->user()->email, | ||||
|             'password' => $request->get('password'), | ||||
|         ]; | ||||
|         if (Auth::once($creds)) { | ||||
|             Auth::logoutOtherDevices($request->get('password')); | ||||
|             session()->flash('info', (string)trans('firefly.other_sessions_logged_out')); | ||||
| 
 | ||||
|             return redirect(route('profile.index')); | ||||
|         } | ||||
|         session()->flash('error', (string)trans('auth.failed')); | ||||
| 
 | ||||
|         return redirect(route('profile.index')); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Regenerate access token. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * @throws Exception | ||||
|      */ | ||||
|     public function regenerate(Request $request) | ||||
|     { | ||||
|         if (!$this->internalAuth) { | ||||
|             $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); | ||||
| 
 | ||||
|             return redirect(route('profile.index')); | ||||
|         } | ||||
| 
 | ||||
|         /** @var User $user */ | ||||
|         $user  = auth()->user(); | ||||
|         $token = $user->generateAccessToken(); | ||||
|         app('preferences')->set('access_token', $token); | ||||
|         session()->flash('success', (string)trans('firefly.token_regenerated')); | ||||
| 
 | ||||
|         return redirect(route('profile.index')); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Undo change of user email address. | ||||
|      * | ||||
|      * @param UserRepositoryInterface $repository | ||||
|      * @param string                  $token | ||||
|      * @param string                  $hash | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function undoEmailChange(UserRepositoryInterface $repository, string $token, string $hash) | ||||
|     { | ||||
|         if (!$this->internalAuth) { | ||||
|             throw new FireflyException(trans('firefly.external_user_mgt_disabled')); | ||||
|         } | ||||
| 
 | ||||
|         // find preference with this token value.
 | ||||
|         $set  = app('preferences')->findByName('email_change_undo_token'); | ||||
|         $user = null; | ||||
|         /** @var Preference $preference */ | ||||
|         foreach ($set as $preference) { | ||||
|             if ($preference->data === $token) { | ||||
|                 $user = $preference->user; | ||||
|             } | ||||
|         } | ||||
|         if (null === $user) { | ||||
|             throw new FireflyException('Invalid token.'); | ||||
|         } | ||||
| 
 | ||||
|         // found user.which email address to return to?
 | ||||
|         $set = app('preferences')->beginsWith($user, 'previous_email_'); | ||||
|         /** @var string $match */ | ||||
|         $match = null; | ||||
|         foreach ($set as $entry) { | ||||
|             $hashed = hash('sha256', sprintf('%s%s', (string)config('app.key'), $entry->data)); | ||||
|             if ($hashed === $hash) { | ||||
|                 $match = $entry->data; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|         if (null === $match) { | ||||
|             throw new FireflyException('Invalid token.'); | ||||
|         } | ||||
|         // change user back
 | ||||
|         // now actually update user:
 | ||||
|         $repository->changeEmail($user, $match); | ||||
|         $repository->unblockUser($user); | ||||
| 
 | ||||
|         // return to login.
 | ||||
|         session()->flash('success', (string)trans('firefly.login_with_old_email')); | ||||
| 
 | ||||
|         return redirect(route('login')); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -40,7 +40,6 @@ use Illuminate\Routing\Redirector; | ||||
| use Illuminate\View\View; | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * Class CreateController | ||||
|  */ | ||||
| class CreateController extends Controller | ||||
| @@ -52,8 +51,6 @@ class CreateController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * CreateController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -79,8 +76,6 @@ class CreateController extends Controller | ||||
|     /** | ||||
|      * Create a new recurring transaction. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function create(Request $request) | ||||
| @@ -124,9 +119,6 @@ class CreateController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Request            $request | ||||
|      * @param TransactionJournal $journal | ||||
|      * | ||||
|      * @return Factory|\Illuminate\Contracts\View\View | ||||
|      */ | ||||
|     public function createFromJournal(Request $request, TransactionJournal $journal) | ||||
| @@ -155,12 +147,12 @@ class CreateController extends Controller | ||||
|             RecurrenceRepetition::WEEKEND_TO_MONDAY     => (string)trans('firefly.jump_to_monday'), | ||||
|         ]; | ||||
| 
 | ||||
| 
 | ||||
|         // fill prefilled with journal info
 | ||||
|         $type = strtolower($journal->transactionType->type); | ||||
| 
 | ||||
|         /** @var Transaction $source */ | ||||
|         $source = $journal->transactions()->where('amount', '<', 0)->first(); | ||||
| 
 | ||||
|         /** @var Transaction $dest */ | ||||
|         $dest        = $journal->transactions()->where('amount', '>', 0)->first(); | ||||
|         $category    = null !== $journal->categories()->first() ? $journal->categories()->first()->name : ''; | ||||
| @@ -221,14 +213,14 @@ class CreateController extends Controller | ||||
|     /** | ||||
|      * Store a recurring transaction. | ||||
|      * | ||||
|      * @param RecurrenceFormRequest $request | ||||
|      * @return Redirector|RedirectResponse | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function store(RecurrenceFormRequest $request) | ||||
|     { | ||||
|         $data = $request->getAll(); | ||||
| 
 | ||||
|         try { | ||||
|             $recurrence = $this->recurring->store($data); | ||||
|         } catch (FireflyException $e) { | ||||
| @@ -241,7 +233,7 @@ class CreateController extends Controller | ||||
|         app('preferences')->mark(); | ||||
| 
 | ||||
|         // store attachment(s):
 | ||||
|         /** @var array|null $files */ | ||||
|         /** @var null|array $files */ | ||||
|         $files = $request->hasFile('attachments') ? $request->file('attachments') : null; | ||||
|         if (null !== $files && !auth()->user()->hasRole('demo')) { | ||||
|             $this->attachments->saveAttachmentsForModel($recurrence, $files); | ||||
|   | ||||
| @@ -42,8 +42,6 @@ class DeleteController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * DeleteController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -65,8 +63,6 @@ class DeleteController extends Controller | ||||
|     /** | ||||
|      * Delete a recurring transaction form. | ||||
|      * | ||||
|      * @param Recurrence $recurrence | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function delete(Recurrence $recurrence) | ||||
| @@ -83,16 +79,12 @@ class DeleteController extends Controller | ||||
|     /** | ||||
|      * Destroy the recurring transaction. | ||||
|      * | ||||
|      * @param RecurringRepositoryInterface $repository | ||||
|      * @param Request                      $request | ||||
|      * @param Recurrence                   $recurrence | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * @return Redirector|RedirectResponse | ||||
|      */ | ||||
|     public function destroy(RecurringRepositoryInterface $repository, Request $request, Recurrence $recurrence) | ||||
|     { | ||||
|         $repository->destroy($recurrence); | ||||
|         $request->session()->flash('success', (string)trans('firefly.' . 'recurrence_deleted', ['title' => $recurrence->title])); | ||||
|         $request->session()->flash('success', (string)trans('firefly.recurrence_deleted', ['title' => $recurrence->title])); | ||||
|         app('preferences')->mark(); | ||||
| 
 | ||||
|         return redirect($this->getPreviousUrl('recurrences.delete.url')); | ||||
|   | ||||
| @@ -41,7 +41,6 @@ use Illuminate\View\View; | ||||
| use Symfony\Component\HttpFoundation\ParameterBag; | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * Class EditController | ||||
|  */ | ||||
| class EditController extends Controller | ||||
| @@ -53,8 +52,6 @@ class EditController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * EditController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -80,12 +77,9 @@ class EditController extends Controller | ||||
|     /** | ||||
|      * Edit a recurring transaction. | ||||
|      * | ||||
|      * @param Request    $request | ||||
|      * @param Recurrence $recurrence | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * @throws FireflyException | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function edit(Request $request, Recurrence $recurrence) | ||||
|     { | ||||
| @@ -107,7 +101,7 @@ class EditController extends Controller | ||||
|         $repetition     = $recurrence->recurrenceRepetitions()->first(); | ||||
|         $currentRepType = $repetition->repetition_type; | ||||
|         if ('' !== $repetition->repetition_moment) { | ||||
|             $currentRepType .= ',' . $repetition->repetition_moment; | ||||
|             $currentRepType .= ','.$repetition->repetition_moment; | ||||
|         } | ||||
| 
 | ||||
|         // put previous url in session if not redirect from store (not "return_to_edit").
 | ||||
| @@ -167,10 +161,8 @@ class EditController extends Controller | ||||
|     /** | ||||
|      * Update the recurring transaction. | ||||
|      * | ||||
|      * @param RecurrenceFormRequest $request | ||||
|      * @param Recurrence            $recurrence | ||||
|      * @return Redirector|RedirectResponse | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function update(RecurrenceFormRequest $request, Recurrence $recurrence) | ||||
| @@ -181,7 +173,7 @@ class EditController extends Controller | ||||
|         $request->session()->flash('success', (string)trans('firefly.updated_recurrence', ['title' => $recurrence->title])); | ||||
| 
 | ||||
|         // store new attachment(s):
 | ||||
|         /** @var array|null $files */ | ||||
|         /** @var null|array $files */ | ||||
|         $files = $request->hasFile('attachments') ? $request->file('attachments') : null; | ||||
|         if (null !== $files && !auth()->user()->hasRole('demo')) { | ||||
|             $this->attachments->saveAttachmentsForModel($recurrence, $files); | ||||
|   | ||||
| @@ -39,7 +39,6 @@ use Psr\Container\NotFoundExceptionInterface; | ||||
| use Symfony\Component\HttpFoundation\ParameterBag; | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * Class IndexController | ||||
|  */ | ||||
| class IndexController extends Controller | ||||
| @@ -50,8 +49,6 @@ class IndexController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * IndexController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -74,9 +71,8 @@ class IndexController extends Controller | ||||
|      * TODO the notes of a recurrence are pretty pointless at this moment. | ||||
|      * Show all recurring transactions. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
| @@ -98,6 +94,7 @@ class IndexController extends Controller | ||||
|         $transformer->setParameters(new ParameterBag()); | ||||
| 
 | ||||
|         $recurring = []; | ||||
| 
 | ||||
|         /** @var Recurrence $recurrence */ | ||||
|         foreach ($recurrences as $recurrence) { | ||||
|             $year->addYear(); | ||||
|   | ||||
| @@ -38,7 +38,6 @@ use Illuminate\View\View; | ||||
| use Symfony\Component\HttpFoundation\ParameterBag; | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * Class ShowController | ||||
|  */ | ||||
| class ShowController extends Controller | ||||
| @@ -50,8 +49,6 @@ class ShowController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * IndexController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -74,14 +71,14 @@ class ShowController extends Controller | ||||
|     /** | ||||
|      * Show a single recurring transaction. | ||||
|      * | ||||
|      * @param Recurrence $recurrence | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function show(Recurrence $recurrence) | ||||
|     { | ||||
|         $repos = app(AttachmentRepositoryInterface::class); | ||||
| 
 | ||||
|         /** @var RecurrenceTransformer $transformer */ | ||||
|         $transformer = app(RecurrenceTransformer::class); | ||||
|         $transformer->setParameters(new ParameterBag()); | ||||
| @@ -108,12 +105,12 @@ class ShowController extends Controller | ||||
|         $attachments           = $recurrence->attachments()->get(); | ||||
|         $array['attachments']  = []; | ||||
|         $attachmentTransformer = app(AttachmentTransformer::class); | ||||
| 
 | ||||
|         /** @var Attachment $attachment */ | ||||
|         foreach ($attachments as $attachment) { | ||||
|             $item                   = $attachmentTransformer->transform($attachment); | ||||
|             $item['file_exists']    = $repos->exists($attachment); // TODO this should be part of the transformer
 | ||||
|             $array['attachments'][] = $item; | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         $subTitle = (string)trans('firefly.overview_for_recurrence', ['title' => $recurrence->title]); | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| <?php | ||||
| 
 | ||||
| 
 | ||||
| /* | ||||
|  * TriggerController.php | ||||
|  * Copyright (c) 2023 james@firefly-iii.org | ||||
| @@ -39,12 +38,6 @@ use Illuminate\Support\Collection; | ||||
|  */ | ||||
| class TriggerController extends Controller | ||||
| { | ||||
|     /** | ||||
|      * @param Recurrence               $recurrence | ||||
|      * @param TriggerRecurrenceRequest $request | ||||
|      * | ||||
|      * @return RedirectResponse | ||||
|      */ | ||||
|     public function trigger(Recurrence $recurrence, TriggerRecurrenceRequest $request): RedirectResponse | ||||
|     { | ||||
|         $all  = $request->getAll(); | ||||
| @@ -55,6 +48,7 @@ class TriggerController extends Controller | ||||
| 
 | ||||
|         // fire the recurring cron job on the given date, then post-date the created transaction.
 | ||||
|         app('log')->info(sprintf('Trigger: will now fire recurring cron job task for date "%s".', $date->format('Y-m-d H:i:s'))); | ||||
| 
 | ||||
|         /** @var CreateRecurringTransactions $job */ | ||||
|         $job = app(CreateRecurringTransactions::class); | ||||
|         $job->setRecurrences(new Collection([$recurrence])); | ||||
| @@ -64,6 +58,7 @@ class TriggerController extends Controller | ||||
|         app('log')->debug('Done with recurrence.'); | ||||
| 
 | ||||
|         $groups = $job->getGroups(); | ||||
| 
 | ||||
|         /** @var TransactionGroup $group */ | ||||
|         foreach ($groups as $group) { | ||||
|             /** @var TransactionJournal $journal */ | ||||
| @@ -86,7 +81,6 @@ class TriggerController extends Controller | ||||
|             $request->session()->flash('success_url', route('transactions.show', [$first->id])); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         return redirect(route('recurring.show', [$recurrence->id])); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -29,7 +29,6 @@ use FireflyIII\Http\Controllers\Controller; | ||||
| use FireflyIII\Repositories\Account\AccountTaskerInterface; | ||||
| use FireflyIII\Support\CacheProperties; | ||||
| use Illuminate\Support\Collection; | ||||
| use Throwable; | ||||
| 
 | ||||
| /** | ||||
|  * Class AccountController. | ||||
| @@ -39,11 +38,6 @@ class AccountController extends Controller | ||||
|     /** | ||||
|      * Show partial overview for account balances. | ||||
|      * | ||||
|      * @param Collection $accounts | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return string | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function general(Collection $accounts, Carbon $start, Carbon $end): string | ||||
| @@ -61,12 +55,14 @@ class AccountController extends Controller | ||||
|         /** @var AccountTaskerInterface $accountTasker */ | ||||
|         $accountTasker = app(AccountTaskerInterface::class); | ||||
|         $accountReport = $accountTasker->getAccountReport($accounts, $start, $end); | ||||
| 
 | ||||
|         try { | ||||
|             $result = view('reports.partials.accounts', compact('accountReport'))->render(); | ||||
|         } catch (Throwable $e) { | ||||
|         } catch (\Throwable $e) { | ||||
|             app('log')->error(sprintf('Could not render reports.partials.accounts: %s', $e->getMessage())); | ||||
|             app('log')->error($e->getTraceAsString()); | ||||
|             $result = 'Could not render view.'; | ||||
| 
 | ||||
|             throw new FireflyException($result, 0, $e); | ||||
|         } | ||||
| 
 | ||||
|   | ||||
| @@ -32,7 +32,6 @@ use FireflyIII\Models\Budget; | ||||
| use FireflyIII\Models\TransactionType; | ||||
| use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; | ||||
| use Illuminate\Support\Collection; | ||||
| use Throwable; | ||||
| 
 | ||||
| /** | ||||
|  * Class BalanceController. | ||||
| @@ -61,11 +60,8 @@ class BalanceController extends Controller | ||||
|     /** | ||||
|      * Show overview of budget balances. | ||||
|      * | ||||
|      * @param Collection $accounts | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return string | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function general(Collection $accounts, Carbon $start, Carbon $end) | ||||
| @@ -74,6 +70,7 @@ class BalanceController extends Controller | ||||
|             'budgets'  => [], | ||||
|             'accounts' => [], | ||||
|         ]; | ||||
| 
 | ||||
|         /** @var Account $account */ | ||||
|         foreach ($accounts as $account) { | ||||
|             $report['accounts'][$account->id] = [ | ||||
| @@ -96,10 +93,13 @@ class BalanceController extends Controller | ||||
|                 'sums'        => [], // per currency
 | ||||
|             ]; | ||||
|             $spent                        = []; | ||||
| 
 | ||||
|             /** @var GroupCollectorInterface $collector */ | ||||
|             $collector = app(GroupCollectorInterface::class); | ||||
|             $journals  = $collector->setRange($start, $end)->setSourceAccounts($accounts)->setTypes([TransactionType::WITHDRAWAL])->setBudget($budget) | ||||
|                                    ->getExtractedJournals(); | ||||
|                 ->getExtractedJournals() | ||||
|             ; | ||||
| 
 | ||||
|             /** @var array $journal */ | ||||
|             foreach ($journals as $journal) { | ||||
|                 $sourceAccount                  = $journal['source_account_id']; | ||||
| @@ -137,12 +137,14 @@ class BalanceController extends Controller | ||||
|             $report['budgets'][$budgetId]['spent'] = $spent; | ||||
|             // get transactions in budget
 | ||||
|         } | ||||
| 
 | ||||
|         try { | ||||
|             $result = view('reports.partials.balance', compact('report'))->render(); | ||||
|         } catch (Throwable $e) { | ||||
|         } catch (\Throwable $e) { | ||||
|             app('log')->error(sprintf('Could not render reports.partials.balance: %s', $e->getMessage())); | ||||
|             app('log')->error($e->getTraceAsString()); | ||||
|             $result = 'Could not render view.'; | ||||
| 
 | ||||
|             throw new FireflyException($result, 0, $e); | ||||
|         } | ||||
| 
 | ||||
|   | ||||
| @@ -29,7 +29,6 @@ use FireflyIII\Helpers\Report\ReportHelperInterface; | ||||
| use FireflyIII\Http\Controllers\Controller; | ||||
| use FireflyIII\Support\CacheProperties; | ||||
| use Illuminate\Support\Collection; | ||||
| use Throwable; | ||||
| 
 | ||||
| /** | ||||
|  * Class BillController | ||||
| @@ -37,11 +36,8 @@ use Throwable; | ||||
| class BillController extends Controller | ||||
| { | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return mixed|string | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function overview(Collection $accounts, Carbon $start, Carbon $end)   // chart properties for cache:
 | ||||
| @@ -54,15 +50,18 @@ class BillController extends Controller | ||||
|         if ($cache->has()) { | ||||
|             return $cache->get(); | ||||
|         } | ||||
| 
 | ||||
|         /** @var ReportHelperInterface $helper */ | ||||
|         $helper = app(ReportHelperInterface::class); | ||||
|         $report = $helper->getBillReport($accounts, $start, $end); | ||||
| 
 | ||||
|         try { | ||||
|             $result = view('reports.partials.bills', compact('report'))->render(); | ||||
|         } catch (Throwable $e) { | ||||
|         } catch (\Throwable $e) { | ||||
|             app('log')->error(sprintf('Could not render reports.partials.budgets: %s', $e->getMessage())); | ||||
|             app('log')->error($e->getTraceAsString()); | ||||
|             $result = 'Could not render view.'; | ||||
| 
 | ||||
|             throw new FireflyException($result, 0, $e); | ||||
|         } | ||||
| 
 | ||||
|   | ||||
| @@ -35,8 +35,6 @@ use FireflyIII\Support\Report\Budget\BudgetReportGenerator; | ||||
| use Illuminate\Contracts\View\Factory; | ||||
| use Illuminate\Support\Collection; | ||||
| use Illuminate\View\View; | ||||
| use JsonException; | ||||
| use Throwable; | ||||
| 
 | ||||
| /** | ||||
|  * Class BudgetController. | ||||
| @@ -49,8 +47,6 @@ class BudgetController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * ExpenseReportController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -67,14 +63,10 @@ class BudgetController extends Controller | ||||
|     /** | ||||
|      * Partial used in the budget report. | ||||
|      * | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $budgets | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * @throws JsonException | ||||
|      * @throws \JsonException | ||||
|      */ | ||||
|     public function accountPerBudget(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end) | ||||
|     { | ||||
| @@ -94,11 +86,6 @@ class BudgetController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $budgets | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function accounts(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end) | ||||
| @@ -106,6 +93,7 @@ class BudgetController extends Controller | ||||
|         $spent  = $this->opsRepository->listExpenses($start, $end, $accounts, $budgets); | ||||
|         $report = []; | ||||
|         $sums   = []; | ||||
| 
 | ||||
|         /** @var Account $account */ | ||||
|         foreach ($accounts as $account) { | ||||
|             $accountId          = $account->id; | ||||
| @@ -150,12 +138,8 @@ class BudgetController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $budgets | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return string | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function avgExpenses(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end) | ||||
| @@ -179,7 +163,7 @@ class BudgetController extends Controller | ||||
|                         'currency_symbol'          => $currency['currency_symbol'], | ||||
|                         'currency_decimal_places'  => $currency['currency_decimal_places'], | ||||
|                     ]; | ||||
|                     $result[$key]['transactions']++; | ||||
|                     ++$result[$key]['transactions']; | ||||
|                     $result[$key]['sum']       = bcadd($journal['amount'], $result[$key]['sum']); | ||||
|                     $result[$key]['avg']       = bcdiv($result[$key]['sum'], (string)$result[$key]['transactions']); | ||||
|                     $result[$key]['avg_float'] = (float)$result[$key]['avg']; // intentional float
 | ||||
| @@ -193,10 +177,11 @@ class BudgetController extends Controller | ||||
| 
 | ||||
|         try { | ||||
|             $result = view('reports.budget.partials.avg-expenses', compact('result'))->render(); | ||||
|         } catch (Throwable $e) { | ||||
|         } catch (\Throwable $e) { | ||||
|             app('log')->error(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage())); | ||||
|             $result = sprintf('Could not render view: %s', $e->getMessage()); | ||||
|             app('log')->error($e->getTraceAsString()); | ||||
| 
 | ||||
|             throw new FireflyException($result, 0, $e); | ||||
|         } | ||||
| 
 | ||||
| @@ -204,11 +189,6 @@ class BudgetController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $budgets | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function budgets(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end) | ||||
| @@ -216,6 +196,7 @@ class BudgetController extends Controller | ||||
|         $spent  = $this->opsRepository->listExpenses($start, $end, $accounts, $budgets); | ||||
|         $sums   = []; | ||||
|         $report = []; | ||||
| 
 | ||||
|         /** @var Budget $budget */ | ||||
|         foreach ($budgets as $budget) { | ||||
|             $budgetId          = $budget->id; | ||||
| @@ -234,6 +215,7 @@ class BudgetController extends Controller | ||||
|                 'currency_decimal_places' => $currency['currency_decimal_places'], | ||||
|                 'sum'                     => '0', | ||||
|             ]; | ||||
| 
 | ||||
|             /** @var array $budget */ | ||||
|             foreach ($currency['budgets'] as $budget) { | ||||
|                 $budgetId = $budget['id']; | ||||
| @@ -247,7 +229,6 @@ class BudgetController extends Controller | ||||
|                         'currency_symbol'         => $currency['currency_symbol'], | ||||
|                         'currency_name'           => $currency['currency_name'], | ||||
|                         'currency_decimal_places' => $currency['currency_decimal_places'], | ||||
| 
 | ||||
|                     ]; | ||||
|                     $report[$budgetId]['currencies'][$currencyId]['sum'] = bcadd($report[$budgetId]['currencies'][$currencyId]['sum'], $journal['amount']); | ||||
|                     $sums[$currencyId]['sum']                            = bcadd($sums[$currencyId]['sum'], $journal['amount']); | ||||
| @@ -274,13 +255,10 @@ class BudgetController extends Controller | ||||
|     /** | ||||
|      * Show partial overview of budgets. | ||||
|      * | ||||
|      * @param Collection $accounts | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return string | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * @throws JsonException | ||||
|      * @throws \JsonException | ||||
|      */ | ||||
|     public function general(Collection $accounts, Carbon $start, Carbon $end) | ||||
|     { | ||||
| @@ -301,11 +279,8 @@ class BudgetController extends Controller | ||||
|     /** | ||||
|      * Show budget overview for a period. | ||||
|      * | ||||
|      * @param Collection $accounts | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return mixed|string | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function period(Collection $accounts, Carbon $start, Carbon $end) | ||||
| @@ -329,7 +304,7 @@ class BudgetController extends Controller | ||||
|             foreach ($currency['budgets'] as $budget) { | ||||
|                 $count = 0; | ||||
|                 foreach ($budget['transaction_journals'] as $journal) { | ||||
|                     $count++; | ||||
|                     ++$count; | ||||
|                     $key                               = sprintf('%d-%d', $budget['id'], $currency['currency_id']); | ||||
|                     $dateKey                           = $journal['date']->format($keyFormat); | ||||
|                     $report[$key]                      ??= [ | ||||
| @@ -344,18 +319,20 @@ class BudgetController extends Controller | ||||
|                         'entries'                 => [], | ||||
|                     ]; | ||||
|                     $report[$key]['entries'][$dateKey] ??= '0'; | ||||
|                     $report[$key]['entries'][$dateKey] = bcadd($journal['amount'], $report[$key] ['entries'][$dateKey]); | ||||
|                     $report[$key]['sum']               = bcadd($report[$key] ['sum'], $journal['amount']); | ||||
|                     $report[$key]['entries'][$dateKey] = bcadd($journal['amount'], $report[$key]['entries'][$dateKey]); | ||||
|                     $report[$key]['sum']               = bcadd($report[$key]['sum'], $journal['amount']); | ||||
|                     $report[$key]['avg']               = bcdiv($report[$key]['sum'], (string)count($periods)); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         try { | ||||
|             $result = view('reports.partials.budget-period', compact('report', 'periods'))->render(); | ||||
|         } catch (Throwable $e) { | ||||
|         } catch (\Throwable $e) { | ||||
|             app('log')->error(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage())); | ||||
|             app('log')->error($e->getTraceAsString()); | ||||
|             $result = 'Could not render view.'; | ||||
| 
 | ||||
|             throw new FireflyException($result, 0, $e); | ||||
|         } | ||||
| 
 | ||||
| @@ -365,12 +342,8 @@ class BudgetController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $budgets | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return string | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function topExpenses(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end) | ||||
| @@ -406,9 +379,10 @@ class BudgetController extends Controller | ||||
| 
 | ||||
|         try { | ||||
|             $result = view('reports.budget.partials.top-expenses', compact('result'))->render(); | ||||
|         } catch (Throwable $e) { | ||||
|         } catch (\Throwable $e) { | ||||
|             app('log')->error(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage())); | ||||
|             $result = sprintf('Could not render view: %s', $e->getMessage()); | ||||
| 
 | ||||
|             throw new FireflyException($result, 0, $e); | ||||
|         } | ||||
| 
 | ||||
|   | ||||
| @@ -36,7 +36,6 @@ use FireflyIII\Support\Report\Category\CategoryReportGenerator; | ||||
| use Illuminate\Contracts\View\Factory; | ||||
| use Illuminate\Support\Collection; | ||||
| use Illuminate\View\View; | ||||
| use Throwable; | ||||
| 
 | ||||
| /** | ||||
|  * Class CategoryController. | ||||
| @@ -50,8 +49,6 @@ class CategoryController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * ExpenseReportController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -67,11 +64,6 @@ class CategoryController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $categories | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function accountPerCategory(Collection $accounts, Collection $categories, Carbon $start, Carbon $end) | ||||
| @@ -79,6 +71,7 @@ class CategoryController extends Controller | ||||
|         $spent  = $this->opsRepository->listExpenses($start, $end, $accounts, $categories); | ||||
|         $earned = $this->opsRepository->listIncome($start, $end, $accounts, $categories); | ||||
|         $report = []; | ||||
| 
 | ||||
|         /** @var Account $account */ | ||||
|         foreach ($accounts as $account) { | ||||
|             $accountId          = $account->id; | ||||
| @@ -108,10 +101,10 @@ class CategoryController extends Controller | ||||
| 
 | ||||
|                     $report[$sourceAccountId]['currencies'][$currencyId]['categories'][$category['id']] | ||||
|                                                                                                                  ??= [ | ||||
|                         'spent'  => '0', | ||||
|                         'earned' => '0', | ||||
|                         'sum'    => '0', | ||||
|                     ]; | ||||
|                                                                                                                      'spent'  => '0', | ||||
|                                                                                                                      'earned' => '0', | ||||
|                                                                                                                      'sum'    => '0', | ||||
|                                                                                                                  ]; | ||||
|                     $report[$sourceAccountId]['currencies'][$currencyId]['categories'][$category['id']]['spent'] = bcadd( | ||||
|                         $report[$sourceAccountId]['currencies'][$currencyId]['categories'][$category['id']]['spent'], | ||||
|                         $journal['amount'] | ||||
| @@ -133,18 +126,18 @@ class CategoryController extends Controller | ||||
|                     $destinationId                                                                              = $journal['destination_account_id']; | ||||
|                     $report[$destinationId]['currencies'][$currencyId] | ||||
|                                                                                                                 ??= [ | ||||
|                         'currency_id'             => $currency['currency_id'], | ||||
|                         'currency_symbol'         => $currency['currency_symbol'], | ||||
|                         'currency_name'           => $currency['currency_name'], | ||||
|                         'currency_decimal_places' => $currency['currency_decimal_places'], | ||||
|                         'categories'              => [], | ||||
|                     ]; | ||||
|                                                                                                                     'currency_id'             => $currency['currency_id'], | ||||
|                                                                                                                     'currency_symbol'         => $currency['currency_symbol'], | ||||
|                                                                                                                     'currency_name'           => $currency['currency_name'], | ||||
|                                                                                                                     'currency_decimal_places' => $currency['currency_decimal_places'], | ||||
|                                                                                                                     'categories'              => [], | ||||
|                                                                                                                 ]; | ||||
|                     $report[$destinationId]['currencies'][$currencyId]['categories'][$category['id']] | ||||
|                                                                                                                 ??= [ | ||||
|                         'spent'  => '0', | ||||
|                         'earned' => '0', | ||||
|                         'sum'    => '0', | ||||
|                     ]; | ||||
|                                                                                                                     'spent'  => '0', | ||||
|                                                                                                                     'earned' => '0', | ||||
|                                                                                                                     'sum'    => '0', | ||||
|                                                                                                                 ]; | ||||
|                     $report[$destinationId]['currencies'][$currencyId]['categories'][$category['id']]['earned'] = bcadd( | ||||
|                         $report[$destinationId]['currencies'][$currencyId]['categories'][$category['id']]['earned'], | ||||
|                         $journal['amount'] | ||||
| @@ -161,11 +154,6 @@ class CategoryController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $categories | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function accounts(Collection $accounts, Collection $categories, Carbon $start, Carbon $end) | ||||
| @@ -174,6 +162,7 @@ class CategoryController extends Controller | ||||
|         $earned = $this->opsRepository->listIncome($start, $end, $accounts, $categories); | ||||
|         $report = []; | ||||
|         $sums   = []; | ||||
| 
 | ||||
|         /** @var Account $account */ | ||||
|         foreach ($accounts as $account) { | ||||
|             $accountId          = $account->id; | ||||
| @@ -265,12 +254,8 @@ class CategoryController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $categories | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return string | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function avgExpenses(Collection $accounts, Collection $categories, Carbon $start, Carbon $end) | ||||
| @@ -294,7 +279,7 @@ class CategoryController extends Controller | ||||
|                         'currency_symbol'          => $currency['currency_symbol'], | ||||
|                         'currency_decimal_places'  => $currency['currency_decimal_places'], | ||||
|                     ]; | ||||
|                     $result[$key]['transactions']++; | ||||
|                     ++$result[$key]['transactions']; | ||||
|                     $result[$key]['sum']       = bcadd($journal['amount'], $result[$key]['sum']); | ||||
|                     $result[$key]['avg']       = bcdiv($result[$key]['sum'], (string)$result[$key]['transactions']); | ||||
|                     $result[$key]['avg_float'] = (float)$result[$key]['avg']; // intentional float
 | ||||
| @@ -308,9 +293,10 @@ class CategoryController extends Controller | ||||
| 
 | ||||
|         try { | ||||
|             $result = view('reports.category.partials.avg-expenses', compact('result'))->render(); | ||||
|         } catch (Throwable $e) { | ||||
|         } catch (\Throwable $e) { | ||||
|             app('log')->error(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage())); | ||||
|             $result = sprintf('Could not render view: %s', $e->getMessage()); | ||||
| 
 | ||||
|             throw new FireflyException($result, 0, $e); | ||||
|         } | ||||
| 
 | ||||
| @@ -318,12 +304,8 @@ class CategoryController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $categories | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return string | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function avgIncome(Collection $accounts, Collection $categories, Carbon $start, Carbon $end) | ||||
| @@ -347,7 +329,7 @@ class CategoryController extends Controller | ||||
|                         'currency_symbol'         => $currency['currency_symbol'], | ||||
|                         'currency_decimal_places' => $currency['currency_decimal_places'], | ||||
|                     ]; | ||||
|                     $result[$key]['transactions']++; | ||||
|                     ++$result[$key]['transactions']; | ||||
|                     $result[$key]['sum']       = bcadd($journal['amount'], $result[$key]['sum']); | ||||
|                     $result[$key]['avg']       = bcdiv($result[$key]['sum'], (string)$result[$key]['transactions']); | ||||
|                     $result[$key]['avg_float'] = (float)$result[$key]['avg']; | ||||
| @@ -361,9 +343,10 @@ class CategoryController extends Controller | ||||
| 
 | ||||
|         try { | ||||
|             $result = view('reports.category.partials.avg-income', compact('result'))->render(); | ||||
|         } catch (Throwable $e) { | ||||
|         } catch (\Throwable $e) { | ||||
|             app('log')->error(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage())); | ||||
|             $result = sprintf('Could not render view: %s', $e->getMessage()); | ||||
| 
 | ||||
|             throw new FireflyException($result, 0, $e); | ||||
|         } | ||||
| 
 | ||||
| @@ -371,11 +354,6 @@ class CategoryController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $categories | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function categories(Collection $accounts, Collection $categories, Carbon $start, Carbon $end) | ||||
| @@ -384,6 +362,7 @@ class CategoryController extends Controller | ||||
|         $earned = $this->opsRepository->listIncome($start, $end, $accounts, $categories); | ||||
|         $sums   = []; | ||||
|         $report = []; | ||||
| 
 | ||||
|         /** @var Category $category */ | ||||
|         foreach ($categories as $category) { | ||||
|             $categoryId          = $category->id; | ||||
| @@ -404,6 +383,7 @@ class CategoryController extends Controller | ||||
|                 'spent_sum'               => '0', | ||||
|                 'total_sum'               => '0', | ||||
|             ]; | ||||
| 
 | ||||
|             /** @var array $category */ | ||||
|             foreach ($currency['categories'] as $category) { | ||||
|                 $categoryId = $category['id']; | ||||
| @@ -445,6 +425,7 @@ class CategoryController extends Controller | ||||
|                 'spent_sum'               => '0', | ||||
|                 'total_sum'               => '0', | ||||
|             ]; | ||||
| 
 | ||||
|             /** @var array $category */ | ||||
|             foreach ($currency['categories'] as $category) { | ||||
|                 $categoryId = $category['id']; | ||||
| @@ -481,11 +462,8 @@ class CategoryController extends Controller | ||||
|     /** | ||||
|      * Show overview of expenses in category. | ||||
|      * | ||||
|      * @param Collection $accounts | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return mixed|string | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function expenses(Collection $accounts, Carbon $start, Carbon $end) | ||||
| @@ -528,7 +506,6 @@ class CategoryController extends Controller | ||||
|                         'currency_decimal_places' => $currencyRow['currency_decimal_places'], | ||||
|                         'sum'                     => '0', | ||||
|                         'entries'                 => [], | ||||
| 
 | ||||
|                     ]; | ||||
|                     foreach ($categoryRow['transaction_journals'] as $journal) { | ||||
|                         $date                         = $journal['date']->format($format); | ||||
| @@ -546,13 +523,13 @@ class CategoryController extends Controller | ||||
| 
 | ||||
|         try { | ||||
|             $result = view('reports.partials.category-period', compact('report', 'periods'))->render(); | ||||
|         } catch (Throwable $e) { | ||||
|         } catch (\Throwable $e) { | ||||
|             app('log')->error(sprintf('Could not render category::expenses: %s', $e->getMessage())); | ||||
|             $result = sprintf('An error prevented Firefly III from rendering: %s. Apologies.', $e->getMessage()); | ||||
| 
 | ||||
|             throw new FireflyException($result, 0, $e); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         $cache->store($result); | ||||
| 
 | ||||
|         return $result; | ||||
| @@ -561,12 +538,6 @@ class CategoryController extends Controller | ||||
|     /** | ||||
|      * Show overview of income in category. | ||||
|      * | ||||
|      * @param Collection $accounts | ||||
|      * | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return string | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function income(Collection $accounts, Carbon $start, Carbon $end): string | ||||
| @@ -609,7 +580,6 @@ class CategoryController extends Controller | ||||
|                         'currency_decimal_places' => $currencyRow['currency_decimal_places'], | ||||
|                         'sum'                     => '0', | ||||
|                         'entries'                 => [], | ||||
| 
 | ||||
|                     ]; | ||||
|                     foreach ($categoryRow['transaction_journals'] as $journal) { | ||||
|                         $date                         = $journal['date']->format($format); | ||||
| @@ -625,13 +595,13 @@ class CategoryController extends Controller | ||||
| 
 | ||||
|         try { | ||||
|             $result = view('reports.partials.category-period', compact('report', 'periods'))->render(); | ||||
|         } catch (Throwable $e) { | ||||
|         } catch (\Throwable $e) { | ||||
|             app('log')->error(sprintf('Could not render category::expenses: %s', $e->getMessage())); | ||||
|             $result = sprintf('An error prevented Firefly III from rendering: %s. Apologies.', $e->getMessage()); | ||||
| 
 | ||||
|             throw new FireflyException($result, 0, $e); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         $cache->store($result); | ||||
| 
 | ||||
|         return $result; | ||||
| @@ -640,11 +610,6 @@ class CategoryController extends Controller | ||||
|     /** | ||||
|      * Show overview of category transactions on the default report. | ||||
|      * | ||||
|      * @param Collection $accounts | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return string | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function operations(Collection $accounts, Carbon $start, Carbon $end): string | ||||
| @@ -667,13 +632,13 @@ class CategoryController extends Controller | ||||
|         $generator->operations(); | ||||
|         $report = $generator->getReport(); | ||||
| 
 | ||||
| 
 | ||||
|         try { | ||||
|             $result = view('reports.partials.categories', compact('report'))->render(); | ||||
|             $cache->store($result); | ||||
|         } catch (Throwable $e) { | ||||
|         } catch (\Throwable $e) { | ||||
|             app('log')->error(sprintf('Could not render category::expenses: %s', $e->getMessage())); | ||||
|             $result = sprintf('An error prevented Firefly III from rendering: %s. Apologies.', $e->getMessage()); | ||||
| 
 | ||||
|             throw new FireflyException($result, 0, $e); | ||||
|         } | ||||
| 
 | ||||
| @@ -681,12 +646,8 @@ class CategoryController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $categories | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return string | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function topExpenses(Collection $accounts, Collection $categories, Carbon $start, Carbon $end) | ||||
| @@ -722,9 +683,10 @@ class CategoryController extends Controller | ||||
| 
 | ||||
|         try { | ||||
|             $result = view('reports.category.partials.top-expenses', compact('result'))->render(); | ||||
|         } catch (Throwable $e) { | ||||
|         } catch (\Throwable $e) { | ||||
|             app('log')->debug(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage())); | ||||
|             $result = sprintf('Could not render view: %s', $e->getMessage()); | ||||
| 
 | ||||
|             throw new FireflyException($e->getMessage(), 0, $e); | ||||
|         } | ||||
| 
 | ||||
| @@ -732,12 +694,8 @@ class CategoryController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $categories | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return string | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function topIncome(Collection $accounts, Collection $categories, Carbon $start, Carbon $end) | ||||
| @@ -773,9 +731,10 @@ class CategoryController extends Controller | ||||
| 
 | ||||
|         try { | ||||
|             $result = view('reports.category.partials.top-income', compact('result'))->render(); | ||||
|         } catch (Throwable $e) { | ||||
|         } catch (\Throwable $e) { | ||||
|             app('log')->debug(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage())); | ||||
|             $result = sprintf('Could not render view: %s', $e->getMessage()); | ||||
| 
 | ||||
|             throw new FireflyException($e->getMessage(), 0, $e); | ||||
|         } | ||||
| 
 | ||||
|   | ||||
| @@ -33,11 +33,9 @@ use FireflyIII\Support\Http\Controllers\AugumentData; | ||||
| use Illuminate\Contracts\View\Factory; | ||||
| use Illuminate\Support\Collection; | ||||
| use Illuminate\View\View; | ||||
| use Throwable; | ||||
| 
 | ||||
| /** | ||||
|  * Class DoubleController | ||||
|  * | ||||
|  */ | ||||
| class DoubleController extends Controller | ||||
| { | ||||
| @@ -51,8 +49,6 @@ class DoubleController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Constructor for ExpenseController | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -70,12 +66,8 @@ class DoubleController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $doubles | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return string | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function avgExpenses(Collection $accounts, Collection $doubles, Carbon $start, Carbon $end) | ||||
| @@ -100,7 +92,7 @@ class DoubleController extends Controller | ||||
|                     'currency_symbol'         => $currency['currency_symbol'], | ||||
|                     'currency_decimal_places' => $currency['currency_decimal_places'], | ||||
|                 ]; | ||||
|                 $result[$key]['transactions']++; | ||||
|                 ++$result[$key]['transactions']; | ||||
|                 $result[$key]['sum']       = bcadd($journal['amount'], $result[$key]['sum']); | ||||
|                 $result[$key]['avg']       = bcdiv($result[$key]['sum'], (string)$result[$key]['transactions']); | ||||
|                 $result[$key]['avg_float'] = (float)$result[$key]['avg']; | ||||
| @@ -113,9 +105,10 @@ class DoubleController extends Controller | ||||
| 
 | ||||
|         try { | ||||
|             $result = view('reports.double.partials.avg-expenses', compact('result'))->render(); | ||||
|         } catch (Throwable $e) { | ||||
|         } catch (\Throwable $e) { | ||||
|             app('log')->error(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage())); | ||||
|             $result = sprintf('Could not render view: %s', $e->getMessage()); | ||||
| 
 | ||||
|             throw new FireflyException($e->getMessage(), 0, $e); | ||||
|         } | ||||
| 
 | ||||
| @@ -123,12 +116,8 @@ class DoubleController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $doubles | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return string | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function avgIncome(Collection $accounts, Collection $doubles, Carbon $start, Carbon $end) | ||||
| @@ -153,7 +142,7 @@ class DoubleController extends Controller | ||||
|                     'currency_symbol'          => $currency['currency_symbol'], | ||||
|                     'currency_decimal_places'  => $currency['currency_decimal_places'], | ||||
|                 ]; | ||||
|                 $result[$key]['transactions']++; | ||||
|                 ++$result[$key]['transactions']; | ||||
|                 $result[$key]['sum']       = bcadd($journal['amount'], $result[$key]['sum']); | ||||
|                 $result[$key]['avg']       = bcdiv($result[$key]['sum'], (string)$result[$key]['transactions']); | ||||
|                 $result[$key]['avg_float'] = (float)$result[$key]['avg']; | ||||
| @@ -166,9 +155,10 @@ class DoubleController extends Controller | ||||
| 
 | ||||
|         try { | ||||
|             $result = view('reports.double.partials.avg-income', compact('result'))->render(); | ||||
|         } catch (Throwable $e) { | ||||
|         } catch (\Throwable $e) { | ||||
|             app('log')->error(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage())); | ||||
|             $result = sprintf('Could not render view: %s', $e->getMessage()); | ||||
| 
 | ||||
|             throw new FireflyException($e->getMessage(), 0, $e); | ||||
|         } | ||||
| 
 | ||||
| @@ -176,11 +166,6 @@ class DoubleController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $double | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function operations(Collection $accounts, Collection $double, Carbon $start, Carbon $end) | ||||
| @@ -295,36 +280,6 @@ class DoubleController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * TODO this method is duplicated. | ||||
|      * | ||||
|      * @param Collection  $accounts | ||||
|      * @param int         $id | ||||
|      * @param string      $name | ||||
|      * @param string|null $iban | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     private function getCounterpartName(Collection $accounts, int $id, string $name, ?string $iban): string | ||||
|     { | ||||
|         /** @var Account $account */ | ||||
|         foreach ($accounts as $account) { | ||||
|             if ($account->name === $name && $account->id !== $id) { | ||||
|                 return $account->name; | ||||
|             } | ||||
|             if (null !== $account->iban && $account->iban === $iban && $account->id !== $id) { | ||||
|                 return $account->iban; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return $name; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $double | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function operationsPerAsset(Collection $accounts, Collection $double, Carbon $start, Carbon $end) | ||||
| @@ -420,12 +375,8 @@ class DoubleController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $doubles | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return string | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function topExpenses(Collection $accounts, Collection $doubles, Carbon $start, Carbon $end) | ||||
| @@ -461,9 +412,10 @@ class DoubleController extends Controller | ||||
| 
 | ||||
|         try { | ||||
|             $result = view('reports.double.partials.top-expenses', compact('result'))->render(); | ||||
|         } catch (Throwable $e) { | ||||
|         } catch (\Throwable $e) { | ||||
|             app('log')->error(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage())); | ||||
|             $result = sprintf('Could not render view: %s', $e->getMessage()); | ||||
| 
 | ||||
|             throw new FireflyException($e->getMessage(), 0, $e); | ||||
|         } | ||||
| 
 | ||||
| @@ -471,12 +423,8 @@ class DoubleController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $doubles | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return string | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function topIncome(Collection $accounts, Collection $doubles, Carbon $start, Carbon $end) | ||||
| @@ -512,12 +460,31 @@ class DoubleController extends Controller | ||||
| 
 | ||||
|         try { | ||||
|             $result = view('reports.double.partials.top-income', compact('result'))->render(); | ||||
|         } catch (Throwable $e) { | ||||
|         } catch (\Throwable $e) { | ||||
|             app('log')->error(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage())); | ||||
|             $result = sprintf('Could not render view: %s', $e->getMessage()); | ||||
| 
 | ||||
|             throw new FireflyException($e->getMessage(), 0, $e); | ||||
|         } | ||||
| 
 | ||||
|         return $result; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * TODO this method is duplicated. | ||||
|      */ | ||||
|     private function getCounterpartName(Collection $accounts, int $id, string $name, ?string $iban): string | ||||
|     { | ||||
|         /** @var Account $account */ | ||||
|         foreach ($accounts as $account) { | ||||
|             if ($account->name === $name && $account->id !== $id) { | ||||
|                 return $account->name; | ||||
|             } | ||||
|             if (null !== $account->iban && $account->iban === $iban && $account->id !== $id) { | ||||
|                 return $account->iban; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return $name; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -29,7 +29,6 @@ use FireflyIII\Http\Controllers\Controller; | ||||
| use FireflyIII\Repositories\Account\AccountTaskerInterface; | ||||
| use FireflyIII\Support\CacheProperties; | ||||
| use Illuminate\Support\Collection; | ||||
| use Throwable; | ||||
| 
 | ||||
| /** | ||||
|  * Class OperationsController. | ||||
| @@ -41,8 +40,6 @@ class OperationsController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * OperationsController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -61,11 +58,8 @@ class OperationsController extends Controller | ||||
|     /** | ||||
|      * View of income and expense. | ||||
|      * | ||||
|      * @param Collection $accounts | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return mixed|string | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function expenses(Collection $accounts, Carbon $start, Carbon $end) | ||||
| @@ -81,12 +75,14 @@ class OperationsController extends Controller | ||||
|         } | ||||
|         $report = $this->tasker->getExpenseReport($start, $end, $accounts); | ||||
|         $type   = 'expense-entry'; | ||||
| 
 | ||||
|         try { | ||||
|             $result = view('reports.partials.income-expenses', compact('report', 'type'))->render(); | ||||
|         } catch (Throwable $e) { | ||||
|         } catch (\Throwable $e) { | ||||
|             app('log')->error(sprintf('Could not render reports.partials.income-expense: %s', $e->getMessage())); | ||||
|             app('log')->error($e->getTraceAsString()); | ||||
|             $result = 'Could not render view.'; | ||||
| 
 | ||||
|             throw new FireflyException($result, 0, $e); | ||||
|         } | ||||
| 
 | ||||
| @@ -98,11 +94,6 @@ class OperationsController extends Controller | ||||
|     /** | ||||
|      * View of income. | ||||
|      * | ||||
|      * @param Collection $accounts | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return string | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function income(Collection $accounts, Carbon $start, Carbon $end): string | ||||
| @@ -118,12 +109,14 @@ class OperationsController extends Controller | ||||
|         } | ||||
|         $report = $this->tasker->getIncomeReport($start, $end, $accounts); | ||||
|         $type   = 'income-entry'; | ||||
| 
 | ||||
|         try { | ||||
|             $result = view('reports.partials.income-expenses', compact('report', 'type'))->render(); | ||||
|         } catch (Throwable $e) { | ||||
|         } catch (\Throwable $e) { | ||||
|             app('log')->error(sprintf('Could not render reports.partials.income-expenses: %s', $e->getMessage())); | ||||
|             app('log')->error($e->getTraceAsString()); | ||||
|             $result = 'Could not render view.'; | ||||
| 
 | ||||
|             throw new FireflyException($result, 0, $e); | ||||
|         } | ||||
| 
 | ||||
| @@ -135,11 +128,8 @@ class OperationsController extends Controller | ||||
|     /** | ||||
|      * Overview of income and expense. | ||||
|      * | ||||
|      * @param Collection $accounts | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return mixed|string | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function operations(Collection $accounts, Carbon $start, Carbon $end) | ||||
| @@ -177,10 +167,11 @@ class OperationsController extends Controller | ||||
| 
 | ||||
|         try { | ||||
|             $result = view('reports.partials.operations', compact('sums'))->render(); | ||||
|         } catch (Throwable $e) { | ||||
|         } catch (\Throwable $e) { | ||||
|             app('log')->error(sprintf('Could not render reports.partials.operations: %s', $e->getMessage())); | ||||
|             app('log')->error($e->getTraceAsString()); | ||||
|             $result = 'Could not render view.'; | ||||
| 
 | ||||
|             throw new FireflyException($result, 0, $e); | ||||
|         } | ||||
|         $cache->store($result); | ||||
|   | ||||
| @@ -32,10 +32,8 @@ use FireflyIII\Repositories\Tag\OperationsRepositoryInterface; | ||||
| use Illuminate\Contracts\View\Factory; | ||||
| use Illuminate\Support\Collection; | ||||
| use Illuminate\View\View; | ||||
| use Throwable; | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * Class TagController | ||||
|  */ | ||||
| class TagController extends Controller | ||||
| @@ -44,8 +42,6 @@ class TagController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * ExpenseReportController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -60,11 +56,6 @@ class TagController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $tags | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function accountPerTag(Collection $accounts, Collection $tags, Carbon $start, Carbon $end) | ||||
| @@ -72,6 +63,7 @@ class TagController extends Controller | ||||
|         $spent  = $this->opsRepository->listExpenses($start, $end, $accounts, $tags); | ||||
|         $earned = $this->opsRepository->listIncome($start, $end, $accounts, $tags); | ||||
|         $report = []; | ||||
| 
 | ||||
|         /** @var Account $account */ | ||||
|         foreach ($accounts as $account) { | ||||
|             $accountId          = $account->id; | ||||
| @@ -101,10 +93,10 @@ class TagController extends Controller | ||||
| 
 | ||||
|                     $report[$sourceAccountId]['currencies'][$currencyId]['tags'][$tag['id']] | ||||
|                                                                                                       ??= [ | ||||
|                         'spent'  => '0', | ||||
|                         'earned' => '0', | ||||
|                         'sum'    => '0', | ||||
|                     ]; | ||||
|                                                                                                           'spent'  => '0', | ||||
|                                                                                                           'earned' => '0', | ||||
|                                                                                                           'sum'    => '0', | ||||
|                                                                                                       ]; | ||||
|                     $report[$sourceAccountId]['currencies'][$currencyId]['tags'][$tag['id']]['spent'] = bcadd( | ||||
|                         $report[$sourceAccountId]['currencies'][$currencyId]['tags'][$tag['id']]['spent'], | ||||
|                         $journal['amount'] | ||||
| @@ -126,18 +118,18 @@ class TagController extends Controller | ||||
|                     $destinationId                                                                   = $journal['destination_account_id']; | ||||
|                     $report[$destinationId]['currencies'][$currencyId] | ||||
|                                                                                                      ??= [ | ||||
|                         'currency_id'             => $currency['currency_id'], | ||||
|                         'currency_symbol'         => $currency['currency_symbol'], | ||||
|                         'currency_name'           => $currency['currency_name'], | ||||
|                         'currency_decimal_places' => $currency['currency_decimal_places'], | ||||
|                         'tags'                    => [], | ||||
|                     ]; | ||||
|                                                                                                          'currency_id'             => $currency['currency_id'], | ||||
|                                                                                                          'currency_symbol'         => $currency['currency_symbol'], | ||||
|                                                                                                          'currency_name'           => $currency['currency_name'], | ||||
|                                                                                                          'currency_decimal_places' => $currency['currency_decimal_places'], | ||||
|                                                                                                          'tags'                    => [], | ||||
|                                                                                                      ]; | ||||
|                     $report[$destinationId]['currencies'][$currencyId]['tags'][$tag['id']] | ||||
|                                                                                                      ??= [ | ||||
|                         'spent'  => '0', | ||||
|                         'earned' => '0', | ||||
|                         'sum'    => '0', | ||||
|                     ]; | ||||
|                                                                                                          'spent'  => '0', | ||||
|                                                                                                          'earned' => '0', | ||||
|                                                                                                          'sum'    => '0', | ||||
|                                                                                                      ]; | ||||
|                     $report[$destinationId]['currencies'][$currencyId]['tags'][$tag['id']]['earned'] = bcadd( | ||||
|                         $report[$destinationId]['currencies'][$currencyId]['tags'][$tag['id']]['earned'], | ||||
|                         $journal['amount'] | ||||
| @@ -154,11 +146,6 @@ class TagController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $tags | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function accounts(Collection $accounts, Collection $tags, Carbon $start, Carbon $end) | ||||
| @@ -167,6 +154,7 @@ class TagController extends Controller | ||||
|         $earned = $this->opsRepository->listIncome($start, $end, $accounts, $tags); | ||||
|         $report = []; | ||||
|         $sums   = []; | ||||
| 
 | ||||
|         /** @var Account $account */ | ||||
|         foreach ($accounts as $account) { | ||||
|             $accountId          = $account->id; | ||||
| @@ -258,12 +246,8 @@ class TagController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $tags | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return string | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function avgExpenses(Collection $accounts, Collection $tags, Carbon $start, Carbon $end) | ||||
| @@ -287,7 +271,7 @@ class TagController extends Controller | ||||
|                         'currency_symbol'          => $currency['currency_symbol'], | ||||
|                         'currency_decimal_places'  => $currency['currency_decimal_places'], | ||||
|                     ]; | ||||
|                     $result[$key]['transactions']++; | ||||
|                     ++$result[$key]['transactions']; | ||||
|                     $result[$key]['sum']       = bcadd($journal['amount'], $result[$key]['sum']); | ||||
|                     $result[$key]['avg']       = bcdiv($result[$key]['sum'], (string)$result[$key]['transactions']); | ||||
|                     $result[$key]['avg_float'] = (float)$result[$key]['avg']; | ||||
| @@ -301,9 +285,10 @@ class TagController extends Controller | ||||
| 
 | ||||
|         try { | ||||
|             $result = view('reports.tag.partials.avg-expenses', compact('result'))->render(); | ||||
|         } catch (Throwable $e) { | ||||
|         } catch (\Throwable $e) { | ||||
|             app('log')->debug(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage())); | ||||
|             $result = sprintf('Could not render view: %s', $e->getMessage()); | ||||
| 
 | ||||
|             throw new FireflyException($result, 0, $e); | ||||
|         } | ||||
| 
 | ||||
| @@ -311,12 +296,8 @@ class TagController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $tags | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return string | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function avgIncome(Collection $accounts, Collection $tags, Carbon $start, Carbon $end) | ||||
| @@ -340,7 +321,7 @@ class TagController extends Controller | ||||
|                         'currency_symbol'         => $currency['currency_symbol'], | ||||
|                         'currency_decimal_places' => $currency['currency_decimal_places'], | ||||
|                     ]; | ||||
|                     $result[$key]['transactions']++; | ||||
|                     ++$result[$key]['transactions']; | ||||
|                     $result[$key]['sum']       = bcadd($journal['amount'], $result[$key]['sum']); | ||||
|                     $result[$key]['avg']       = bcdiv($result[$key]['sum'], (string)$result[$key]['transactions']); | ||||
|                     $result[$key]['avg_float'] = (float)$result[$key]['avg']; | ||||
| @@ -354,9 +335,10 @@ class TagController extends Controller | ||||
| 
 | ||||
|         try { | ||||
|             $result = view('reports.tag.partials.avg-income', compact('result'))->render(); | ||||
|         } catch (Throwable $e) { | ||||
|         } catch (\Throwable $e) { | ||||
|             app('log')->debug(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage())); | ||||
|             $result = sprintf('Could not render view: %s', $e->getMessage()); | ||||
| 
 | ||||
|             throw new FireflyException($result, 0, $e); | ||||
|         } | ||||
| 
 | ||||
| @@ -364,11 +346,6 @@ class TagController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $tags | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function tags(Collection $accounts, Collection $tags, Carbon $start, Carbon $end) | ||||
| @@ -377,6 +354,7 @@ class TagController extends Controller | ||||
|         $earned = $this->opsRepository->listIncome($start, $end, $accounts, $tags); | ||||
|         $sums   = []; | ||||
|         $report = []; | ||||
| 
 | ||||
|         /** @var Tag $tag */ | ||||
|         foreach ($tags as $tag) { | ||||
|             $tagId          = $tag->id; | ||||
| @@ -397,6 +375,7 @@ class TagController extends Controller | ||||
|                 'spent_sum'               => '0', | ||||
|                 'total_sum'               => '0', | ||||
|             ]; | ||||
| 
 | ||||
|             /** @var array $tag */ | ||||
|             foreach ($currency['tags'] as $tag) { | ||||
|                 $tagId = $tag['id']; | ||||
| @@ -438,6 +417,7 @@ class TagController extends Controller | ||||
|                 'spent_sum'               => '0', | ||||
|                 'total_sum'               => '0', | ||||
|             ]; | ||||
| 
 | ||||
|             /** @var array $tag */ | ||||
|             foreach ($currency['tags'] as $tag) { | ||||
|                 $tagId = $tag['id']; | ||||
| @@ -472,12 +452,8 @@ class TagController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $tags | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return string | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function topExpenses(Collection $accounts, Collection $tags, Carbon $start, Carbon $end) | ||||
| @@ -513,9 +489,10 @@ class TagController extends Controller | ||||
| 
 | ||||
|         try { | ||||
|             $result = view('reports.tag.partials.top-expenses', compact('result'))->render(); | ||||
|         } catch (Throwable $e) { | ||||
|         } catch (\Throwable $e) { | ||||
|             app('log')->debug(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage())); | ||||
|             $result = sprintf('Could not render view: %s', $e->getMessage()); | ||||
| 
 | ||||
|             throw new FireflyException($result, 0, $e); | ||||
|         } | ||||
| 
 | ||||
| @@ -523,12 +500,8 @@ class TagController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $tags | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return string | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function topIncome(Collection $accounts, Collection $tags, Carbon $start, Carbon $end) | ||||
| @@ -564,9 +537,10 @@ class TagController extends Controller | ||||
| 
 | ||||
|         try { | ||||
|             $result = view('reports.tag.partials.top-income', compact('result'))->render(); | ||||
|         } catch (Throwable $e) { | ||||
|         } catch (\Throwable $e) { | ||||
|             app('log')->debug(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage())); | ||||
|             $result = sprintf('Could not render view: %s', $e->getMessage()); | ||||
| 
 | ||||
|             throw new FireflyException($result, 0, $e); | ||||
|         } | ||||
| 
 | ||||
|   | ||||
| @@ -44,7 +44,6 @@ use Psr\Container\NotFoundExceptionInterface; | ||||
| 
 | ||||
| /** | ||||
|  * Class ReportController. | ||||
|  * | ||||
|  */ | ||||
| class ReportController extends Controller | ||||
| { | ||||
| @@ -76,11 +75,7 @@ class ReportController extends Controller | ||||
|     /** | ||||
|      * Show audit report. | ||||
|      * | ||||
|      * @param Collection $accounts | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return Factory|View|string | ||||
|      * @return Factory|string|View | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
| @@ -111,12 +106,7 @@ class ReportController extends Controller | ||||
|     /** | ||||
|      * Show budget report. | ||||
|      * | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $budgets | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return Factory|View|string | ||||
|      * @return Factory|string|View | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
| @@ -148,12 +138,7 @@ class ReportController extends Controller | ||||
|     /** | ||||
|      * Show category report. | ||||
|      * | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $categories | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return Factory|View|string | ||||
|      * @return Factory|string|View | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
| @@ -185,11 +170,7 @@ class ReportController extends Controller | ||||
|     /** | ||||
|      * Show default report. | ||||
|      * | ||||
|      * @param Collection $accounts | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return Factory|View|string | ||||
|      * @return Factory|string|View | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
| @@ -221,12 +202,8 @@ class ReportController extends Controller | ||||
|     /** | ||||
|      * Show account report. | ||||
|      * | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $expense | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * | ||||
|      * @return string | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function doubleReport(Collection $accounts, Collection $expense, Carbon $start, Carbon $end) | ||||
| @@ -258,9 +235,8 @@ class ReportController extends Controller | ||||
|     /** | ||||
|      * Show index. | ||||
|      * | ||||
|      * @param AccountRepositoryInterface $repository | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws ContainerExceptionInterface | ||||
|      * @throws NotFoundExceptionInterface | ||||
|      */ | ||||
| @@ -276,6 +252,7 @@ class ReportController extends Controller | ||||
| 
 | ||||
|         // group accounts by role:
 | ||||
|         $groupedAccounts = []; | ||||
| 
 | ||||
|         /** @var Account $account */ | ||||
|         foreach ($accounts as $account) { | ||||
|             $type = $account->accountType->type; | ||||
| @@ -301,9 +278,8 @@ class ReportController extends Controller | ||||
|     /** | ||||
|      * Show options for reports. | ||||
|      * | ||||
|      * @param string $reportType | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function options(string $reportType) | ||||
| @@ -322,14 +298,9 @@ class ReportController extends Controller | ||||
|     /** | ||||
|      * Process the submit of report. | ||||
|      * | ||||
|      * @param ReportFormRequest $request | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector|View | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      * | ||||
|      */ | ||||
|     public function postIndex(ReportFormRequest $request): RedirectResponse | Redirector | View | ||||
|     public function postIndex(ReportFormRequest $request): Redirector|RedirectResponse|View | ||||
|     { | ||||
|         // report type:
 | ||||
|         $reportType = $request->get('report_type'); | ||||
| @@ -391,12 +362,8 @@ class ReportController extends Controller | ||||
|     /** | ||||
|      * Get a tag report. | ||||
|      * | ||||
|      * @param Collection $accounts | ||||
|      * @param Collection $tags | ||||
|      * @param Carbon     $start | ||||
|      * @param Carbon     $end | ||||
|      * @return Factory|string|View | ||||
|      * | ||||
|      * @return Factory|View|string | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function tagReport(Collection $accounts, Collection $tags, Carbon $start, Carbon $end) | ||||
|   | ||||
| @@ -52,8 +52,6 @@ class CreateController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * RuleController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -74,10 +72,8 @@ class CreateController extends Controller | ||||
|     /** | ||||
|      * Create a new rule. It will be stored under the given $ruleGroup. | ||||
|      * | ||||
|      * @param Request        $request | ||||
|      * @param RuleGroup|null $ruleGroup | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function create(Request $request, RuleGroup $ruleGroup = null) | ||||
| @@ -105,7 +101,7 @@ class CreateController extends Controller | ||||
|             } | ||||
|             $oldTriggers = $this->parseFromOperators($operators); | ||||
|         } | ||||
|         //var_dump($oldTriggers);exit;
 | ||||
|         // var_dump($oldTriggers);exit;
 | ||||
| 
 | ||||
|         // restore actions and triggers from old input:
 | ||||
|         if (is_array($request->old()) && count($request->old()) > 0) { | ||||
| @@ -141,10 +137,8 @@ class CreateController extends Controller | ||||
|     /** | ||||
|      * Create a new rule. It will be stored under the given $ruleGroup. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * @param Bill    $bill | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function createFromBill(Request $request, Bill $bill) | ||||
| @@ -193,10 +187,8 @@ class CreateController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Request            $request | ||||
|      * @param TransactionJournal $journal | ||||
|      * | ||||
|      * @return Factory|\Illuminate\Contracts\View\View | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function createFromJournal(Request $request, TransactionJournal $journal) | ||||
| @@ -243,11 +235,6 @@ class CreateController extends Controller | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function duplicate(Request $request): JsonResponse | ||||
|     { | ||||
|         $ruleId = (int)$request->get('id'); | ||||
| @@ -262,10 +249,7 @@ class CreateController extends Controller | ||||
|     /** | ||||
|      * Store the new rule. | ||||
|      * | ||||
|      * @param RuleFormRequest $request | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * | ||||
|      * @return Redirector|RedirectResponse | ||||
|      */ | ||||
|     public function store(RuleFormRequest $request) | ||||
|     { | ||||
|   | ||||
| @@ -40,8 +40,6 @@ class DeleteController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * RuleController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -62,8 +60,6 @@ class DeleteController extends Controller | ||||
|     /** | ||||
|      * Delete a given rule. | ||||
|      * | ||||
|      * @param Rule $rule | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function delete(Rule $rule) | ||||
| @@ -78,10 +74,6 @@ class DeleteController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Actually destroy the given rule. | ||||
|      * | ||||
|      * @param Rule $rule | ||||
|      * | ||||
|      * @return RedirectResponse | ||||
|      */ | ||||
|     public function destroy(Rule $rule): RedirectResponse | ||||
|     { | ||||
|   | ||||
| @@ -37,7 +37,6 @@ use Illuminate\Http\RedirectResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Routing\Redirector; | ||||
| use Illuminate\View\View; | ||||
| use Throwable; | ||||
| 
 | ||||
| /** | ||||
|  * Class EditController | ||||
| @@ -51,8 +50,6 @@ class EditController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * RuleController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -73,10 +70,8 @@ class EditController extends Controller | ||||
|     /** | ||||
|      * Edit a rule. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * @param Rule    $rule | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function edit(Request $request, Rule $rule) | ||||
| @@ -120,7 +115,6 @@ class EditController extends Controller | ||||
|             'active'          => $hasOldInput ? (bool)$request->old('active') : $rule->active, | ||||
|             'stop_processing' => $hasOldInput ? (bool)$request->old('stop_processing') : $rule->stop_processing, | ||||
|             'strict'          => $hasOldInput ? (bool)$request->old('strict') : $rule->strict, | ||||
| 
 | ||||
|         ]; | ||||
| 
 | ||||
|         // get rule trigger for update / store-journal:
 | ||||
| @@ -139,9 +133,29 @@ class EditController extends Controller | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param array $submittedOperators | ||||
|      * Update the rule. | ||||
|      * | ||||
|      * @return array | ||||
|      * @return Redirector|RedirectResponse | ||||
|      */ | ||||
|     public function update(RuleFormRequest $request, Rule $rule) | ||||
|     { | ||||
|         $data = $request->getRuleData(); | ||||
| 
 | ||||
|         $this->ruleRepos->update($rule, $data); | ||||
| 
 | ||||
|         session()->flash('success', (string)trans('firefly.updated_rule', ['title' => $rule->title])); | ||||
|         app('preferences')->mark(); | ||||
|         $redirect = redirect($this->getPreviousUrl('rules.edit.url')); | ||||
|         if (1 === (int)$request->get('return_to_edit')) { | ||||
|             session()->put('rules.edit.fromUpdate', true); | ||||
| 
 | ||||
|             $redirect = redirect(route('rules.edit', [$rule->id]))->withInput(['return_to_edit' => 1]); | ||||
|         } | ||||
| 
 | ||||
|         return $redirect; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     private function parseFromOperators(array $submittedOperators): array | ||||
| @@ -170,41 +184,16 @@ class EditController extends Controller | ||||
|                         'triggers'   => $triggers, | ||||
|                     ] | ||||
|                 )->render(); | ||||
|             } catch (Throwable $e) { | ||||
|             } catch (\Throwable $e) { | ||||
|                 $message = sprintf('Throwable was thrown in getPreviousTriggers(): %s', $e->getMessage()); | ||||
|                 app('log')->debug($message); | ||||
|                 app('log')->error($e->getTraceAsString()); | ||||
| 
 | ||||
|                 throw new FireflyException($message, 0, $e); | ||||
|             } | ||||
|             $index++; | ||||
|             ++$index; | ||||
|         } | ||||
| 
 | ||||
|         return $renderedEntries; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Update the rule. | ||||
|      * | ||||
|      * @param RuleFormRequest $request | ||||
|      * @param Rule            $rule | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      */ | ||||
|     public function update(RuleFormRequest $request, Rule $rule) | ||||
|     { | ||||
|         $data = $request->getRuleData(); | ||||
| 
 | ||||
|         $this->ruleRepos->update($rule, $data); | ||||
| 
 | ||||
|         session()->flash('success', (string)trans('firefly.updated_rule', ['title' => $rule->title])); | ||||
|         app('preferences')->mark(); | ||||
|         $redirect = redirect($this->getPreviousUrl('rules.edit.url')); | ||||
|         if (1 === (int)$request->get('return_to_edit')) { | ||||
|             session()->put('rules.edit.fromUpdate', true); | ||||
| 
 | ||||
|             $redirect = redirect(route('rules.edit', [$rule->id]))->withInput(['return_to_edit' => 1]); | ||||
|         } | ||||
| 
 | ||||
|         return $redirect; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -47,8 +47,6 @@ class IndexController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * RuleController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -79,13 +77,6 @@ class IndexController extends Controller | ||||
|         return view('rules.index', compact('ruleGroups')); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Request   $request | ||||
|      * @param Rule      $rule | ||||
|      * @param RuleGroup $ruleGroup | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function moveRule(Request $request, Rule $rule, RuleGroup $ruleGroup): JsonResponse | ||||
|     { | ||||
|         $order = (int)$request->get('order'); | ||||
| @@ -94,11 +85,6 @@ class IndexController extends Controller | ||||
|         return response()->json([]); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Rule $rule | ||||
|      * | ||||
|      * @return RedirectResponse | ||||
|      */ | ||||
|     public function search(Rule $rule): RedirectResponse | ||||
|     { | ||||
|         $route = route('search.index'); | ||||
|   | ||||
| @@ -32,18 +32,15 @@ use FireflyIII\Models\Rule; | ||||
| use FireflyIII\Models\RuleTrigger; | ||||
| use FireflyIII\Support\Http\Controllers\RuleManagement; | ||||
| use FireflyIII\TransactionRules\Engine\RuleEngineInterface; | ||||
| use FireflyIII\TransactionRules\TransactionMatcher; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Contracts\View\Factory; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\RedirectResponse; | ||||
| use Illuminate\Support\Collection; | ||||
| use Illuminate\View\View; | ||||
| use Throwable; | ||||
| 
 | ||||
| /** | ||||
|  * Class SelectController. | ||||
|  * | ||||
|  */ | ||||
| class SelectController extends Controller | ||||
| { | ||||
| @@ -68,11 +65,6 @@ class SelectController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Execute the given rule on a set of existing transactions. | ||||
|      * | ||||
|      * @param SelectTransactionsRequest $request | ||||
|      * @param Rule                      $rule | ||||
|      * | ||||
|      * @return RedirectResponse | ||||
|      */ | ||||
|     public function execute(SelectTransactionsRequest $request, Rule $rule): RedirectResponse | ||||
|     { | ||||
| @@ -104,12 +96,8 @@ class SelectController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * View to select transactions by a rule. | ||||
|      * | ||||
|      * @param Rule $rule | ||||
|      * | ||||
|      * @return Factory|View|RedirectResponse | ||||
|      */ | ||||
|     public function selectTransactions(Rule $rule): Factory | View | RedirectResponse | ||||
|     public function selectTransactions(Rule $rule): Factory|RedirectResponse|View | ||||
|     { | ||||
|         if (false === $rule->active) { | ||||
|             session()->flash('warning', trans('firefly.cannot_fire_inactive_rules')); | ||||
| @@ -128,15 +116,13 @@ class SelectController extends Controller | ||||
|      * This method allows the user to test a certain set of rule triggers. The rule triggers are passed along | ||||
|      * using the URL parameters (GET), and are usually put there using a Javascript thing. | ||||
|      * | ||||
|      * @param TestRuleFormRequest $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function testTriggers(TestRuleFormRequest $request): JsonResponse | ||||
|     { | ||||
|         // build fake rule
 | ||||
|         $rule = new Rule(); | ||||
| 
 | ||||
|         /** @var \Illuminate\Database\Eloquent\Collection<int, RuleTrigger> $triggers */ | ||||
|         $triggers     = new Collection(); | ||||
|         $rule->strict = '1' === $request->get('strict'); | ||||
| @@ -180,12 +166,14 @@ class SelectController extends Controller | ||||
| 
 | ||||
|         // Return json response
 | ||||
|         $view = 'ERROR, see logs.'; | ||||
| 
 | ||||
|         try { | ||||
|             $view = view('list.journals-array-tiny', ['groups' => $collection])->render(); | ||||
|         } catch (Throwable $exception) { | ||||
|         } catch (\Throwable $exception) { | ||||
|             app('log')->error(sprintf('Could not render view in testTriggers(): %s', $exception->getMessage())); | ||||
|             app('log')->error($exception->getTraceAsString()); | ||||
|             $view = sprintf('Could not render list.journals-tiny: %s', $exception->getMessage()); | ||||
| 
 | ||||
|             throw new FireflyException($view, 0, $exception); | ||||
|         } | ||||
| 
 | ||||
| @@ -196,9 +184,6 @@ class SelectController extends Controller | ||||
|      * This method allows the user to test a certain set of rule triggers. The rule triggers are grabbed from | ||||
|      * the rule itself. | ||||
|      * | ||||
|      * @param Rule $rule | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function testTriggersByRule(Rule $rule): JsonResponse | ||||
| @@ -223,12 +208,14 @@ class SelectController extends Controller | ||||
| 
 | ||||
|         // Return json response
 | ||||
|         $view = 'ERROR, see logs.'; | ||||
| 
 | ||||
|         try { | ||||
|             $view = view('list.journals-array-tiny', ['groups' => $collection])->render(); | ||||
|         } catch (Throwable $exception) { | ||||
|         } catch (\Throwable $exception) { | ||||
|             $message = sprintf('Could not render view in testTriggersByRule(): %s', $exception->getMessage()); | ||||
|             app('log')->error($message); | ||||
|             app('log')->error($exception->getTraceAsString()); | ||||
| 
 | ||||
|             throw new FireflyException($message, 0, $exception); | ||||
|         } | ||||
| 
 | ||||
|   | ||||
| @@ -41,8 +41,6 @@ class CreateController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * CreateController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -82,9 +80,7 @@ class CreateController extends Controller | ||||
|     /** | ||||
|      * Store the rule group. | ||||
|      * | ||||
|      * @param RuleGroupFormRequest $request | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * @return Redirector|RedirectResponse | ||||
|      */ | ||||
|     public function store(RuleGroupFormRequest $request) | ||||
|     { | ||||
|   | ||||
| @@ -42,8 +42,6 @@ class DeleteController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * DeleteController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -64,8 +62,6 @@ class DeleteController extends Controller | ||||
|     /** | ||||
|      * Delete a rule group. | ||||
|      * | ||||
|      * @param RuleGroup $ruleGroup | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function delete(RuleGroup $ruleGroup) | ||||
| @@ -81,10 +77,7 @@ class DeleteController extends Controller | ||||
|     /** | ||||
|      * Actually destroy the rule group. | ||||
|      * | ||||
|      * @param Request   $request | ||||
|      * @param RuleGroup $ruleGroup | ||||
|      * | ||||
|      * @return RedirectResponse|Redirector | ||||
|      * @return Redirector|RedirectResponse | ||||
|      */ | ||||
|     public function destroy(Request $request, RuleGroup $ruleGroup) | ||||
|     { | ||||
|   | ||||
| @@ -43,8 +43,6 @@ class EditController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * EditController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -65,9 +63,6 @@ class EditController extends Controller | ||||
|     /** | ||||
|      * Edit a rule group. | ||||
|      * | ||||
|      * @param Request   $request | ||||
|      * @param RuleGroup $ruleGroup | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function edit(Request $request, RuleGroup $ruleGroup) | ||||
| @@ -90,10 +85,6 @@ class EditController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * Move a rule group in either direction. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function moveGroup(Request $request): JsonResponse | ||||
|     { | ||||
| @@ -117,16 +108,14 @@ class EditController extends Controller | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return new JsonResponse(['OK']); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Update the rule group. | ||||
|      * | ||||
|      * @param RuleGroupFormRequest $request | ||||
|      * @param RuleGroup            $ruleGroup | ||||
|      * | ||||
|      * @return $this|RedirectResponse|Redirector | ||||
|      * @return $this|Redirector|RedirectResponse | ||||
|      */ | ||||
|     public function update(RuleGroupFormRequest $request, RuleGroup $ruleGroup) | ||||
|     { | ||||
|   | ||||
| @@ -24,7 +24,6 @@ declare(strict_types=1); | ||||
| namespace FireflyIII\Http\Controllers\RuleGroup; | ||||
| 
 | ||||
| use Carbon\Carbon; | ||||
| use Exception; | ||||
| use FireflyIII\Http\Controllers\Controller; | ||||
| use FireflyIII\Http\Requests\SelectTransactionsRequest; | ||||
| use FireflyIII\Models\RuleGroup; | ||||
| @@ -44,8 +43,6 @@ class ExecutionController extends Controller | ||||
| 
 | ||||
|     /** | ||||
|      * ExecutionController constructor. | ||||
|      * | ||||
| 
 | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -66,11 +63,7 @@ class ExecutionController extends Controller | ||||
|     /** | ||||
|      * Execute the given rulegroup on a set of existing transactions. | ||||
|      * | ||||
|      * @param SelectTransactionsRequest $request | ||||
|      * @param RuleGroup                 $ruleGroup | ||||
|      * | ||||
|      * @return RedirectResponse | ||||
|      * @throws Exception | ||||
|      * @throws \Exception | ||||
|      */ | ||||
|     public function execute(SelectTransactionsRequest $request, RuleGroup $ruleGroup): RedirectResponse | ||||
|     { | ||||
| @@ -103,8 +96,6 @@ class ExecutionController extends Controller | ||||
|     /** | ||||
|      * Select transactions to apply the group on. | ||||
|      * | ||||
|      * @param RuleGroup $ruleGroup | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function selectTransactions(RuleGroup $ruleGroup) | ||||
|   | ||||
| @@ -30,7 +30,6 @@ use Illuminate\Contracts\View\Factory; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\View\View; | ||||
| use Throwable; | ||||
| 
 | ||||
| /** | ||||
|  * Class SearchController. | ||||
| @@ -57,9 +56,6 @@ class SearchController extends Controller | ||||
|     /** | ||||
|      * Do the search. | ||||
|      * | ||||
|      * @param Request         $request | ||||
|      * @param SearchInterface $searcher | ||||
|      * | ||||
|      * @return Factory|View | ||||
|      */ | ||||
|     public function index(Request $request, SearchInterface $searcher) | ||||
| @@ -98,10 +94,6 @@ class SearchController extends Controller | ||||
|     /** | ||||
|      * JSON request that does the work. | ||||
|      * | ||||
|      * @param Request         $request | ||||
|      * @param SearchInterface $searcher | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function search(Request $request, SearchInterface $searcher): JsonResponse | ||||
| @@ -120,15 +112,16 @@ class SearchController extends Controller | ||||
|         $hasPages   = $groups->hasPages(); | ||||
|         $searchTime = round($searcher->searchTime(), 3); // in seconds
 | ||||
|         $parameters = ['search' => $fullQuery]; | ||||
|         $url        = route('search.index') . '?' . http_build_query($parameters); | ||||
|         $url        = route('search.index').'?'.http_build_query($parameters); | ||||
|         $groups->setPath($url); | ||||
| 
 | ||||
|         try { | ||||
|             $html = view('search.search', compact('groups', 'hasPages', 'searchTime'))->render(); | ||||
|         } catch (Throwable $e) { | ||||
|         } catch (\Throwable $e) { | ||||
|             app('log')->error(sprintf('Cannot render search.search: %s', $e->getMessage())); | ||||
|             app('log')->error($e->getTraceAsString()); | ||||
|             $html = 'Could not render view.'; | ||||
| 
 | ||||
|             throw new FireflyException($html, 0, $e); | ||||
|         } | ||||
| 
 | ||||
|   | ||||
| @@ -33,7 +33,7 @@ use Illuminate\Http\Response; | ||||
| class CronController | ||||
| { | ||||
|     /** | ||||
|      * @return Application|ResponseFactory|Response | ||||
|      * @return Application|Response|ResponseFactory | ||||
|      */ | ||||
|     public function cron() | ||||
|     { | ||||
|   | ||||
| @@ -34,12 +34,11 @@ class HealthcheckController extends Controller | ||||
| { | ||||
|     /** | ||||
|      * Sends 'OK' info when app is alive | ||||
|      * | ||||
|      * @return Response | ||||
|      */ | ||||
|     public function check(): Response | ||||
|     { | ||||
|         User::count(); // sanity check for database health. Will crash if not OK.
 | ||||
| 
 | ||||
|         return response('OK', 200); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -23,7 +23,6 @@ declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Http\Controllers\System; | ||||
| 
 | ||||
| use Artisan; | ||||
| use Cache; | ||||
| use Exception; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| @@ -38,8 +37,6 @@ use phpseclib3\Crypt\RSA; | ||||
| 
 | ||||
| /** | ||||
|  * Class InstallController | ||||
|  * | ||||
| 
 | ||||
|  */ | ||||
| class InstallController extends Controller | ||||
| { | ||||
| @@ -90,11 +87,6 @@ class InstallController extends Controller | ||||
|         return view('install.index'); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function runCommand(Request $request): JsonResponse | ||||
|     { | ||||
|         $requestIndex = (int)$request->get('index'); | ||||
| @@ -112,6 +104,7 @@ class InstallController extends Controller | ||||
|             $command    = $indexes[$requestIndex]; | ||||
|             $parameters = $this->upgradeCommands[$command]; | ||||
|             app('log')->debug(sprintf('Will now execute command "%s" with parameters', $command), $parameters); | ||||
| 
 | ||||
|             try { | ||||
|                 $result = $this->executeCommand($command, $parameters); | ||||
|             } catch (FireflyException $e) { | ||||
| @@ -126,48 +119,21 @@ class InstallController extends Controller | ||||
|             if (false === $result) { | ||||
|                 $response['errorMessage'] = $this->lastError; | ||||
|                 $response['error']        = true; | ||||
| 
 | ||||
|                 return response()->json($response); | ||||
|             } | ||||
|             $response['hasNextCommand'] = array_key_exists($requestIndex + 1, $indexes); | ||||
|             $response['previous']       = $command; | ||||
|         } | ||||
| 
 | ||||
|         return response()->json($response); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param string $command | ||||
|      * @param array  $args | ||||
|      * | ||||
|      * @return bool | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     private function executeCommand(string $command, array $args): bool | ||||
|     { | ||||
|         app('log')->debug(sprintf('Will now call command %s with args.', $command), $args); | ||||
|         try { | ||||
|             if ('generate-keys' === $command) { | ||||
|                 $this->keys(); | ||||
|             } | ||||
|             if ('generate-keys' !== $command) { | ||||
|                 Artisan::call($command, $args); | ||||
|                 app('log')->debug(Artisan::output()); | ||||
|             } | ||||
|         } catch (Exception $e) { // intentional generic exception
 | ||||
|             throw new FireflyException($e->getMessage(), 0, $e); | ||||
|         } | ||||
|         // clear cache as well.
 | ||||
|         Cache::clear(); | ||||
|         app('preferences')->mark(); | ||||
| 
 | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Create specific RSA keys. | ||||
|      */ | ||||
|     public function keys(): void | ||||
|     { | ||||
| 
 | ||||
|         $key = RSA::createKey(4096); | ||||
| 
 | ||||
|         [$publicKey, $privateKey] = [ | ||||
| @@ -182,4 +148,29 @@ class InstallController extends Controller | ||||
|         file_put_contents($publicKey, (string)$key->getPublicKey()); | ||||
|         file_put_contents($privateKey, $key->toString('PKCS1')); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     private function executeCommand(string $command, array $args): bool | ||||
|     { | ||||
|         app('log')->debug(sprintf('Will now call command %s with args.', $command), $args); | ||||
| 
 | ||||
|         try { | ||||
|             if ('generate-keys' === $command) { | ||||
|                 $this->keys(); | ||||
|             } | ||||
|             if ('generate-keys' !== $command) { | ||||
|                 \Artisan::call($command, $args); | ||||
|                 app('log')->debug(\Artisan::output()); | ||||
|             } | ||||
|         } catch (\Exception $e) { // intentional generic exception
 | ||||
|             throw new FireflyException($e->getMessage(), 0, $e); | ||||
|         } | ||||
|         // clear cache as well.
 | ||||
|         \Cache::clear(); | ||||
|         app('preferences')->mark(); | ||||
| 
 | ||||
|         return true; | ||||
|     } | ||||
| } | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user