From 45293fbd427beb95e47f612f002e324800dcc16c Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 25 Sep 2015 16:00:14 +0200 Subject: [PATCH] Fixes for #109. --- .../ChartJsCategoryChartGenerator.php | 13 ++-- app/Http/Controllers/CategoryController.php | 65 +++++++++++++++- .../Controllers/Chart/CategoryController.php | 1 - app/Http/routes.php | 1 + .../Category/CategoryRepository.php | 34 ++++++++- .../Category/CategoryRepositoryInterface.php | 15 ++++ app/Support/Navigation.php | 7 +- resources/twig/categories/show.twig | 29 ++++++- resources/twig/categories/show_with_date.twig | 75 +++++++++++++++++++ resources/twig/emails/registered-html.twig | 2 +- resources/twig/emails/registered.twig | 2 +- 11 files changed, 228 insertions(+), 16 deletions(-) create mode 100644 resources/twig/categories/show_with_date.twig diff --git a/app/Generator/Chart/Category/ChartJsCategoryChartGenerator.php b/app/Generator/Chart/Category/ChartJsCategoryChartGenerator.php index 621a51ee13..196a5ecd2f 100644 --- a/app/Generator/Chart/Category/ChartJsCategoryChartGenerator.php +++ b/app/Generator/Chart/Category/ChartJsCategoryChartGenerator.php @@ -45,14 +45,11 @@ class ChartJsCategoryChartGenerator implements CategoryChartGenerator foreach ($entries as $entry) { $data['labels'][] = $entry[0]->formatLocalized($format); - $amount = round($entry[1], 2); - if ($amount > 0) { - $data['datasets'][0]['data'][] = null; - $data['datasets'][1]['data'][] = $amount; - } else { - $data['datasets'][0]['data'][] = $amount * -1; - $data['datasets'][1]['data'][] = null; - } + $spent = round($entry[1], 2); + $earned = round($entry[2], 2); + + $data['datasets'][0]['data'][] = $spent == 0 ? null : $spent; + $data['datasets'][1]['data'][] = $earned == 0 ? null : $earned; } return $data; diff --git a/app/Http/Controllers/CategoryController.php b/app/Http/Controllers/CategoryController.php index 7580f30a78..10725adce6 100644 --- a/app/Http/Controllers/CategoryController.php +++ b/app/Http/Controllers/CategoryController.php @@ -5,8 +5,11 @@ use Carbon\Carbon; use FireflyIII\Http\Requests\CategoryFormRequest; use FireflyIII\Models\Category; use FireflyIII\Repositories\Category\CategoryRepositoryInterface; +use FireflyIII\Support\CacheProperties; use Illuminate\Pagination\LengthAwarePaginator; +use Illuminate\Support\Collection; use Input; +use Navigation; use Preferences; use Session; use URL; @@ -139,6 +142,30 @@ class CategoryController extends Controller return view('categories.noCategory', compact('list', 'subTitle')); } + /** + * @param CategoryRepositoryInterface $repository + * @param Category $category + * + * @return \Illuminate\View\View + */ + public function showWithDate(CategoryRepositoryInterface $repository, Category $category, $date) + { + $carbon = new Carbon($date); + $range = Preferences::get('viewRange', '1M')->data; + $start = Navigation::startOfPeriod($carbon, $range); + $end = Navigation::endOfPeriod($carbon, $range); + + $hideCategory = true; // used in list. + $page = intval(Input::get('page')); + + $set = $repository->getJournalsInRange($category, $page, $start, $end); + $count = $repository->countJournalsInRange($category, $start, $end); + $journals = new LengthAwarePaginator($set, $count, 50, $page); + $journals->setPath('categories/show/' . $category->id . '/' . $date); + + return view('categories.show_with_date', compact('category', 'journals', 'hideCategory')); + } + /** * @param CategoryRepositoryInterface $repository * @param Category $category @@ -156,7 +183,43 @@ class CategoryController extends Controller $journals = new LengthAwarePaginator($set, $count, 50, $page); $journals->setPath('categories/show/' . $category->id); - return view('categories.show', compact('category', 'journals', 'hideCategory', 'totalSum', 'periodSum')); + // list of ranges for list of periods: + + // oldest transaction in category: + $start = $repository->getFirstActivityDate($category); + $range = Preferences::get('viewRange', '1M')->data; + $start = Navigation::startOfPeriod($start, $range); + $end = Navigation::endOfX(new Carbon, $range); + $entries = new Collection; + + // chart properties for cache: + $cache = new CacheProperties(); + $cache->addProperty($start); + $cache->addProperty($end); + $cache->addProperty('category-show'); + $cache->addProperty($category->id); + if ($cache->has()) { + $entries = $cache->get(); + } else { + + while ($end >= $start) { + $end = Navigation::startOfPeriod($end, $range); + $currentEnd = Navigation::endOfPeriod($end, $range); + + // here do something. + $spent = $repository->spentInPeriod($category, $end, $currentEnd); + $earned = $repository->earnedInPeriod($category, $end, $currentEnd); + $dateStr = $end->format('Y-m-d'); + $dateName = Navigation::periodShow($end, $range); + $entries->push([$dateStr, $dateName, $spent, $earned]); + + $end = Navigation::subtractPeriod($end, $range, 1); + + } + $cache->store($entries); + } + + return view('categories.show', compact('category', 'journals', 'entries', 'hideCategory', 'totalSum', 'periodSum')); } /** diff --git a/app/Http/Controllers/Chart/CategoryController.php b/app/Http/Controllers/Chart/CategoryController.php index f7d735aef6..374072ea6a 100644 --- a/app/Http/Controllers/Chart/CategoryController.php +++ b/app/Http/Controllers/Chart/CategoryController.php @@ -69,7 +69,6 @@ class CategoryController extends Controller $earned = $repository->earnedInPeriod($category, $start, $currentEnd); $entries->push([clone $start, $spent, $earned]); $start = Navigation::addPeriod($start, $range, 0); - } $data = $this->generator->all($entries); diff --git a/app/Http/routes.php b/app/Http/routes.php index 0471e559b9..cd1a57bd18 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -244,6 +244,7 @@ Route::group( Route::get('/categories/edit/{category}', ['uses' => 'CategoryController@edit', 'as' => 'categories.edit']); Route::get('/categories/delete/{category}', ['uses' => 'CategoryController@delete', 'as' => 'categories.delete']); Route::get('/categories/show/{category}', ['uses' => 'CategoryController@show', 'as' => 'categories.show']); + Route::get('/categories/show/{category}/{date}', ['uses' => 'CategoryController@showWithDate', 'as' => 'categories.show.date']); Route::get('/categories/list/noCategory', ['uses' => 'CategoryController@noCategory', 'as' => 'categories.noCategory']); Route::post('/categories/store', ['uses' => 'CategoryController@store', 'as' => 'categories.store']); Route::post('/categories/update/{category}', ['uses' => 'CategoryController@update', 'as' => 'categories.update']); diff --git a/app/Repositories/Category/CategoryRepository.php b/app/Repositories/Category/CategoryRepository.php index a1825a049c..c0e838c50d 100644 --- a/app/Repositories/Category/CategoryRepository.php +++ b/app/Repositories/Category/CategoryRepository.php @@ -309,7 +309,7 @@ class CategoryRepository extends ComponentRepository implements CategoryReposito $cache->addProperty($category->id); $cache->addProperty($start); $cache->addProperty($end); - $cache->addProperty('spentInPeriod'); + $cache->addProperty('earnedInPeriod'); if ($cache->has()) { return $cache->get(); // @codeCoverageIgnore @@ -323,4 +323,36 @@ class CategoryRepository extends ComponentRepository implements CategoryReposito return $sum; } + + /** + * @param Category $category + * @param int $page + * + * @return Collection + */ + public function getJournalsInRange(Category $category, $page, Carbon $start, Carbon $end) + { + $offset = $page > 0 ? $page * 50 : 0; + + return $category->transactionJournals() + ->after($start) + ->before($end) + ->withRelevantData()->take(50)->offset($offset) + ->orderBy('transaction_journals.date', 'DESC') + ->orderBy('transaction_journals.order', 'ASC') + ->orderBy('transaction_journals.id', 'DESC') + ->get( + ['transaction_journals.*'] + ); + } + + /** + * @param Category $category + * + * @return int + */ + public function countJournalsInRange(Category $category, Carbon $start, Carbon $end) + { + return $category->transactionJournals()->before($end)->after($start)->count(); + } } diff --git a/app/Repositories/Category/CategoryRepositoryInterface.php b/app/Repositories/Category/CategoryRepositoryInterface.php index 2f2e3d1edc..06e40064a0 100644 --- a/app/Repositories/Category/CategoryRepositoryInterface.php +++ b/app/Repositories/Category/CategoryRepositoryInterface.php @@ -20,6 +20,13 @@ interface CategoryRepositoryInterface */ public function countJournals(Category $category); + /** + * @param Category $category + * + * @return int + */ + public function countJournalsInRange(Category $category, Carbon $start, Carbon $end); + /** * @param Category $category * @@ -57,6 +64,14 @@ interface CategoryRepositoryInterface */ public function getJournals(Category $category, $page); + /** + * @param Category $category + * @param int $page + * + * @return Collection + */ + public function getJournalsInRange(Category $category, $page, Carbon $start, Carbon $end); + /** * This method returns the sum of the journals in the category, optionally * limited by a start or end date. diff --git a/app/Support/Navigation.php b/app/Support/Navigation.php index d22b0250e6..773addd142 100644 --- a/app/Support/Navigation.php +++ b/app/Support/Navigation.php @@ -106,13 +106,14 @@ class Navigation * * @return Carbon */ - public function endOfX(Carbon $theCurrentEnd, $repeatFreq, Carbon $maxDate) + public function endOfX(Carbon $theCurrentEnd, $repeatFreq, Carbon $maxDate = null) { $functionMap = [ 'daily' => 'endOfDay', 'week' => 'endOfWeek', 'weekly' => 'endOfWeek', 'month' => 'endOfMonth', + '1M' => 'endOfMonth', 'monthly' => 'endOfMonth', 'quarter' => 'lastOfQuarter', 'quarterly' => 'lastOfQuarter', @@ -128,7 +129,7 @@ class Navigation } - if ($currentEnd > $maxDate) { + if (!is_null($maxDate) && $currentEnd > $maxDate) { return clone $maxDate; } @@ -149,6 +150,7 @@ class Navigation 'week' => 'Week %W, %Y', 'weekly' => 'Week %W, %Y', 'quarter' => '%B %Y', + '1M' => '%B %Y', 'month' => '%B %Y', 'monthly' => '%B %Y', 'year' => '%Y', @@ -224,6 +226,7 @@ class Navigation 'week' => 'subWeeks', 'weekly' => 'subWeeks', 'month' => 'subMonths', + '1M' => 'subMonths', 'monthly' => 'subMonths', 'year' => 'subYears', 'yearly' => 'subYears', diff --git a/resources/twig/categories/show.twig b/resources/twig/categories/show.twig index 38e95fee51..88803214ca 100644 --- a/resources/twig/categories/show.twig +++ b/resources/twig/categories/show.twig @@ -38,7 +38,7 @@
-
+
@@ -49,6 +49,33 @@
+
+ {% for entry in entries %} +
+ +
+ + {% if entry[2] != 0 %} + + + + + {% endif %} + {% if entry[3] != 0 %} + + + + + {% endif %} +
{{ 'spent'|_ }}{{ entry[2]|formatAmount }}
{{ 'earned'|_ }}{{ entry[3]|formatAmount }}
+
+
+ + {% endfor %} +
{% endblock %} diff --git a/resources/twig/categories/show_with_date.twig b/resources/twig/categories/show_with_date.twig new file mode 100644 index 0000000000..50efe41d60 --- /dev/null +++ b/resources/twig/categories/show_with_date.twig @@ -0,0 +1,75 @@ +{% extends "./layout/default.twig" %} + +{% block breadcrumbs %} + {{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, category) }} +{% endblock %} + +{% block content %} +
+
+
+
+

{{ 'overview'|_ }} (month)

+
+
+ {% if Config.get('firefly.chart') == 'google' %} +
+ {% endif %} + {% if Config.get('firefly.chart') == 'chartjs' %} + + {% endif %} +
+
+
+
+
+
+

{{ 'overview'|_ }} (all)

+
+
+ {% if Config.get('firefly.chart') == 'google' %} +
+ {% endif %} + {% if Config.get('firefly.chart') == 'chartjs' %} + + {% endif %} +
+
+
+
+ +
+
+ +
+
+

{{ 'transactions'|_ }}

+
+
+ {% include 'list/journals' %} +
+
+
+
+ +{% endblock %} +{% block scripts %} + + + {% if Config.get('firefly.chart') == 'google' %} + + + {% endif %} + {% if Config.get('firefly.chart') == 'chartjs' %} + + + {% endif %} + + +{% endblock %} diff --git a/resources/twig/emails/registered-html.twig b/resources/twig/emails/registered-html.twig index a776c2299a..6a2728beeb 100644 --- a/resources/twig/emails/registered-html.twig +++ b/resources/twig/emails/registered-html.twig @@ -19,7 +19,7 @@