/** * Returns a chart of what has been earned in this period in each category * grouped by month. * * @param CRI $repository * @param $reportType * @param Carbon $start * @param Carbon $end * @param Collection $accounts * * @return \Illuminate\Http\JsonResponse */ public function earnedInPeriod(CRI $repository, $reportType, Carbon $start, Carbon $end, Collection $accounts) { $cache = new CacheProperties(); // chart properties for cache: $cache->addProperty($start); $cache->addProperty($end); $cache->addProperty($reportType); $cache->addProperty($accounts); $cache->addProperty('category'); $cache->addProperty('earned-in-period'); if ($cache->has()) { return Response::json($cache->get()); // @codeCoverageIgnore } $set = $repository->earnedForAccountsPerMonth($accounts, $start, $end); $categories = $set->unique('id')->sortBy(function (Category $category) { return $category->name; }); $entries = new Collection(); while ($start < $end) { // filter the set: $row = [clone $start]; // get possibly relevant entries from the big $set $currentSet = $set->filter(function (Category $category) use($start) { return $category->dateFormatted == $start->format("Y-m"); }); // check for each category if its in the current set. /** @var Category $category */ foreach ($categories as $category) { // if its in there, use the value. $entry = $currentSet->filter(function (Category $cat) use($category) { return $cat->id == $category->id; })->first(); if (!is_null($entry)) { $row[] = round($entry->earned, 2); } else { $row[] = 0; } } $entries->push($row); $start->addMonth(); } $data = $this->generator->earnedInPeriod($categories, $entries); $cache->store($data); return $data; }
/** * Returns a chart of what has been earned in this period in each category * grouped by month. * * @param CategoryRepositoryInterface $repository * @param $report_type * @param Carbon $start * @param Carbon $end * @param Collection $accounts * * @return \Illuminate\Http\JsonResponse */ public function earnedInPeriod(CategoryRepositoryInterface $repository, $report_type, Carbon $start, Carbon $end, Collection $accounts) { $original = clone $start; $cache = new CacheProperties(); // chart properties for cache: $cache->addProperty($start); $cache->addProperty($end); $cache->addProperty($report_type); $cache->addProperty($accounts); $cache->addProperty('category'); $cache->addProperty('earned-in-period'); if ($cache->has()) { return Response::json($cache->get()); // @codeCoverageIgnore } $categories = new Collection(); $sets = new Collection(); $entries = new Collection(); // run a very special query each month: $start = clone $original; while ($start < $end) { $currentEnd = clone $start; $currentStart = clone $start; $currentStart->startOfMonth(); $currentEnd->endOfMonth(); // get a list of categories, and what the user has earned for that category // (if the user has earned anything) $set = $repository->earnedForAccounts($accounts, $currentStart, $currentEnd); $categories = $categories->merge($set); // save the set combined with the data that is in it: // for example: // december 2015, salary:1000, bonus:200 $sets->push([$currentStart, $set]); $start->addMonth(); } // filter categories into a single bunch. Useful later on. // $categories contains all the categories the user has earned money // in in this period. $categories = $categories->unique('id'); $categories = $categories->sortBy(function (Category $category) { return $category->name; }); // start looping the time again, this time processing the // data for each month. $start = clone $original; while ($start < $end) { $currentEnd = clone $start; $currentStart = clone $start; $currentStart->startOfMonth(); $currentEnd->endOfMonth(); // in $sets we have saved all the sets of data for each month // so now we need to retrieve the corrent one. // match is on date of course. $currentSet = $sets->first(function ($key, $value) use($currentStart) { // set for this date. return $value[0] == $currentStart; }); // create a row used later on. $row = [clone $currentStart]; // loop all categories: /** @var Category $category */ foreach ($categories as $category) { // if entry is not null, we've earned money in this period for this category. $entry = $currentSet[1]->first(function ($key, $value) use($category) { return $value->id == $category->id; }); // save amount if (!is_null($entry)) { $row[] = $entry->earned; } else { $row[] = 0; } } $entries->push($row); $start->addMonth(); } $data = $this->generator->earnedInPeriod($categories, $entries); $cache->store($data); return $data; }