This commit is contained in:
James Cole
2018-01-14 19:36:24 +01:00
parent c2a425121d
commit 00607d2a6d
4 changed files with 84 additions and 86 deletions

View File

@@ -611,21 +611,19 @@ class BudgetController extends Controller
if ($cache->has()) { if ($cache->has()) {
return $cache->get(); // @codeCoverageIgnore return $cache->get(); // @codeCoverageIgnore
} }
$dates = app('navigation')->blockPeriods($start, $end, $range);
Log::debug('Going to get period expenses and incomes.'); foreach ($dates as $date) {
while ($end >= $start) {
$end = app('navigation')->startOfPeriod($end, $range);
$currentEnd = app('navigation')->endOfPeriod($end, $range);
/** @var JournalCollectorInterface $collector */ /** @var JournalCollectorInterface $collector */
$collector = app(JournalCollectorInterface::class); $collector = app(JournalCollectorInterface::class);
$collector->setAllAssetAccounts()->setRange($end, $currentEnd)->withoutBudget()->withOpposingAccount()->setTypes([TransactionType::WITHDRAWAL]); $collector->setAllAssetAccounts()->setRange($date['start'], $date['end'])->withoutBudget()->withOpposingAccount()->setTypes(
[TransactionType::WITHDRAWAL]
);
$set = $collector->getJournals(); $set = $collector->getJournals();
$sum = strval($set->sum('transaction_amount') ?? '0'); $sum = strval($set->sum('transaction_amount') ?? '0');
$journals = $set->count(); $journals = $set->count();
$dateStr = $end->format('Y-m-d'); $dateStr = $date['end']->format('Y-m-d');
$dateName = app('navigation')->periodShow($end, $range); $dateName = app('navigation')->periodShow($date['end'], $date['period']);
$entries->push(['string' => $dateStr, 'name' => $dateName, 'count' => $journals, 'sum' => $sum, 'date' => clone $end]); $entries->push(['string' => $dateStr, 'name' => $dateName, 'count' => $journals, 'sum' => $sum, 'date' => clone $date['end']]);
$end = app('navigation')->subtractPeriod($end, $range, 1);
} }
$cache->store($entries); $cache->store($entries);

View File

@@ -46,6 +46,13 @@ use View;
*/ */
class CategoryController extends Controller class CategoryController extends Controller
{ {
/** @var AccountRepositoryInterface */
private $accountRepos;
/** @var JournalRepositoryInterface */
private $journalRepos;
/** @var CategoryRepositoryInterface */
private $repository;
/** /**
* *
*/ */
@@ -57,6 +64,9 @@ class CategoryController extends Controller
function ($request, $next) { function ($request, $next) {
app('view')->share('title', trans('firefly.categories')); app('view')->share('title', trans('firefly.categories'));
app('view')->share('mainTitleIcon', 'fa-bar-chart'); app('view')->share('mainTitleIcon', 'fa-bar-chart');
$this->journalRepos = app(JournalRepositoryInterface::class);
$this->repository = app(CategoryRepositoryInterface::class);
$this->accountRepos = app(AccountRepositoryInterface::class);
return $next($request); return $next($request);
} }
@@ -95,16 +105,15 @@ class CategoryController extends Controller
} }
/** /**
* @param Request $request * @param Request $request
* @param CategoryRepositoryInterface $repository * @param Category $category
* @param Category $category
* *
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/ */
public function destroy(Request $request, CategoryRepositoryInterface $repository, Category $category) public function destroy(Request $request, Category $category)
{ {
$name = $category->name; $name = $category->name;
$repository->destroy($category); $this->repository->destroy($category);
$request->session()->flash('success', strval(trans('firefly.deleted_category', ['name' => $name]))); $request->session()->flash('success', strval(trans('firefly.deleted_category', ['name' => $name])));
Preferences::mark(); Preferences::mark();
@@ -132,21 +141,21 @@ class CategoryController extends Controller
} }
/** /**
* @param CategoryRepositoryInterface $repository * @param Request $request
* *
* @return View * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/ */
public function index(Request $request, CategoryRepositoryInterface $repository) public function index(Request $request)
{ {
$page = 0 === intval($request->get('page')) ? 1 : intval($request->get('page')); $page = 0 === intval($request->get('page')) ? 1 : intval($request->get('page'));
$pageSize = intval(Preferences::get('listPageSize', 50)->data); $pageSize = intval(Preferences::get('listPageSize', 50)->data);
$collection = $repository->getCategories(); $collection = $this->repository->getCategories();
$total = $collection->count(); $total = $collection->count();
$collection = $collection->slice(($page - 1) * $pageSize, $pageSize); $collection = $collection->slice(($page - 1) * $pageSize, $pageSize);
$collection->each( $collection->each(
function (Category $category) use ($repository) { function (Category $category) {
$category->lastActivity = $repository->lastUseDate($category, new Collection); $category->lastActivity = $this->repository->lastUseDate($category, new Collection);
} }
); );
@@ -158,13 +167,12 @@ class CategoryController extends Controller
} }
/** /**
* @param Request $request * @param Request $request
* @param JournalRepositoryInterface $repository * @param string $moment
* @param string $moment
* *
* @return View * @return View
*/ */
public function noCategory(Request $request, JournalRepositoryInterface $repository, string $moment = '') public function noCategory(Request $request, string $moment = '')
{ {
// default values: // default values:
$range = Preferences::get('viewRange', '1M')->data; $range = Preferences::get('viewRange', '1M')->data;
@@ -177,27 +185,27 @@ class CategoryController extends Controller
// prep for "all" view. // prep for "all" view.
if ('all' === $moment) { if ('all' === $moment) {
$subTitle = trans('firefly.all_journals_without_category'); $subTitle = trans('firefly.all_journals_without_category');
$first = $repository->first(); $first = $this->journalRepos->first();
$start = $first->date ?? new Carbon; $start = $first->date ?? new Carbon;
$end = new Carbon; $end = new Carbon;
} }
// prep for "specific date" view. // prep for "specific date" view.$dates = app('navigation')->blockPeriods($start, $end, $range);
if (strlen($moment) > 0 && 'all' !== $moment) { if (strlen($moment) > 0 && 'all' !== $moment) {
$start = new Carbon($moment); $start = app('navigation')->startOfPeriod(new Carbon($moment), $range);
$end = app('navigation')->endOfPeriod($start, $range); $end = app('navigation')->endOfPeriod($start, $range);
$subTitle = trans( $subTitle = trans(
'firefly.without_category_between', 'firefly.without_category_between',
['start' => $start->formatLocalized($this->monthAndDayFormat), 'end' => $end->formatLocalized($this->monthAndDayFormat)] ['start' => $start->formatLocalized($this->monthAndDayFormat), 'end' => $end->formatLocalized($this->monthAndDayFormat)]
); );
$periods = $this->getNoCategoryPeriodOverview(); $periods = $this->getNoCategoryPeriodOverview($start);
} }
// prep for current period // prep for current period
if (0 === strlen($moment)) { if (0 === strlen($moment)) {
$start = clone session('start', app('navigation')->startOfPeriod(new Carbon, $range)); $start = clone session('start', app('navigation')->startOfPeriod(new Carbon, $range));
$end = clone session('end', app('navigation')->endOfPeriod(new Carbon, $range)); $end = clone session('end', app('navigation')->endOfPeriod(new Carbon, $range));
$periods = $this->getNoCategoryPeriodOverview(); $periods = $this->getNoCategoryPeriodOverview($start);
$subTitle = trans( $subTitle = trans(
'firefly.without_category_between', 'firefly.without_category_between',
['start' => $start->formatLocalized($this->monthAndDayFormat), 'end' => $end->formatLocalized($this->monthAndDayFormat)] ['start' => $start->formatLocalized($this->monthAndDayFormat), 'end' => $end->formatLocalized($this->monthAndDayFormat)]
@@ -248,14 +256,14 @@ class CategoryController extends Controller
// prep for "specific date" view. // prep for "specific date" view.
if (strlen($moment) > 0 && 'all' !== $moment) { if (strlen($moment) > 0 && 'all' !== $moment) {
$start = new Carbon($moment); $start = app('navigation')->startOfPeriod(new Carbon($moment), $range);
$end = app('navigation')->endOfPeriod($start, $range); $end = app('navigation')->endOfPeriod($start, $range);
$subTitle = trans( $subTitle = trans(
'firefly.journals_in_period_for_category', 'firefly.journals_in_period_for_category',
['name' => $category->name, ['name' => $category->name,
'start' => $start->formatLocalized($this->monthAndDayFormat), 'end' => $end->formatLocalized($this->monthAndDayFormat),] 'start' => $start->formatLocalized($this->monthAndDayFormat), 'end' => $end->formatLocalized($this->monthAndDayFormat),]
); );
$periods = $this->getPeriodOverview($category); $periods = $this->getPeriodOverview($category, $start);
$path = route('categories.show', [$category->id, $moment]); $path = route('categories.show', [$category->id, $moment]);
} }
@@ -265,7 +273,7 @@ class CategoryController extends Controller
$start = clone session('start', app('navigation')->startOfPeriod(new Carbon, $range)); $start = clone session('start', app('navigation')->startOfPeriod(new Carbon, $range));
/** @var Carbon $end */ /** @var Carbon $end */
$end = clone session('end', app('navigation')->endOfPeriod(new Carbon, $range)); $end = clone session('end', app('navigation')->endOfPeriod(new Carbon, $range));
$periods = $this->getPeriodOverview($category); $periods = $this->getPeriodOverview($category, $start);
$subTitle = trans( $subTitle = trans(
'firefly.journals_in_period_for_category', 'firefly.journals_in_period_for_category',
['name' => $category->name, 'start' => $start->formatLocalized($this->monthAndDayFormat), ['name' => $category->name, 'start' => $start->formatLocalized($this->monthAndDayFormat),
@@ -336,38 +344,36 @@ class CategoryController extends Controller
} }
/** /**
* @param Carbon $theDate
*
* @return Collection * @return Collection
*/ */
private function getNoCategoryPeriodOverview(): Collection private function getNoCategoryPeriodOverview(Carbon $theDate): Collection
{ {
$repository = app(JournalRepositoryInterface::class); $range = Preferences::get('viewRange', '1M')->data;
$first = $repository->first(); $first = $this->journalRepos->first();
$start = $first->date ?? new Carbon; $start = $first->date ?? new Carbon;
$range = Preferences::get('viewRange', '1M')->data; $end = $theDate ?? new Carbon;
$start = app('navigation')->startOfPeriod($start, $range);
$end = app('navigation')->endOfX(new Carbon, $range, null);
$entries = new Collection;
// properties for cache // properties for cache
$cache = new CacheProperties; $cache = new CacheProperties;
$cache->addProperty($start); $cache->addProperty($start);
$cache->addProperty($end); $cache->addProperty($end);
$cache->addProperty('no-budget-period-entries'); $cache->addProperty('no-category-period-entries');
if ($cache->has()) { if ($cache->has()) {
return $cache->get(); // @codeCoverageIgnore return $cache->get(); // @codeCoverageIgnore
} }
Log::debug(sprintf('Going to get period expenses and incomes between %s and %s.', $start->format('Y-m-d'), $end->format('Y-m-d'))); $dates = app('navigation')->blockPeriods($start, $end, $range);
while ($end >= $start) { $entries = new Collection;
Log::debug('Loop!');
$end = app('navigation')->startOfPeriod($end, $range); foreach ($dates as $date) {
$currentEnd = app('navigation')->endOfPeriod($end, $range);
// count journals without category in this period: // count journals without category in this period:
/** @var JournalCollectorInterface $collector */ /** @var JournalCollectorInterface $collector */
$collector = app(JournalCollectorInterface::class); $collector = app(JournalCollectorInterface::class);
$collector->setAllAssetAccounts()->setRange($end, $currentEnd)->withoutCategory() $collector->setAllAssetAccounts()->setRange($date['start'], $date['end'])->withoutCategory()
->withOpposingAccount()->setTypes([TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER]); ->withOpposingAccount()->setTypes([TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER]);
$collector->removeFilter(InternalTransferFilter::class); $collector->removeFilter(InternalTransferFilter::class);
$count = $collector->getJournals()->count(); $count = $collector->getJournals()->count();
@@ -375,7 +381,7 @@ class CategoryController extends Controller
// amount transferred // amount transferred
/** @var JournalCollectorInterface $collector */ /** @var JournalCollectorInterface $collector */
$collector = app(JournalCollectorInterface::class); $collector = app(JournalCollectorInterface::class);
$collector->setAllAssetAccounts()->setRange($end, $currentEnd)->withoutCategory() $collector->setAllAssetAccounts()->setRange($date['start'], $date['end'])->withoutCategory()
->withOpposingAccount()->setTypes([TransactionType::TRANSFER]); ->withOpposingAccount()->setTypes([TransactionType::TRANSFER]);
$collector->removeFilter(InternalTransferFilter::class); $collector->removeFilter(InternalTransferFilter::class);
$transferred = Steam::positive($collector->getJournals()->sum('transaction_amount')); $transferred = Steam::positive($collector->getJournals()->sum('transaction_amount'));
@@ -383,17 +389,20 @@ class CategoryController extends Controller
// amount spent // amount spent
/** @var JournalCollectorInterface $collector */ /** @var JournalCollectorInterface $collector */
$collector = app(JournalCollectorInterface::class); $collector = app(JournalCollectorInterface::class);
$collector->setAllAssetAccounts()->setRange($end, $currentEnd)->withoutCategory()->withOpposingAccount()->setTypes([TransactionType::WITHDRAWAL]); $collector->setAllAssetAccounts()->setRange($date['start'], $date['end'])->withoutCategory()->withOpposingAccount()->setTypes(
[TransactionType::WITHDRAWAL]
);
$spent = $collector->getJournals()->sum('transaction_amount'); $spent = $collector->getJournals()->sum('transaction_amount');
// amount earned // amount earned
/** @var JournalCollectorInterface $collector */ /** @var JournalCollectorInterface $collector */
$collector = app(JournalCollectorInterface::class); $collector = app(JournalCollectorInterface::class);
$collector->setAllAssetAccounts()->setRange($end, $currentEnd)->withoutCategory()->withOpposingAccount()->setTypes([TransactionType::DEPOSIT]); $collector->setAllAssetAccounts()->setRange($date['start'], $date['end'])->withoutCategory()->withOpposingAccount()->setTypes(
$earned = $collector->getJournals()->sum('transaction_amount'); [TransactionType::DEPOSIT]
);
$dateStr = $end->format('Y-m-d'); $earned = $collector->getJournals()->sum('transaction_amount');
$dateName = app('navigation')->periodShow($end, $range); $dateStr = $date['end']->format('Y-m-d');
$dateName = app('navigation')->periodShow($date['end'], $date['period']);
$entries->push( $entries->push(
[ [
'string' => $dateStr, 'string' => $dateStr,
@@ -402,10 +411,9 @@ class CategoryController extends Controller
'spent' => $spent, 'spent' => $spent,
'earned' => $earned, 'earned' => $earned,
'transferred' => $transferred, 'transferred' => $transferred,
'date' => clone $end, 'date' => clone $date['end'],
] ]
); );
$end = app('navigation')->subtractPeriod($end, $range, 1);
} }
Log::debug('End of loops'); Log::debug('End of loops');
$cache->store($entries); $cache->store($entries);
@@ -418,45 +426,39 @@ class CategoryController extends Controller
* *
* @return Collection * @return Collection
*/ */
private function getPeriodOverview(Category $category): Collection private function getPeriodOverview(Category $category, Carbon $date): Collection
{ {
/** @var CategoryRepositoryInterface $repository */ $range = Preferences::get('viewRange', '1M')->data;
$repository = app(CategoryRepositoryInterface::class); $first = $this->journalRepos->first();
/** @var AccountRepositoryInterface $accountRepository */ $start = $first->date ?? new Carbon;
$accountRepository = app(AccountRepositoryInterface::class); $end = $date ?? new Carbon;
$accounts = $accountRepository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]); $accounts = $this->accountRepos->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
$first = $repository->firstUseDate($category);
if (null === $first) {
$first = new Carbon; // @codeCoverageIgnore
}
$range = Preferences::get('viewRange', '1M')->data;
$first = app('navigation')->startOfPeriod($first, $range);
$end = app('navigation')->endOfX(new Carbon, $range, null);
$entries = new Collection;
$count = 0;
// properties for entries with their amounts. // properties for entries with their amounts.
$cache = new CacheProperties(); $cache = new CacheProperties();
$cache->addProperty($first); $cache->addProperty($start);
$cache->addProperty($end); $cache->addProperty($end);
$cache->addProperty($range);
$cache->addProperty('categories.entries'); $cache->addProperty('categories.entries');
$cache->addProperty($category->id); $cache->addProperty($category->id);
if ($cache->has()) { if ($cache->has()) {
return $cache->get(); // @codeCoverageIgnore return $cache->get(); // @codeCoverageIgnore
} }
while ($end >= $first && $count < 90) {
$end = app('navigation')->startOfPeriod($end, $range); $dates = app('navigation')->blockPeriods($start, $end, $range);
$currentEnd = app('navigation')->endOfPeriod($end, $range); $entries = new Collection;
$spent = $repository->spentInPeriod(new Collection([$category]), $accounts, $end, $currentEnd);
$earned = $repository->earnedInPeriod(new Collection([$category]), $accounts, $end, $currentEnd); foreach ($dates as $date) {
$dateStr = $end->format('Y-m-d'); $spent = $this->repository->spentInPeriod(new Collection([$category]), $accounts, $date['start'], $date['end']);
$dateName = app('navigation')->periodShow($end, $range); $earned = $this->repository->earnedInPeriod(new Collection([$category]), $accounts, $date['start'], $date['end']);
$dateStr = $date['end']->format('Y-m-d');
$dateName = app('navigation')->periodShow($date['end'], $date['period']);
// amount transferred // amount transferred
/** @var JournalCollectorInterface $collector */ /** @var JournalCollectorInterface $collector */
$collector = app(JournalCollectorInterface::class); $collector = app(JournalCollectorInterface::class);
$collector->setAllAssetAccounts()->setRange($end, $currentEnd)->setCategory($category) $collector->setAllAssetAccounts()->setRange($date['start'], $date['end'])->setCategory($category)
->withOpposingAccount()->setTypes([TransactionType::TRANSFER]); ->withOpposingAccount()->setTypes([TransactionType::TRANSFER]);
$collector->removeFilter(InternalTransferFilter::class); $collector->removeFilter(InternalTransferFilter::class);
$transferred = Steam::positive($collector->getJournals()->sum('transaction_amount')); $transferred = Steam::positive($collector->getJournals()->sum('transaction_amount'));
@@ -469,11 +471,9 @@ class CategoryController extends Controller
'earned' => $earned, 'earned' => $earned,
'sum' => bcadd($earned, $spent), 'sum' => bcadd($earned, $spent),
'transferred' => $transferred, 'transferred' => $transferred,
'date' => clone $end, 'date' => clone $date['end'],
] ]
); );
$end = app('navigation')->subtractPeriod($end, $range, 1);
++$count;
} }
$cache->store($entries); $cache->store($entries);

View File

@@ -42,7 +42,7 @@
<div class="col-lg-2 col-md-3 col-sm-12 col-xs-12"> <div class="col-lg-2 col-md-3 col-sm-12 col-xs-12">
{% for period in periods %} {% for period in periods %}
{% if period.count > 0 %} {% if period.count > 0 %}
<div class="box {% if period.date == start %}box-solid box-primary{% endif %}"> <div class="box {% if period.date == end %}box-solid box-primary{% endif %}">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title"><a href="{{ route('categories.no-category',[period.string]) }}">{{ period.name }}</a> <h3 class="box-title"><a href="{{ route('categories.no-category',[period.string]) }}">{{ period.name }}</a>
</h3> </h3>

View File

@@ -88,7 +88,7 @@
<div class="col-lg-2 col-md-4 col-sm-12 col-xs-12"> <div class="col-lg-2 col-md-4 col-sm-12 col-xs-12">
{% for period in periods %} {% for period in periods %}
{% if period.spent != 0 or period.earned != 0 or period.sum != 0 %} {% if period.spent != 0 or period.earned != 0 or period.sum != 0 %}
<div class="box {% if period.date == start %}box-solid box-primary{% endif %}"> <div class="box {% if period.date == end %}box-solid box-primary{% endif %}">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title"><a href="{{ route('categories.show',[category.id,period.string]) }}">{{ period.name }}</a> <h3 class="box-title"><a href="{{ route('categories.show',[category.id,period.string]) }}">{{ period.name }}</a>
</h3> </h3>