mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
ShowAll method for category
This commit is contained in:
parent
b9d142c2b7
commit
5efdf53c06
@ -20,7 +20,7 @@ use FireflyIII\Http\Requests\CategoryFormRequest;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface as CRI;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use Illuminate\Support\Collection;
|
||||
use Input;
|
||||
@ -89,13 +89,14 @@ class CategoryController extends Controller
|
||||
return view('categories.delete', compact('category', 'subTitle'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param CRI $repository
|
||||
* @param Category $category
|
||||
* @param CategoryRepositoryInterface $repository
|
||||
* @param Category $category
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*/
|
||||
public function destroy(CRI $repository, Category $category)
|
||||
public function destroy(CategoryRepositoryInterface $repository, Category $category)
|
||||
{
|
||||
|
||||
$name = $category->name;
|
||||
@ -136,11 +137,11 @@ class CategoryController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CRI $repository
|
||||
* @param CategoryRepositoryInterface $repository
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function index(CRI $repository)
|
||||
public function index(CategoryRepositoryInterface $repository)
|
||||
{
|
||||
$categories = $repository->getCategories();
|
||||
|
||||
@ -176,20 +177,15 @@ class CategoryController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CRI $repository
|
||||
* @param AccountRepositoryInterface $accountRepository
|
||||
* @param Category $category
|
||||
* @param Category $category
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function show(CRI $repository, AccountRepositoryInterface $accountRepository, Category $category)
|
||||
public function show(Category $category)
|
||||
{
|
||||
$range = Preferences::get('viewRange', '1M')->data;
|
||||
/** @var Carbon $start */
|
||||
$start = session('start', Navigation::startOfPeriod(new Carbon, $range));
|
||||
/** @var Carbon $end */
|
||||
$range = Preferences::get('viewRange', '1M')->data;
|
||||
$start = session('start', Navigation::startOfPeriod(new Carbon, $range));
|
||||
$end = session('end', Navigation::endOfPeriod(new Carbon, $range));
|
||||
$accounts = $accountRepository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
|
||||
$hideCategory = true; // used in list.
|
||||
$page = intval(Input::get('page')) === 0 ? 1 : intval(Input::get('page'));
|
||||
$pageSize = intval(Preferences::get('transactionPageSize', 50)->data);
|
||||
@ -202,48 +198,38 @@ class CategoryController extends Controller
|
||||
$journals = $collector->getPaginatedJournals();
|
||||
$journals->setPath('categories/show/' . $category->id);
|
||||
|
||||
// oldest transaction in category:
|
||||
$entries = $this->getGroupedEntries($category);
|
||||
|
||||
return view('categories.show', compact('category', 'journals', 'entries', 'hideCategory', 'subTitle', 'subTitleIcon', 'start', 'end'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CategoryRepositoryInterface $repository
|
||||
* @param Category $category
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function showAll(CategoryRepositoryInterface $repository, Category $category)
|
||||
{
|
||||
$range = Preferences::get('viewRange', '1M')->data;
|
||||
$start = $repository->firstUseDate($category);
|
||||
if ($start->year == 1900) {
|
||||
$start = new Carbon;
|
||||
}
|
||||
$range = Preferences::get('viewRange', '1M')->data;
|
||||
$start = Navigation::startOfPeriod($start, $range);
|
||||
$end = Navigation::endOfX(new Carbon, $range);
|
||||
$entries = new Collection;
|
||||
$end = Navigation::endOfPeriod(new Carbon, $range);
|
||||
$subTitle = $category->name;
|
||||
$subTitleIcon = 'fa-bar-chart';
|
||||
$hideCategory = true; // used in list.
|
||||
$page = intval(Input::get('page')) === 0 ? 1 : intval(Input::get('page'));
|
||||
$pageSize = intval(Preferences::get('transactionPageSize', 50)->data);
|
||||
|
||||
// chart properties for cache:
|
||||
$cache = new CacheProperties();
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty('category-show');
|
||||
$cache->addProperty($category->id);
|
||||
// new collector:
|
||||
$collector = app(JournalCollectorInterface::class);
|
||||
$collector->setPage($page)->setLimit($pageSize)->setAllAssetAccounts()->setRange($start, $end)->setCategory($category);
|
||||
$journals = $collector->getPaginatedJournals();
|
||||
$journals->setPath('categories/show/' . $category->id . '/all');
|
||||
|
||||
|
||||
if ($cache->has()) {
|
||||
$entries = $cache->get();
|
||||
|
||||
return view('categories.show', compact('category', 'journals', 'entries', 'subTitleIcon', 'hideCategory', 'subTitle'));
|
||||
}
|
||||
|
||||
|
||||
$categoryCollection = new Collection([$category]);
|
||||
|
||||
while ($end >= $start) {
|
||||
$end = Navigation::startOfPeriod($end, $range);
|
||||
$currentEnd = Navigation::endOfPeriod($end, $range);
|
||||
$spent = $repository->spentInPeriod($categoryCollection, $accounts, $end, $currentEnd);
|
||||
$earned = $repository->earnedInPeriod($categoryCollection, $accounts, $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', 'subTitle', 'subTitleIcon'));
|
||||
return view('categories.show', compact('category', 'journals', 'hideCategory', 'subTitle', 'subTitleIcon', 'start', 'end'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -259,6 +245,7 @@ class CategoryController extends Controller
|
||||
$start = Navigation::startOfPeriod($carbon, $range);
|
||||
$end = Navigation::endOfPeriod($carbon, $range);
|
||||
$subTitle = $category->name;
|
||||
$subTitleIcon = 'fa-bar-chart';
|
||||
$hideCategory = true; // used in list.
|
||||
$page = intval(Input::get('page')) === 0 ? 1 : intval(Input::get('page'));
|
||||
$pageSize = intval(Preferences::get('transactionPageSize', 50)->data);
|
||||
@ -269,16 +256,16 @@ class CategoryController extends Controller
|
||||
$journals = $collector->getPaginatedJournals();
|
||||
$journals->setPath('categories/show/' . $category->id . '/' . $date);
|
||||
|
||||
return view('categories.show-by-date', compact('category', 'journals', 'hideCategory', 'subTitle', 'carbon'));
|
||||
return view('categories.show', compact('category', 'journals', 'hideCategory', 'subTitle', 'subTitleIcon', 'start', 'end'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CategoryFormRequest $request
|
||||
* @param CRI $repository
|
||||
* @param CategoryFormRequest $request
|
||||
* @param CategoryRepositoryInterface $repository
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @return $this|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*/
|
||||
public function store(CategoryFormRequest $request, CRI $repository)
|
||||
public function store(CategoryFormRequest $request, CategoryRepositoryInterface $repository)
|
||||
{
|
||||
$data = $request->getCategoryData();
|
||||
$category = $repository->store($data);
|
||||
@ -297,13 +284,13 @@ class CategoryController extends Controller
|
||||
|
||||
|
||||
/**
|
||||
* @param CategoryFormRequest $request
|
||||
* @param CRI $repository
|
||||
* @param Category $category
|
||||
* @param CategoryFormRequest $request
|
||||
* @param CategoryRepositoryInterface $repository
|
||||
* @param Category $category
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*/
|
||||
public function update(CategoryFormRequest $request, CRI $repository, Category $category)
|
||||
public function update(CategoryFormRequest $request, CategoryRepositoryInterface $repository, Category $category)
|
||||
{
|
||||
$data = $request->getCategoryData();
|
||||
$repository->update($category, $data);
|
||||
@ -322,4 +309,48 @@ class CategoryController extends Controller
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
private function getGroupedEntries(Category $category): Collection
|
||||
{
|
||||
$repository = app(CategoryRepositoryInterface::class);
|
||||
$accountRepository = app(AccountRepositoryInterface::class);
|
||||
$accounts = $accountRepository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
|
||||
$first = $repository->firstUseDate($category);
|
||||
if ($first->year == 1900) {
|
||||
$first = new Carbon;
|
||||
}
|
||||
$range = Preferences::get('viewRange', '1M')->data;
|
||||
$first = Navigation::startOfPeriod($first, $range);
|
||||
$end = Navigation::endOfX(new Carbon, $range);
|
||||
$entries = new Collection;
|
||||
|
||||
// properties for entries with their amounts.
|
||||
$cache = new CacheProperties();
|
||||
$cache->addProperty($first);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty('categories.entries');
|
||||
$cache->addProperty($category->id);
|
||||
|
||||
if ($cache->has()) {
|
||||
return $cache->get();
|
||||
}
|
||||
while ($end >= $first) {
|
||||
$end = Navigation::startOfPeriod($end, $range);
|
||||
$currentEnd = Navigation::endOfPeriod($end, $range);
|
||||
$spent = $repository->spentInPeriod(new Collection([$category]), $accounts, $end, $currentEnd);
|
||||
$earned = $repository->earnedInPeriod(new Collection([$category]), $accounts, $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 $entries;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -12,4 +12,5 @@ $(function () {
|
||||
"use strict";
|
||||
columnChart(all, 'all');
|
||||
columnChart(current, 'period');
|
||||
columnChart(specific, 'period-specific-period');
|
||||
});
|
@ -101,6 +101,7 @@ return [
|
||||
'cannot_reset_demo_user' => 'You cannot reset the password of the demonstration account',
|
||||
'per_period' => 'Per period',
|
||||
'all_periods' => 'All periods',
|
||||
'show_the_current_period_and_overview' => 'Show the current period and overview',
|
||||
|
||||
// repeat frequencies:
|
||||
'repeat_freq_yearly' => 'yearly',
|
||||
|
@ -76,12 +76,21 @@
|
||||
</div>
|
||||
<div class="box-body">
|
||||
{% include 'list.journals-tasker' with {sorting:true, hideBills:true, hideBudgets: true} %}
|
||||
<p>
|
||||
<i class="fa fa-calendar" aria-hidden="true"></i>
|
||||
<a href="{{ route('accounts.show.all', [account.id]) }}">
|
||||
{{ 'show_all_no_filter'|_ }}
|
||||
</a>
|
||||
</p>
|
||||
{% if entries %}
|
||||
<p>
|
||||
<i class="fa fa-calendar" aria-hidden="true"></i>
|
||||
<a href="{{ route('accounts.show.all', [account.id]) }}">
|
||||
{{ 'show_all_no_filter'|_ }}
|
||||
</a>
|
||||
</p>
|
||||
{% else %}
|
||||
<p>
|
||||
<i class="fa fa-calendar" aria-hidden="true"></i>
|
||||
<a href="{{ route('accounts.show', [account.id]) }}">
|
||||
{{ 'show_the_current_period_and_overview'|_ }}
|
||||
</a>
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,34 +1,49 @@
|
||||
{% extends "./layout/default" %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
{{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, category) }}
|
||||
{{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, category, start, end) }}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-md-6 col-sm-12">
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ 'overview'|_ }} ({{ 'per_period'|_|lower }})</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<canvas id="period" style="width:100%" height="350"></canvas>
|
||||
{% if entries %}
|
||||
{# both charts #}
|
||||
<div class="col-lg-6 col-md-6 col-sm-12">
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ 'overview'|_ }} ({{ 'per_period'|_|lower }})</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<canvas id="period" style="width:100%" height="350"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6 col-md-6 col-sm-12">
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ 'overview'|_ }} ({{ 'all_periods'|_|lower }})</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<canvas id="all" style="width:100%;" height="350"></canvas>
|
||||
<div class="col-lg-6 col-md-6 col-sm-12">
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ 'overview'|_ }} ({{ 'all_periods'|_|lower }})</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<canvas id="all" style="width:100%;" height="350"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
{# single chart #}
|
||||
<div class="col-lg-12 col-md-12 col-sm-12">
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ 'overview'|_ }} ({{ 'current_period'|_|lower }})</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<canvas id="period-specific-period" style="width:100%;height:350px;" height="350"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-10 col-md-8 col-sm-12 col-xs-12">
|
||||
<div class="{% if entries %}col-lg-10 col-md-8 col-sm-12 col-xs-12{% else %}col-lg-12 col-md-12 col-sm-12 col-xs-12{% endif %}">
|
||||
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
@ -36,38 +51,55 @@
|
||||
</div>
|
||||
<div class="box-body">
|
||||
{% include 'list.journals-tasker' %}
|
||||
{% if entries %}
|
||||
<p>
|
||||
<i class="fa fa-calendar" aria-hidden="true"></i>
|
||||
<a href="{{ route('categories.show.all', [category.id]) }}">
|
||||
{{ 'show_all_no_filter'|_ }}
|
||||
</a>
|
||||
</p>
|
||||
{% else %}
|
||||
<p>
|
||||
<i class="fa fa-calendar" aria-hidden="true"></i>
|
||||
<a href="{{ route('categories.show', [category.id]) }}">
|
||||
{{ 'show_the_current_period_and_overview'|_ }}
|
||||
</a>
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-2 col-md-4 col-sm-12 col-xs-12">
|
||||
{% for entry in entries %}
|
||||
{% if entry[2] != 0 or entry[3] != 0 %}
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><a href="{{ route('categories.show.date',[category.id,entry[0]]) }}">{{ entry[1] }}</a>
|
||||
</h3>
|
||||
{% if entries %}
|
||||
<div class="col-lg-2 col-md-4 col-sm-12 col-xs-12">
|
||||
{% for entry in entries %}
|
||||
{% if entry[2] != 0 or entry[3] != 0 %}
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><a href="{{ route('categories.show.date',[category.id,entry[0]]) }}">{{ entry[1] }}</a>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="box-body no-padding">
|
||||
<table class="table table-hover">
|
||||
{% if entry[2] != 0 %}
|
||||
<tr>
|
||||
<td colspan="33%">{{ 'spent'|_ }}</td>
|
||||
<td colspan="67%">{{ entry[2]|formatAmount }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if entry[3] != 0 %}
|
||||
<tr>
|
||||
<td colspan="33%">{{ 'earned'|_ }}</td>
|
||||
<td colspan="67%">{{ entry[3]|formatAmount }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body no-padding">
|
||||
<table class="table table-hover">
|
||||
{% if entry[2] != 0 %}
|
||||
<tr>
|
||||
<td colspan="33%">{{ 'spent'|_ }}</td>
|
||||
<td colspan="67%">{{ entry[2]|formatAmount }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if entry[3] != 0 %}
|
||||
<tr>
|
||||
<td colspan="33%">{{ 'earned'|_ }}</td>
|
||||
<td colspan="67%">{{ entry[3]|formatAmount }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@ -75,6 +107,7 @@
|
||||
<script type="text/javascript">
|
||||
var current = '{{ route('chart.category.current', [category.id]) }}';
|
||||
var all = '{{ route('chart.category.all', [category.id]) }}';
|
||||
var specific = '{{ route('chart.category.specific', [category.id, start.format('Ymd')]) }}';
|
||||
</script>
|
||||
<script type="text/javascript" src="js/lib/Chart.bundle.min.js"></script>
|
||||
<script type="text/javascript" src="js/ff/charts.defaults.js"></script>
|
||||
|
@ -177,6 +177,7 @@ Route::group(
|
||||
Route::get('delete/{category}', ['uses' => 'CategoryController@delete', 'as' => 'delete']);
|
||||
|
||||
Route::get('show/{category}', ['uses' => 'CategoryController@show', 'as' => 'show']);
|
||||
Route::get('show/{category}/all', ['uses' => 'CategoryController@showAll', 'as' => 'show.all']);
|
||||
Route::get('show/{category}/{date}', ['uses' => 'CategoryController@showByDate', 'as' => 'show.date']);
|
||||
Route::get('list/no-category', ['uses' => 'CategoryController@noCategory', 'as' => 'no-category']);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user