From d75614e9a7e9c9864863ebb4bcb50ffe9502e0fe Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 30 Dec 2015 16:42:09 +0100 Subject: [PATCH] Optimised two charts, cleaned up some code. --- .../Controllers/Chart/CategoryController.php | 26 +-- .../Category/CategoryRepositoryInterface.php | 24 +-- .../Category/SingleCategoryRepository.php | 151 +++++++----------- .../SingleCategoryRepositoryInterface.php | 53 +++--- 4 files changed, 111 insertions(+), 143 deletions(-) diff --git a/app/Http/Controllers/Chart/CategoryController.php b/app/Http/Controllers/Chart/CategoryController.php index eb69f95549..bc37dc0517 100644 --- a/app/Http/Controllers/Chart/CategoryController.php +++ b/app/Http/Controllers/Chart/CategoryController.php @@ -244,16 +244,21 @@ class CategoryController extends Controller $cache->addProperty($end); $cache->addProperty($category->id); $cache->addProperty('category'); - $cache->addProperty('currentPeriod'); + $cache->addProperty('current-period'); if ($cache->has()) { return Response::json($cache->get()); // @codeCoverageIgnore } $entries = new Collection; + // get amount earned in period, grouped by day. + $spentArray = $repository->spentPerDay($category, $start, $end); + $earnedArray = $repository->earnedPerDay($category, $start, $end); + // get amount spent in period, grouped by day. while ($start <= $end) { - $spent = $repository->spentOnDaySum($category, $start); - $earned = $repository->earnedOnDaySum($category, $start); + $str = $start->format('Y-m-d'); + $spent = isset($spentArray[$str]) ? $spentArray[$str] : 0; + $earned = isset($earnedArray[$str]) ? $earnedArray[$str] : 0; $date = Navigation::periodShow($start, '1D'); $entries->push([clone $start, $date, $spent, $earned]); $start->addDay(); @@ -263,8 +268,6 @@ class CategoryController extends Controller $cache->store($data); return Response::json($data); - - } /** @@ -295,12 +298,17 @@ class CategoryController extends Controller } $entries = new Collection; + // get amount earned in period, grouped by day. + $spentArray = $repository->spentPerDay($category, $start, $end); + $earnedArray = $repository->earnedPerDay($category, $start, $end); + // get amount spent in period, grouped by day. while ($start <= $end) { - $spent = $repository->spentOnDaySum($category, $start); - $earned = $repository->earnedOnDaySum($category, $start); - $theDate = Navigation::periodShow($start, '1D'); - $entries->push([clone $start, $theDate, $spent, $earned]); + $str = $start->format('Y-m-d'); + $spent = isset($spentArray[$str]) ? $spentArray[$str] : 0; + $earned = isset($earnedArray[$str]) ? $earnedArray[$str] : 0; + $date = Navigation::periodShow($start, '1D'); + $entries->push([clone $start, $date, $spent, $earned]); $start->addDay(); } diff --git a/app/Repositories/Category/CategoryRepositoryInterface.php b/app/Repositories/Category/CategoryRepositoryInterface.php index 47bba21750..dd96800255 100644 --- a/app/Repositories/Category/CategoryRepositoryInterface.php +++ b/app/Repositories/Category/CategoryRepositoryInterface.php @@ -84,18 +84,6 @@ interface CategoryRepositoryInterface */ public function spentForAccountsPerMonth(Collection $accounts, Carbon $start, Carbon $end); - /** - * Returns the total amount of money related to transactions without any category connected to - * it. Returns either the spent amount. - * - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end - * - * @return string - */ - public function sumSpentNoCategory(Collection $accounts, Carbon $start, Carbon $end); - /** * Returns the total amount of money related to transactions without any category connected to * it. Returns either the earned amount. @@ -108,4 +96,16 @@ interface CategoryRepositoryInterface */ public function sumEarnedNoCategory(Collection $accounts, Carbon $start, Carbon $end); + /** + * Returns the total amount of money related to transactions without any category connected to + * it. Returns either the spent amount. + * + * @param Collection $accounts + * @param Carbon $start + * @param Carbon $end + * + * @return string + */ + public function sumSpentNoCategory(Collection $accounts, Carbon $start, Carbon $end); + } diff --git a/app/Repositories/Category/SingleCategoryRepository.php b/app/Repositories/Category/SingleCategoryRepository.php index ada1aa5bf6..eca6aafec8 100644 --- a/app/Repositories/Category/SingleCategoryRepository.php +++ b/app/Repositories/Category/SingleCategoryRepository.php @@ -2,12 +2,13 @@ namespace FireflyIII\Repositories\Category; +use Auth; use Carbon\Carbon; +use DB; use FireflyIII\Models\Category; use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionType; use FireflyIII\Repositories\Shared\ComponentRepository; -use FireflyIII\Support\CacheProperties; use Illuminate\Support\Collection; /** @@ -69,6 +70,10 @@ class SingleCategoryRepository extends ComponentRepository implements SingleCate } /** + * TODO this method is not optimal, and should be replaced. + * + * @deprecated + * * @param Category $category * @param \Carbon\Carbon $start * @param \Carbon\Carbon $end @@ -77,67 +82,47 @@ class SingleCategoryRepository extends ComponentRepository implements SingleCate */ public function earnedInPeriod(Category $category, Carbon $start, Carbon $end) { - $cache = new CacheProperties; // we must cache this. - $cache->addProperty($category->id); - $cache->addProperty($start); - $cache->addProperty($end); - $cache->addProperty('earnedInPeriod'); - - if ($cache->has()) { - return $cache->get(); // @codeCoverageIgnore - } - $sum = $category->transactionjournals()->transactionTypes([TransactionType::DEPOSIT])->before($end)->after($start)->get(['transaction_journals.*']) ->sum( 'amount' ); - $cache->store($sum); - return $sum; } - /** - * Calculate how much is earned in this period. + * Returns an array with the following key:value pairs: * - * @param Category $category - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * yyyy-mm-dd: * - * @return string - */ - public function earnedInPeriodForAccounts(Category $category, Collection $accounts, Carbon $start, Carbon $end) - { - $accountIds = $accounts->pluck('id')->toArray(); - $sum - = $category - ->transactionjournals() - ->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') - ->before($end) - ->whereIn('transactions.account_id', $accountIds) - ->transactionTypes([TransactionType::DEPOSIT]) - ->after($start) - ->get(['transaction_journals.*']) - ->sum('amount'); - - return $sum; - - } - - /** - * - * Corrected for tags. + * Where yyyy-mm-dd is the date and is the money earned using DEPOSITS in the $category + * from all the users $accounts. * * @param Category $category - * @param Carbon $date + * @param Carbon $start + * @param Carbon $end * - * @return float + * @return array */ - public function earnedOnDaySum(Category $category, Carbon $date) + public function earnedPerDay(Category $category, Carbon $start, Carbon $end) { - return $category->transactionjournals()->transactionTypes([TransactionType::DEPOSIT])->onDate($date)->get(['transaction_journals.*'])->sum('amount'); + /** @var Collection $query */ + $query = Auth::user()->transactionJournals() + ->transactionTypes([TransactionType::DEPOSIT]) + ->leftJoin('category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id') + ->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') + ->where('transactions.amount', '>', 0) + ->before($end) + ->after($start) + ->where('category_transaction_journal.category_id', $category->id) + ->groupBy('date')->get(['transaction_journals.date as dateFormatted', DB::Raw('SUM(`transactions`.`amount`) AS `sum`')]); + + $return = []; + foreach ($query->toArray() as $entry) { + $return[$entry['dateFormatted']] = $entry['sum']; + } + + return $return; } /** @@ -221,37 +206,11 @@ class SingleCategoryRepository extends ComponentRepository implements SingleCate return null; } - /** - * Calculates how much is spent in this period. + * TODO this method is not optimal, and should be replaced. * - * @param Category $category - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * @deprecated * - * @return string - */ - public function spentInPeriodForAccounts(Category $category, Collection $accounts, Carbon $start, Carbon $end) - { - $accountIds = $accounts->pluck('id')->toArray(); - - $sum - = $category - ->transactionjournals() - ->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') - ->after($start) - ->before($end) - ->whereIn('transactions.account_id', $accountIds) - ->transactionTypes([TransactionType::WITHDRAWAL]) - ->get(['transaction_journals.*']) - ->sum('amount'); - - return $sum; - - } - - /** * @param Category $category * @param \Carbon\Carbon $start * @param \Carbon\Carbon $end @@ -260,38 +219,48 @@ class SingleCategoryRepository extends ComponentRepository implements SingleCate */ public function spentInPeriod(Category $category, Carbon $start, Carbon $end) { - $cache = new CacheProperties; // we must cache this. - $cache->addProperty($category->id); - $cache->addProperty($start); - $cache->addProperty($end); - $cache->addProperty('spentInPeriod'); - - if ($cache->has()) { - return $cache->get(); // @codeCoverageIgnore - } - $sum = $category->transactionjournals()->transactionTypes([TransactionType::WITHDRAWAL])->before($end)->after($start)->get(['transaction_journals.*']) ->sum( 'amount' ); - $cache->store($sum); - return $sum; } /** - * Corrected for tags + * Returns an array with the following key:value pairs: + * + * yyyy-mm-dd: + * + * Where yyyy-mm-dd is the date and is the money spent using DEPOSITS in the $category + * from all the users accounts. * * @param Category $category - * @param Carbon $date + * @param Carbon $start + * @param Carbon $end * - * @return string + * @return array */ - public function spentOnDaySum(Category $category, Carbon $date) + public function spentPerDay(Category $category, Carbon $start, Carbon $end) { - return $category->transactionjournals()->transactionTypes([TransactionType::WITHDRAWAL])->onDate($date)->get(['transaction_journals.*'])->sum('amount'); + /** @var Collection $query */ + $query = Auth::user()->transactionJournals() + ->transactionTypes([TransactionType::WITHDRAWAL]) + ->leftJoin('category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id') + ->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') + ->where('transactions.amount', '<', 0) + ->before($end) + ->after($start) + ->where('category_transaction_journal.category_id', $category->id) + ->groupBy('date')->get(['transaction_journals.date as dateFormatted', DB::Raw('SUM(`transactions`.`amount`) AS `sum`')]); + + $return = []; + foreach ($query->toArray() as $entry) { + $return[$entry['dateFormatted']] = $entry['sum']; + } + + return $return; } /** diff --git a/app/Repositories/Category/SingleCategoryRepositoryInterface.php b/app/Repositories/Category/SingleCategoryRepositoryInterface.php index 4c5a4ffa2a..d2e233da30 100644 --- a/app/Repositories/Category/SingleCategoryRepositoryInterface.php +++ b/app/Repositories/Category/SingleCategoryRepositoryInterface.php @@ -50,6 +50,8 @@ interface SingleCategoryRepositoryInterface public function destroy(Category $category); /** + * @deprecated + * * @param Category $category * @param \Carbon\Carbon $start * @param \Carbon\Carbon $end @@ -58,29 +60,22 @@ interface SingleCategoryRepositoryInterface */ public function earnedInPeriod(Category $category, Carbon $start, Carbon $end); - /** - * Calculate how much is earned in this period. + * Returns an array with the following key:value pairs: * - * @param Category $category - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * yyyy-mm-dd: * - * @return string - */ - public function earnedInPeriodForAccounts(Category $category, Collection $accounts, Carbon $start, Carbon $end); - - /** - * - * Corrected for tags. + * Where yyyy-mm-dd is the date and is the money earned using DEPOSITS in the $category + * from all the users accounts. * * @param Category $category - * @param Carbon $date + * @param Carbon $start + * @param Carbon $end * - * @return float + * @return array */ - public function earnedOnDaySum(Category $category, Carbon $date); + public function earnedPerDay(Category $category, Carbon $start, Carbon $end); + /** * @param Category $category @@ -117,6 +112,8 @@ interface SingleCategoryRepositoryInterface public function getLatestActivity(Category $category); /** + * @deprecated + * * @param Category $category * @param \Carbon\Carbon $start * @param \Carbon\Carbon $end @@ -126,27 +123,21 @@ interface SingleCategoryRepositoryInterface public function spentInPeriod(Category $category, Carbon $start, Carbon $end); /** - * Calculates how much is spent in this period. + * Returns an array with the following key:value pairs: * - * @param Category $category - * @param Collection $accounts - * @param Carbon $start - * @param Carbon $end + * yyyy-mm-dd: * - * @return string - */ - public function spentInPeriodForAccounts(Category $category, Collection $accounts, Carbon $start, Carbon $end); - - /** - * - * Corrected for tags. + * Where yyyy-mm-dd is the date and is the money spent using WITHDRAWALS in the $category + * from all the users accounts. * * @param Category $category - * @param Carbon $date + * @param Carbon $start + * @param Carbon $end * - * @return float + * @return array */ - public function spentOnDaySum(Category $category, Carbon $date); + public function spentPerDay(Category $category, Carbon $start, Carbon $end); + /** * @param array $data