diff --git a/app/Generator/Chart/Account/AccountChartGeneratorInterface.php b/app/Generator/Chart/Account/AccountChartGeneratorInterface.php index 9e90645c5e..dd0c57c135 100644 --- a/app/Generator/Chart/Account/AccountChartGeneratorInterface.php +++ b/app/Generator/Chart/Account/AccountChartGeneratorInterface.php @@ -42,10 +42,10 @@ interface AccountChartGeneratorInterface /** * @param Account $account - * @param Carbon $start - * @param Carbon $end + * @param array $labels + * @param array $dataSet * * @return array */ - public function single(Account $account, Carbon $start, Carbon $end): array; + public function single(Account $account, array $labels, array $dataSet): array; } diff --git a/app/Generator/Chart/Account/ChartJsAccountChartGenerator.php b/app/Generator/Chart/Account/ChartJsAccountChartGenerator.php index 38987abec1..484a7aa517 100644 --- a/app/Generator/Chart/Account/ChartJsAccountChartGenerator.php +++ b/app/Generator/Chart/Account/ChartJsAccountChartGenerator.php @@ -29,28 +29,6 @@ class ChartJsAccountChartGenerator implements AccountChartGeneratorInterface 'labels' => [], 'datasets' => [[ 'label' => trans('firefly.spent'), 'data' => []]]]; - - $start->subDay(); - $ids = $this->getIdsFromCollection($accounts); - $startBalances = Steam::balancesById($ids, $start); - $endBalances = Steam::balancesById($ids, $end); - - $accounts->each( - function (Account $account) use ($startBalances, $endBalances) { - $id = $account->id; - $startBalance = $this->isInArray($startBalances, $id); - $endBalance = $this->isInArray($endBalances, $id); - $diff = bcsub($endBalance, $startBalance); - $account->difference = round($diff, 2); - } - ); - - $accounts = $accounts->sortByDesc( - function (Account $account) { - return $account->difference; - } - ); - foreach ($accounts as $account) { if ($account->difference > 0) { $data['labels'][] = $account->name; @@ -80,7 +58,7 @@ class ChartJsAccountChartGenerator implements AccountChartGeneratorInterface } foreach ($accounts as $account) { - $set = [ + $data['datasets'][] = [ 'label' => $account->name, 'fillColor' => 'rgba(220,220,220,0.2)', 'strokeColor' => 'rgba(220,220,220,1)', @@ -88,20 +66,8 @@ class ChartJsAccountChartGenerator implements AccountChartGeneratorInterface 'pointStrokeColor' => '#fff', 'pointHighlightFill' => '#fff', 'pointHighlightStroke' => 'rgba(220,220,220,1)', - 'data' => [], + 'data' => $account->balances, ]; - $current = clone $start; - $range = Steam::balanceInRange($account, $start, clone $end); - $previous = round(array_values($range)[0], 2); - while ($current <= $end) { - $format = $current->format('Y-m-d'); - $balance = isset($range[$format]) ? round($range[$format], 2) : $previous; - - $set['data'][] = $balance; - $previous = $balance; - $current->addDay(); - } - $data['datasets'][] = $set; } $data['count'] = count($data['datasets']); @@ -110,71 +76,27 @@ class ChartJsAccountChartGenerator implements AccountChartGeneratorInterface /** * @param Account $account - * @param Carbon $start - * @param Carbon $end + * @param array $labels + * @param array $dataSet * * @return array */ - public function single(Account $account, Carbon $start, Carbon $end): array + public function single(Account $account, array $labels, array $dataSet): array { // language: $format = (string)trans('config.month_and_day'); $data = [ 'count' => 1, - 'labels' => [], + 'labels' => $labels, 'datasets' => [ [ 'label' => $account->name, - 'data' => [], + 'data' => $dataSet, ], ], ]; - $range = Steam::balanceInRange($account, $start, $end); - $current = clone $start; - $previous = array_values($range)[0]; - - while ($end >= $current) { - $theDate = $current->format('Y-m-d'); - $balance = $range[$theDate] ?? $previous; - - $data['labels'][] = $current->formatLocalized($format); - $data['datasets'][0]['data'][] = $balance; - $previous = $balance; - $current->addDay(); - } - return $data; } - /** - * @param Collection $collection - * - * @return array - */ - protected function getIdsFromCollection(Collection $collection): array - { - $ids = []; - foreach ($collection as $entry) { - $ids[] = $entry->id; - } - - return array_unique($ids); - - } - - /** - * @param $array - * @param $entryId - * - * @return string - */ - protected function isInArray($array, $entryId): string - { - if (isset($array[$entryId])) { - return $array[$entryId]; - } - - return '0'; - } } diff --git a/app/Http/Controllers/Chart/AccountController.php b/app/Http/Controllers/Chart/AccountController.php index e0689b1754..d06193e5ea 100644 --- a/app/Http/Controllers/Chart/AccountController.php +++ b/app/Http/Controllers/Chart/AccountController.php @@ -7,8 +7,13 @@ use Carbon\Carbon; use FireflyIII\Generator\Chart\Account\AccountChartGeneratorInterface; use FireflyIII\Http\Controllers\Controller; use FireflyIII\Models\Account; +use FireflyIII\Models\AccountType; use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI; +use FireflyIII\Support\CacheProperties; use Illuminate\Support\Collection; +use Preferences; +use Response; +use Steam; /** checked * Class AccountController @@ -40,26 +45,44 @@ class AccountController extends Controller */ public function expenseAccounts(ARI $repository) { - /* - $start = clone session('start', Carbon::now()->startOfMonth()); - $end = clone session('end', Carbon::now()->endOfMonth()); - $accounts = $repository->getAccounts(['Expense account', 'Beneficiary account']); - - // chart properties for cache: - $cache = new CacheProperties(); + $start = clone session('start', Carbon::now()->startOfMonth()); + $end = clone session('end', Carbon::now()->endOfMonth()); + $cache = new CacheProperties; $cache->addProperty($start); $cache->addProperty($end); $cache->addProperty('expenseAccounts'); $cache->addProperty('accounts'); if ($cache->has()) { - return Response::json($cache->get()); + // return Response::json($cache->get()); } + $accounts = $repository->getAccountsByType(['Expense account', 'Beneficiary account']); + + $start->subDay(); + $ids = $accounts->pluck('id')->toArray(); + $startBalances = Steam::balancesById($ids, $start); + $endBalances = Steam::balancesById($ids, $end); + + $accounts->each( + function (Account $account) use ($startBalances, $endBalances) { + $id = $account->id; + $startBalance = $startBalances[$id] ?? '0'; + $endBalance = $endBalances[$id] ?? '0'; + $diff = bcsub($endBalance, $startBalance); + $account->difference = round($diff, 2); + } + ); + + + $accounts = $accounts->sortByDesc( + function (Account $account) { + return $account->difference; + } + ); $data = $this->generator->expenseAccounts($accounts, $start, $end); $cache->store($data); return Response::json($data); -*/ } /** @@ -71,42 +94,54 @@ class AccountController extends Controller */ public function frontpage(ARI $repository) { - /* - $frontPage = Preferences::get('frontPageAccounts', []); - $start = clone session('start', Carbon::now()->startOfMonth()); - $end = clone session('end', Carbon::now()->endOfMonth()); - $accounts = $repository->getFrontpageAccounts($frontPage); + $start = clone session('start', Carbon::now()->startOfMonth()); + $end = clone session('end', Carbon::now()->endOfMonth()); + // chart properties for cache: - $cache = new CacheProperties(); + $cache = new CacheProperties; $cache->addProperty($start); $cache->addProperty($end); $cache->addProperty('frontpage'); $cache->addProperty('accounts'); if ($cache->has()) { - return Response::json($cache->get()); + // return Response::json($cache->get()); } + $frontPage = Preferences::get('frontPageAccounts', $repository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET])->pluck('id')->toArray()); + $accounts = $repository->getAccountsById($frontPage->data); + + foreach ($accounts as $account) { + $balances = []; + $current = clone $start; + $range = Steam::balanceInRange($account, $start, clone $end); + $previous = round(array_values($range)[0], 2); + while ($current <= $end) { + $format = $current->format('Y-m-d'); + $balance = isset($range[$format]) ? round($range[$format], 2) : $previous; + $previous = $balance; + $balances[] = $balance; + $current->addDay(); + } + $account->balances = $balances; + } $data = $this->generator->frontpage($accounts, $start, $end); $cache->store($data); return Response::json($data); -*/ } /** * Shows the balances for a given set of dates and accounts. * - * @param $reportType * @param Carbon $start * @param Carbon $end * @param Collection $accounts * * @return \Illuminate\Http\JsonResponse */ - public function report(string $reportType, Carbon $start, Carbon $end, Collection $accounts) + public function report(Carbon $start, Carbon $end, Collection $accounts) { - /* // chart properties for cache: $cache = new CacheProperties(); $cache->addProperty($start); @@ -114,10 +149,24 @@ class AccountController extends Controller $cache->addProperty('all'); $cache->addProperty('accounts'); $cache->addProperty('default'); - $cache->addProperty($reportType); $cache->addProperty($accounts); if ($cache->has()) { - return Response::json($cache->get()); + // return Response::json($cache->get()); + } + + foreach ($accounts as $account) { + $balances = []; + $current = clone $start; + $range = Steam::balanceInRange($account, $start, clone $end); + $previous = round(array_values($range)[0], 2); + while ($current <= $end) { + $format = $current->format('Y-m-d'); + $balance = isset($range[$format]) ? round($range[$format], 2) : $previous; + $previous = $balance; + $balances[] = $balance; + $current->addDay(); + } + $account->balances = $balances; } // make chart: @@ -125,7 +174,6 @@ class AccountController extends Controller $cache->store($data); return Response::json($data); - */ } /** @@ -137,8 +185,6 @@ class AccountController extends Controller */ public function single(Account $account) { - /* - $start = clone session('start', Carbon::now()->startOfMonth()); $end = clone session('end', Carbon::now()->endOfMonth()); @@ -150,13 +196,31 @@ class AccountController extends Controller $cache->addProperty('single'); $cache->addProperty($account->id); if ($cache->has()) { - return Response::json($cache->get()); + // return Response::json($cache->get()); } - $data = $this->generator->single($account, $start, $end); + $format = (string)trans('config.month_and_day'); + $range = Steam::balanceInRange($account, $start, $end); + $current = clone $start; + $previous = array_values($range)[0]; + $labels = []; + $chartData = []; + + while ($end >= $current) { + $theDate = $current->format('Y-m-d'); + $balance = $range[$theDate] ?? $previous; + + $labels[] = $current->formatLocalized($format); + $chartData[] = $balance; + $previous = $balance; + $current->addDay(); + } + + + $data = $this->generator->single($account, $labels, $chartData); $cache->store($data); return Response::json($data); - */ } + } diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index 67a44d0142..51577790b9 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -1,9 +1,9 @@ getAccountsByType([AccountType::DEFAULT, AccountType::ASSET])->pluck('id')->toArray() + ); /** @var Carbon $start */ $start = session('start', Carbon::now()->startOfMonth()); /** @var Carbon $end */ $end = session('end', Carbon::now()->endOfMonth()); $showTour = Preferences::get('tour', true)->data; $accounts = $repository->getAccountsById($frontPage->data); - $savings = $repository->getSavingsAccounts(); - $piggyBankAccounts = $repository->getPiggyBankAccounts(); + $savings = $repository->getSavingsAccounts($start, $end); + $piggyBankAccounts = $repository->getPiggyBankAccounts($start, $end); $savingsTotal = 0; diff --git a/app/Http/routes.php b/app/Http/routes.php index ed96303917..1555574eb9 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -191,7 +191,7 @@ Route::group( // accounts: Route::get('/chart/account/frontpage', ['uses' => 'Chart\AccountController@frontpage']); Route::get('/chart/account/expense', ['uses' => 'Chart\AccountController@expenseAccounts']); - Route::get('/chart/account/report/{reportType}/{start_date}/{end_date}/{accountList}', ['uses' => 'Chart\AccountController@report']); + Route::get('/chart/account/report/default/{start_date}/{end_date}/{accountList}', ['uses' => 'Chart\AccountController@report']); Route::get('/chart/account/{account}', ['uses' => 'Chart\AccountController@single']); diff --git a/app/Repositories/Account/AccountRepository.php b/app/Repositories/Account/AccountRepository.php index 6be17384db..ec420ba87f 100644 --- a/app/Repositories/Account/AccountRepository.php +++ b/app/Repositories/Account/AccountRepository.php @@ -216,9 +216,12 @@ class AccountRepository implements AccountRepositoryInterface /** * Get the accounts of a user that have piggy banks connected to them. * + * @param Carbon $start + * @param Carbon $end + * * @return Collection */ - public function getPiggyBankAccounts(): Collection + public function getPiggyBankAccounts(Carbon $start, Carbon $end): Collection { $collection = new Collection(DB::table('piggy_banks')->distinct()->get(['piggy_banks.account_id'])); $accountIds = $collection->pluck('account_id')->toArray(); @@ -228,16 +231,39 @@ class AccountRepository implements AccountRepositoryInterface $accounts = $this->user->accounts()->whereIn('id', $accountIds)->where('accounts.active', 1)->get(); } + $accounts->each( + function (Account $account) use ($start, $end) { + $account->startBalance = Steam::balanceIgnoreVirtual($account, $start); + $account->endBalance = Steam::balanceIgnoreVirtual($account, $end); + $account->piggyBalance = 0; + /** @var PiggyBank $piggyBank */ + foreach ($account->piggyBanks as $piggyBank) { + $account->piggyBalance += $piggyBank->currentRelevantRep()->currentamount; + } + // sum of piggy bank amounts on this account: + // diff between endBalance and piggyBalance. + // then, percentage. + $difference = bcsub($account->endBalance, $account->piggyBalance); + $account->difference = $difference; + $account->percentage = $difference != 0 && $account->endBalance != 0 ? round((($difference / $account->endBalance) * 100)) : 100; + + } + ); + + return $accounts; } /** - * Get savings accounts and the balance difference in the period. + * Get savings accounts. + * + * @param Carbon $start + * @param Carbon $end * * @return Collection */ - public function getSavingsAccounts(): Collection + public function getSavingsAccounts(Carbon $start, Carbon $end): Collection { $accounts = $this->user->accounts()->accountTypeIn(['Default account', 'Asset account'])->orderBy('accounts.name', 'ASC') ->leftJoin('account_meta', 'account_meta.account_id', '=', 'accounts.id') @@ -246,6 +272,32 @@ class AccountRepository implements AccountRepositoryInterface ->where('account_meta.data', '"savingAsset"') ->get(['accounts.*']); + $accounts->each( + function (Account $account) use ($start, $end) { + $account->startBalance = Steam::balance($account, $start); + $account->endBalance = Steam::balance($account, $end); + + // diff (negative when lost, positive when gained) + $diff = bcsub($account->endBalance, $account->startBalance); + + if ($diff < 0 && $account->startBalance > 0) { + // percentage lost compared to start. + $pct = (($diff * -1) / $account->startBalance) * 100; + } else { + if ($diff >= 0 && $account->startBalance > 0) { + $pct = ($diff / $account->startBalance) * 100; + } else { + $pct = 100; + } + } + $pct = $pct > 100 ? 100 : $pct; + $account->difference = $diff; + $account->percentage = round($pct); + + } + ); + + return $accounts; } diff --git a/app/Repositories/Account/AccountRepositoryInterface.php b/app/Repositories/Account/AccountRepositoryInterface.php index 3f48ae943e..4949bed888 100644 --- a/app/Repositories/Account/AccountRepositoryInterface.php +++ b/app/Repositories/Account/AccountRepositoryInterface.php @@ -91,16 +91,22 @@ interface AccountRepositoryInterface /** * Get the accounts of a user that have piggy banks connected to them. * - * @return Collection - */ - public function getPiggyBankAccounts(): Collection; - - /** - * Get savings accounts and the balance difference in the period. + * @param Carbon $start + * @param Carbon $end * * @return Collection */ - public function getSavingsAccounts() : Collection; + public function getPiggyBankAccounts(Carbon $start, Carbon $end): Collection; + + /** + * Get savings accounts. + * + * @param Carbon $start + * @param Carbon $end + * + * @return Collection + */ + public function getSavingsAccounts(Carbon $start, Carbon $end): Collection; /** * @param Collection $accounts