mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-29 18:20:01 +00:00
Make stuff scale better #1040
This commit is contained in:
@@ -88,7 +88,7 @@ class ShowController extends Controller
|
|||||||
'firefly.without_budget_between',
|
'firefly.without_budget_between',
|
||||||
['start' => $start->formatLocalized($this->monthAndDayFormat), 'end' => $end->formatLocalized($this->monthAndDayFormat)]
|
['start' => $start->formatLocalized($this->monthAndDayFormat), 'end' => $end->formatLocalized($this->monthAndDayFormat)]
|
||||||
);
|
);
|
||||||
$periods = $this->getBudgetPeriodOverview($end);
|
$periods = $this->getNoBudgetPeriodOverview($end);
|
||||||
$page = (int)$request->get('page');
|
$page = (int)$request->get('page');
|
||||||
$pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
|
$pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
|
||||||
|
|
||||||
|
@@ -32,6 +32,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
|||||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||||
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
|
||||||
use FireflyIII\Support\CacheProperties;
|
use FireflyIII\Support\CacheProperties;
|
||||||
|
use FireflyIII\Support\Http\Controllers\DateCalculation;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
@@ -40,6 +41,7 @@ use Illuminate\Support\Collection;
|
|||||||
*/
|
*/
|
||||||
class CategoryController extends Controller
|
class CategoryController extends Controller
|
||||||
{
|
{
|
||||||
|
use DateCalculation;
|
||||||
/** @var GeneratorInterface Chart generation methods. */
|
/** @var GeneratorInterface Chart generation methods. */
|
||||||
protected $generator;
|
protected $generator;
|
||||||
|
|
||||||
@@ -97,17 +99,36 @@ class CategoryController extends Controller
|
|||||||
'entries' => [], 'type' => 'line', 'fill' => false,
|
'entries' => [], 'type' => 'line', 'fill' => false,
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
$step = $this->calculateStep($start, $end);
|
||||||
while ($start <= $end) {
|
$current = clone $start;
|
||||||
$currentEnd = app('navigation')->endOfPeriod($start, $range);
|
switch ($step) {
|
||||||
$spent = $repository->spentInPeriod(new Collection([$category]), $accounts, $start, $currentEnd);
|
case '1D':
|
||||||
$earned = $repository->earnedInPeriod(new Collection([$category]), $accounts, $start, $currentEnd);
|
while ($current <= $end) {
|
||||||
$sum = bcadd($spent, $earned);
|
$spent = $repository->spentInPeriod(new Collection([$category]), $accounts, $current, $current);
|
||||||
$label = app('navigation')->periodShow($start, $range);
|
$earned = $repository->earnedInPeriod(new Collection([$category]), $accounts, $current, $current);
|
||||||
$chartData[0]['entries'][$label] = round(bcmul($spent, '-1'), 12);
|
$sum = bcadd($spent, $earned);
|
||||||
$chartData[1]['entries'][$label] = round($earned, 12);
|
$label = app('navigation')->periodShow($current, $step);
|
||||||
$chartData[2]['entries'][$label] = round($sum, 12);
|
$chartData[0]['entries'][$label] = round(bcmul($spent, '-1'), 12);
|
||||||
$start = app('navigation')->addPeriod($start, $range, 0);
|
$chartData[1]['entries'][$label] = round($earned, 12);
|
||||||
|
$chartData[2]['entries'][$label] = round($sum, 12);
|
||||||
|
$current->addDay();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '1W':
|
||||||
|
case '1M':
|
||||||
|
case '1Y':
|
||||||
|
while ($current <= $end) {
|
||||||
|
$currentEnd = app('navigation')->endOfPeriod($current, $range);
|
||||||
|
$spent = $repository->spentInPeriod(new Collection([$category]), $accounts, $current, $currentEnd);
|
||||||
|
$earned = $repository->earnedInPeriod(new Collection([$category]), $accounts, $current, $currentEnd);
|
||||||
|
$sum = bcadd($spent, $earned);
|
||||||
|
$label = app('navigation')->periodShow($current, $step);
|
||||||
|
$chartData[0]['entries'][$label] = round(bcmul($spent, '-1'), 12);
|
||||||
|
$chartData[1]['entries'][$label] = round($earned, 12);
|
||||||
|
$chartData[2]['entries'][$label] = round($sum, 12);
|
||||||
|
$current= app('navigation')->addPeriod($current, $step, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = $this->generator->multiSet($chartData);
|
$data = $this->generator->multiSet($chartData);
|
||||||
@@ -135,7 +156,7 @@ class CategoryController extends Controller
|
|||||||
$cache->addProperty($end);
|
$cache->addProperty($end);
|
||||||
$cache->addProperty('chart.category.frontpage');
|
$cache->addProperty('chart.category.frontpage');
|
||||||
if ($cache->has()) {
|
if ($cache->has()) {
|
||||||
//return response()->json($cache->get()); // @codeCoverageIgnore
|
return response()->json($cache->get()); // @codeCoverageIgnore
|
||||||
}
|
}
|
||||||
|
|
||||||
// currency repos:
|
// currency repos:
|
||||||
@@ -168,7 +189,7 @@ class CategoryController extends Controller
|
|||||||
$noCategory = $repository->spentInPeriodPcWoCategory(new Collection, $start, $end);
|
$noCategory = $repository->spentInPeriodPcWoCategory(new Collection, $start, $end);
|
||||||
foreach ($noCategory as $currencyId => $spent) {
|
foreach ($noCategory as $currencyId => $spent) {
|
||||||
$currencies[$currencyId] = $currencies[$currencyId] ?? $currencyRepository->findNull($currencyId);
|
$currencies[$currencyId] = $currencies[$currencyId] ?? $currencyRepository->findNull($currencyId);
|
||||||
$tempData[] = [
|
$tempData[] = [
|
||||||
'name' => trans('firefly.no_category'),
|
'name' => trans('firefly.no_category'),
|
||||||
'spent' => bcmul($spent, '-1'),
|
'spent' => bcmul($spent, '-1'),
|
||||||
'spent_float' => (float)bcmul($spent, '-1'),
|
'spent_float' => (float)bcmul($spent, '-1'),
|
||||||
|
@@ -192,7 +192,7 @@ class TagController extends Controller
|
|||||||
'firefly.journals_in_period_for_tag', ['tag' => $tag->tag, 'start' => $start->formatLocalized($this->monthAndDayFormat),
|
'firefly.journals_in_period_for_tag', ['tag' => $tag->tag, 'start' => $start->formatLocalized($this->monthAndDayFormat),
|
||||||
'end' => $end->formatLocalized($this->monthAndDayFormat),]
|
'end' => $end->formatLocalized($this->monthAndDayFormat),]
|
||||||
);
|
);
|
||||||
$periods = $this->getTagPeriodOverview($tag);
|
$periods = $this->getTagPeriodOverview($tag, $start);
|
||||||
$path = route('tags.show', [$tag->id, $start->format('Y-m-d'), $end->format('Y-m-d')]);
|
$path = route('tags.show', [$tag->id, $start->format('Y-m-d'), $end->format('Y-m-d')]);
|
||||||
|
|
||||||
/** @var TransactionCollectorInterface $collector */
|
/** @var TransactionCollectorInterface $collector */
|
||||||
|
@@ -92,6 +92,23 @@ class TagRepository implements TagRepositoryInterface
|
|||||||
return (string)$set->sum('transaction_amount');
|
return (string)$set->sum('transaction_amount');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Tag $tag
|
||||||
|
* @param Carbon $start
|
||||||
|
* @param Carbon $end
|
||||||
|
*
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function expenseInPeriod(Tag $tag, Carbon $start, Carbon $end): Collection
|
||||||
|
{
|
||||||
|
/** @var TransactionCollectorInterface $collector */
|
||||||
|
$collector = app(TransactionCollectorInterface::class);
|
||||||
|
$collector->setUser($this->user);
|
||||||
|
$collector->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])->setAllAssetAccounts()->setTag($tag);
|
||||||
|
|
||||||
|
return $collector->getTransactions();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $tag
|
* @param string $tag
|
||||||
*
|
*
|
||||||
@@ -151,6 +168,23 @@ class TagRepository implements TagRepositoryInterface
|
|||||||
return $tags;
|
return $tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Tag $tag
|
||||||
|
* @param Carbon $start
|
||||||
|
* @param Carbon $end
|
||||||
|
*
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function incomeInPeriod(Tag $tag, Carbon $start, Carbon $end): Collection
|
||||||
|
{
|
||||||
|
/** @var TransactionCollectorInterface $collector */
|
||||||
|
$collector = app(TransactionCollectorInterface::class);
|
||||||
|
$collector->setUser($this->user);
|
||||||
|
$collector->setRange($start, $end)->setTypes([TransactionType::DEPOSIT])->setAllAssetAccounts()->setTag($tag);
|
||||||
|
|
||||||
|
return $collector->getTransactions();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Tag $tag
|
* @param Tag $tag
|
||||||
*
|
*
|
||||||
@@ -315,6 +349,23 @@ class TagRepository implements TagRepositoryInterface
|
|||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Tag $tag
|
||||||
|
* @param Carbon $start
|
||||||
|
* @param Carbon $end
|
||||||
|
*
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function transferredInPeriod(Tag $tag, Carbon $start, Carbon $end): Collection
|
||||||
|
{
|
||||||
|
/** @var TransactionCollectorInterface $collector */
|
||||||
|
$collector = app(TransactionCollectorInterface::class);
|
||||||
|
$collector->setUser($this->user);
|
||||||
|
$collector->setRange($start, $end)->setTypes([TransactionType::TRANSFER])->setAllAssetAccounts()->setTag($tag);
|
||||||
|
|
||||||
|
return $collector->getTransactions();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Tag $tag
|
* @param Tag $tag
|
||||||
* @param array $data
|
* @param array $data
|
||||||
|
@@ -55,6 +55,15 @@ interface TagRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function earnedInPeriod(Tag $tag, Carbon $start, Carbon $end): string;
|
public function earnedInPeriod(Tag $tag, Carbon $start, Carbon $end): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Tag $tag
|
||||||
|
* @param Carbon $start
|
||||||
|
* @param Carbon $end
|
||||||
|
*
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function expenseInPeriod(Tag $tag, Carbon $start, Carbon $end): Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $tag
|
* @param string $tag
|
||||||
*
|
*
|
||||||
@@ -83,6 +92,15 @@ interface TagRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function get(): Collection;
|
public function get(): Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Tag $tag
|
||||||
|
* @param Carbon $start
|
||||||
|
* @param Carbon $end
|
||||||
|
*
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function incomeInPeriod(Tag $tag, Carbon $start, Carbon $end): Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Tag $tag
|
* @param Tag $tag
|
||||||
*
|
*
|
||||||
@@ -147,6 +165,15 @@ interface TagRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function tagCloud(?int $year): array;
|
public function tagCloud(?int $year): array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Tag $tag
|
||||||
|
* @param Carbon $start
|
||||||
|
* @param Carbon $end
|
||||||
|
*
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function transferredInPeriod(Tag $tag, Carbon $start, Carbon $end): Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update a tag.
|
* Update a tag.
|
||||||
*
|
*
|
||||||
|
@@ -60,12 +60,14 @@ trait PeriodOverview
|
|||||||
* and for each period, the amount of money spent and earned. This is a complex operation which is cached for
|
* and for each period, the amount of money spent and earned. This is a complex operation which is cached for
|
||||||
* performance reasons.
|
* performance reasons.
|
||||||
*
|
*
|
||||||
* @param Account $account the account involved
|
* The method has been refactored recently for better performance.
|
||||||
* @param Carbon $date
|
*
|
||||||
|
* @param Account $account The account involved
|
||||||
|
* @param Carbon $date The start date.
|
||||||
*
|
*
|
||||||
* @return Collection
|
* @return Collection
|
||||||
*/
|
*/
|
||||||
protected function getAccountPeriodOverview(Account $account, Carbon $date): Collection // period overview
|
protected function getAccountPeriodOverview(Account $account, Carbon $date): Collection
|
||||||
{
|
{
|
||||||
/** @var AccountRepositoryInterface $repository */
|
/** @var AccountRepositoryInterface $repository */
|
||||||
$repository = app(AccountRepositoryInterface::class);
|
$repository = app(AccountRepositoryInterface::class);
|
||||||
@@ -95,15 +97,15 @@ trait PeriodOverview
|
|||||||
$collector = app(TransactionCollectorInterface::class);
|
$collector = app(TransactionCollectorInterface::class);
|
||||||
$collector->setAccounts(new Collection([$account]))->setRange($currentDate['start'], $currentDate['end'])->setTypes([TransactionType::DEPOSIT])
|
$collector->setAccounts(new Collection([$account]))->setRange($currentDate['start'], $currentDate['end'])->setTypes([TransactionType::DEPOSIT])
|
||||||
->withOpposingAccount();
|
->withOpposingAccount();
|
||||||
$set = $collector->getTransactions();
|
$earnedSet = $collector->getTransactions();
|
||||||
$earned = $this->groupByCurrency($set);
|
$earned = $this->groupByCurrency($earnedSet);
|
||||||
|
|
||||||
/** @var TransactionCollectorInterface $collector */
|
/** @var TransactionCollectorInterface $collector */
|
||||||
$collector = app(TransactionCollectorInterface::class);
|
$collector = app(TransactionCollectorInterface::class);
|
||||||
$collector->setAccounts(new Collection([$account]))->setRange($currentDate['start'], $currentDate['end'])->setTypes([TransactionType::WITHDRAWAL])
|
$collector->setAccounts(new Collection([$account]))->setRange($currentDate['start'], $currentDate['end'])->setTypes([TransactionType::WITHDRAWAL])
|
||||||
->withOpposingAccount();
|
->withOpposingAccount();
|
||||||
$set = $collector->getTransactions();
|
$spentSet = $collector->getTransactions();
|
||||||
$spent = $this->groupByCurrency($set);
|
$spent = $this->groupByCurrency($spentSet);
|
||||||
|
|
||||||
$title = app('navigation')->periodShow($currentDate['start'], $currentDate['period']);
|
$title = app('navigation')->periodShow($currentDate['start'], $currentDate['period']);
|
||||||
/** @noinspection PhpUndefinedMethodInspection */
|
/** @noinspection PhpUndefinedMethodInspection */
|
||||||
@@ -115,7 +117,6 @@ trait PeriodOverview
|
|||||||
'earned' => $earned,
|
'earned' => $earned,
|
||||||
'transferred' => '0',
|
'transferred' => '0',
|
||||||
'route' => route('accounts.show', [$account->id, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
|
'route' => route('accounts.show', [$account->id, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
|
||||||
|
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -126,11 +127,84 @@ trait PeriodOverview
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets period overview used for budgets.
|
* Overview for single category. Has been refactored recently.
|
||||||
|
*
|
||||||
|
* @param Category $category
|
||||||
|
* @param Carbon $date
|
||||||
*
|
*
|
||||||
* @return Collection
|
* @return Collection
|
||||||
*/
|
*/
|
||||||
protected function getBudgetPeriodOverview(Carbon $date): Collection
|
protected function getCategoryPeriodOverview(Category $category, Carbon $date): Collection
|
||||||
|
{
|
||||||
|
/** @var JournalRepositoryInterface $journalRepository */
|
||||||
|
$journalRepository = app(JournalRepositoryInterface::class);
|
||||||
|
$range = app('preferences')->get('viewRange', '1M')->data;
|
||||||
|
$first = $journalRepository->firstNull();
|
||||||
|
$end = null === $first ? new Carbon : $first->date;
|
||||||
|
$start = clone $date;
|
||||||
|
|
||||||
|
if ($end < $start) {
|
||||||
|
[$start, $end] = [$end, $start]; // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
|
||||||
|
// properties for entries with their amounts.
|
||||||
|
$cache = new CacheProperties();
|
||||||
|
$cache->addProperty($start);
|
||||||
|
$cache->addProperty($end);
|
||||||
|
$cache->addProperty($range);
|
||||||
|
$cache->addProperty('category-show-period-entries');
|
||||||
|
$cache->addProperty($category->id);
|
||||||
|
|
||||||
|
if ($cache->has()) {
|
||||||
|
return $cache->get(); // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
/** @var array $dates */
|
||||||
|
$dates = app('navigation')->blockPeriods($start, $end, $range);
|
||||||
|
$entries = new Collection;
|
||||||
|
/** @var CategoryRepositoryInterface $categoryRepository */
|
||||||
|
$categoryRepository = app(CategoryRepositoryInterface::class);
|
||||||
|
|
||||||
|
foreach ($dates as $currentDate) {
|
||||||
|
$spent = $categoryRepository->spentInPeriodCollection(new Collection([$category]), new Collection, $currentDate['start'], $currentDate['end']);
|
||||||
|
$earned = $categoryRepository->earnedInPeriodCollection(new Collection([$category]), new Collection, $currentDate['start'], $currentDate['end']);
|
||||||
|
$spent = $this->groupByCurrency($spent);
|
||||||
|
$earned = $this->groupByCurrency($earned);
|
||||||
|
|
||||||
|
// amount transferred
|
||||||
|
/** @var TransactionCollectorInterface $collector */
|
||||||
|
$collector = app(TransactionCollectorInterface::class);
|
||||||
|
$collector->setAllAssetAccounts()->setRange($currentDate['start'], $currentDate['end'])->setCategory($category)
|
||||||
|
->withOpposingAccount()->setTypes([TransactionType::TRANSFER]);
|
||||||
|
$collector->removeFilter(InternalTransferFilter::class);
|
||||||
|
$transferred = $this->groupByCurrency($collector->getTransactions());
|
||||||
|
|
||||||
|
$title = app('navigation')->periodShow($currentDate['end'], $currentDate['period']);
|
||||||
|
$entries->push(
|
||||||
|
[
|
||||||
|
'transactions' => 0,
|
||||||
|
'title' => $title,
|
||||||
|
'spent' => $spent,
|
||||||
|
'earned' => $earned,
|
||||||
|
'transferred' => $transferred,
|
||||||
|
'route' => route('categories.show', [$category->id, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$cache->store($entries);
|
||||||
|
|
||||||
|
return $entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same as above, but for lists that involve transactions without a budget.
|
||||||
|
*
|
||||||
|
* This method has been refactored recently.
|
||||||
|
*
|
||||||
|
* @param Carbon $date
|
||||||
|
*
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
protected function getNoBudgetPeriodOverview(Carbon $date): Collection
|
||||||
{
|
{
|
||||||
/** @var JournalRepositoryInterface $repository */
|
/** @var JournalRepositoryInterface $repository */
|
||||||
$repository = app(JournalRepositoryInterface::class);
|
$repository = app(JournalRepositoryInterface::class);
|
||||||
@@ -138,8 +212,12 @@ trait PeriodOverview
|
|||||||
$end = null === $first ? new Carbon : $first->date;
|
$end = null === $first ? new Carbon : $first->date;
|
||||||
$start = clone $date;
|
$start = clone $date;
|
||||||
$range = app('preferences')->get('viewRange', '1M')->data;
|
$range = app('preferences')->get('viewRange', '1M')->data;
|
||||||
$entries = new Collection;
|
|
||||||
$cache = new CacheProperties;
|
if ($end < $start) {
|
||||||
|
[$start, $end] = [$end, $start]; // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
|
||||||
|
$cache = new CacheProperties;
|
||||||
$cache->addProperty($start);
|
$cache->addProperty($start);
|
||||||
$cache->addProperty($end);
|
$cache->addProperty($end);
|
||||||
$cache->addProperty('no-budget-period-entries');
|
$cache->addProperty('no-budget-period-entries');
|
||||||
@@ -149,7 +227,8 @@ trait PeriodOverview
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @var array $dates */
|
/** @var array $dates */
|
||||||
$dates = app('navigation')->blockPeriods($start, $end, $range);
|
$dates = app('navigation')->blockPeriods($start, $end, $range);
|
||||||
|
$entries = new Collection;
|
||||||
foreach ($dates as $currentDate) {
|
foreach ($dates as $currentDate) {
|
||||||
/** @var TransactionCollectorInterface $collector */
|
/** @var TransactionCollectorInterface $collector */
|
||||||
$collector = app(TransactionCollectorInterface::class);
|
$collector = app(TransactionCollectorInterface::class);
|
||||||
@@ -162,12 +241,12 @@ trait PeriodOverview
|
|||||||
$title = app('navigation')->periodShow($currentDate['end'], $currentDate['period']);
|
$title = app('navigation')->periodShow($currentDate['end'], $currentDate['period']);
|
||||||
$entries->push(
|
$entries->push(
|
||||||
[
|
[
|
||||||
'route' => route('budgets.no-budget', [$currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
|
|
||||||
'transactions' => $count,
|
'transactions' => $count,
|
||||||
'title' => $title,
|
'title' => $title,
|
||||||
'spent' => $spent,
|
'spent' => $spent,
|
||||||
'earned' => '0',
|
'earned' => '0',
|
||||||
'transferred' => '0',
|
'transferred' => '0',
|
||||||
|
'route' => route('budgets.no-budget', [$currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -177,133 +256,70 @@ trait PeriodOverview
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a period overview for category.
|
* This shows a period overview for a tag. It goes back in time and lists all relevant transactions and sums.
|
||||||
*
|
|
||||||
* TODO refactor me.
|
|
||||||
*
|
|
||||||
* @param Category $category
|
|
||||||
* @param Carbon $date
|
|
||||||
*
|
|
||||||
* @return Collection
|
|
||||||
*/
|
|
||||||
protected function getCategoryPeriodOverview(Category $category, Carbon $date): Collection // periodOverview method
|
|
||||||
{
|
|
||||||
/** @var JournalRepositoryInterface $journalRepository */
|
|
||||||
$journalRepository = app(JournalRepositoryInterface::class);
|
|
||||||
/** @var CategoryRepositoryInterface $categoryRepository */
|
|
||||||
$categoryRepository = app(CategoryRepositoryInterface::class);
|
|
||||||
|
|
||||||
|
|
||||||
$range = app('preferences')->get('viewRange', '1M')->data;
|
|
||||||
$first = $journalRepository->firstNull();
|
|
||||||
$end = null === $first ? new Carbon : $first->date;
|
|
||||||
$start = clone $date;
|
|
||||||
|
|
||||||
// properties for entries with their amounts.
|
|
||||||
$cache = new CacheProperties();
|
|
||||||
$cache->addProperty($start);
|
|
||||||
$cache->addProperty($end);
|
|
||||||
$cache->addProperty($range);
|
|
||||||
$cache->addProperty('categories.entries');
|
|
||||||
$cache->addProperty($category->id);
|
|
||||||
|
|
||||||
if ($cache->has()) {
|
|
||||||
//return $cache->get(); // @codeCoverageIgnore
|
|
||||||
}
|
|
||||||
/** @var array $dates */
|
|
||||||
$dates = app('navigation')->blockPeriods($start, $end, $range);
|
|
||||||
$entries = new Collection;
|
|
||||||
|
|
||||||
foreach ($dates as $currentDate) {
|
|
||||||
$spent = $categoryRepository->spentInPeriodCollection(new Collection([$category]), new Collection, $currentDate['start'], $currentDate['end']);
|
|
||||||
$earned = $categoryRepository->earnedInPeriodCollection(new Collection([$category]), new Collection, $currentDate['start'], $currentDate['end']);
|
|
||||||
$spent = $this->groupByCurrency($spent);
|
|
||||||
$earned = $this->groupByCurrency($earned);
|
|
||||||
// amount transferred
|
|
||||||
/** @var TransactionCollectorInterface $collector */
|
|
||||||
$collector = app(TransactionCollectorInterface::class);
|
|
||||||
$collector->setAllAssetAccounts()->setRange($currentDate['start'], $currentDate['end'])->setCategory($category)
|
|
||||||
->withOpposingAccount()->setTypes([TransactionType::TRANSFER]);
|
|
||||||
$collector->removeFilter(InternalTransferFilter::class);
|
|
||||||
$transferred = $this->groupByCurrency($collector->getTransactions());
|
|
||||||
$title = app('navigation')->periodShow($currentDate['end'], $currentDate['period']);
|
|
||||||
$entries->push(
|
|
||||||
[
|
|
||||||
'route' => route('categories.show', [$category->id, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
|
|
||||||
'title' => $title,
|
|
||||||
'spent' => $spent,
|
|
||||||
'earned' => $earned,
|
|
||||||
'transferred' => $transferred,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
$cache->store($entries);
|
|
||||||
|
|
||||||
return $entries;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get overview of periods for tag.
|
|
||||||
*
|
|
||||||
* TODO refactor this.
|
|
||||||
*
|
*
|
||||||
* @param Tag $tag
|
* @param Tag $tag
|
||||||
*
|
*
|
||||||
* @return Collection
|
* @return Collection
|
||||||
*/
|
*/
|
||||||
protected function getTagPeriodOverview(Tag $tag): Collection // period overview for tags.
|
protected function getTagPeriodOverview(Tag $tag, Carbon $date): Collection // period overview for tags.
|
||||||
{
|
{
|
||||||
/** @var TagRepositoryInterface $repository */
|
/** @var TagRepositoryInterface $repository */
|
||||||
$repository = app(TagRepositoryInterface::class);
|
$repository = app(TagRepositoryInterface::class);
|
||||||
// get first and last tag date from tag:
|
$range = app('preferences')->get('viewRange', '1M')->data;
|
||||||
$range = app('preferences')->get('viewRange', '1M')->data;
|
|
||||||
/** @var Carbon $end */
|
/** @var Carbon $end */
|
||||||
$end = app('navigation')->endOfX($repository->lastUseDate($tag) ?? new Carbon, $range, null);
|
$start = clone $date;
|
||||||
$start = $repository->firstUseDate($tag) ?? new Carbon;
|
$end = $repository->firstUseDate($tag) ?? new Carbon;
|
||||||
|
|
||||||
|
|
||||||
|
if ($end < $start) {
|
||||||
|
[$start, $end] = [$end, $start]; // @codeCoverageIgnore
|
||||||
|
}
|
||||||
|
|
||||||
// properties for entries with their amounts.
|
// properties for entries with their amounts.
|
||||||
$cache = new CacheProperties;
|
$cache = new CacheProperties;
|
||||||
$cache->addProperty($start);
|
$cache->addProperty($start);
|
||||||
$cache->addProperty($end);
|
$cache->addProperty($end);
|
||||||
$cache->addProperty('tag.entries');
|
$cache->addProperty('tag-period-entries');
|
||||||
$cache->addProperty($tag->id);
|
$cache->addProperty($tag->id);
|
||||||
|
|
||||||
if ($cache->has()) {
|
if ($cache->has()) {
|
||||||
return $cache->get(); // @codeCoverageIgnore
|
return $cache->get(); // @codeCoverageIgnore
|
||||||
}
|
}
|
||||||
|
|
||||||
$collection = new Collection;
|
/** @var array $dates */
|
||||||
$currentEnd = clone $end;
|
$dates = app('navigation')->blockPeriods($start, $end, $range);
|
||||||
|
$entries = new Collection;
|
||||||
// while end larger or equal to start
|
// while end larger or equal to start
|
||||||
while ($currentEnd >= $start) {
|
foreach ($dates as $currentDate) {
|
||||||
$currentStart = app('navigation')->startOfPeriod($currentEnd, $range);
|
|
||||||
|
|
||||||
// get expenses and what-not in this period and this tag.
|
$spentSet = $repository->expenseInPeriod($tag, $currentDate['start'], $currentDate['end']);
|
||||||
$arr = [
|
$spent = $this->groupByCurrency($spentSet);
|
||||||
'string' => $end->format('Y-m-d'),
|
$earnedSet = $repository->incomeInPeriod($tag, $currentDate['start'], $currentDate['end']);
|
||||||
'name' => app('navigation')->periodShow($currentEnd, $range),
|
$earned = $this->groupByCurrency($earnedSet);
|
||||||
'start' => clone $currentStart,
|
$transferredSet = $repository->transferredInPeriod($tag, $currentDate['start'], $currentDate['end']);
|
||||||
'end' => clone $currentEnd,
|
$transferred = $this->groupByCurrency($transferredSet);
|
||||||
'date' => clone $end,
|
$title = app('navigation')->periodShow($currentDate['end'], $currentDate['period']);
|
||||||
'spent' => $repository->spentInPeriod($tag, $currentStart, $currentEnd),
|
|
||||||
'earned' => $repository->earnedInPeriod($tag, $currentStart, $currentEnd),
|
$entries->push(
|
||||||
];
|
[
|
||||||
$collection->push($arr);
|
'transactions' => $spentSet->count() + $earnedSet->count() + $transferredSet->count(),
|
||||||
|
'title' => $title,
|
||||||
|
'spent' => $spent,
|
||||||
|
'earned' => $earned,
|
||||||
|
'transferred' => $transferred,
|
||||||
|
'route' => route('tags.show', [$tag->id, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
/** @var Carbon $currentEnd */
|
|
||||||
$currentEnd = clone $currentStart;
|
|
||||||
$currentEnd->subDay();
|
|
||||||
}
|
}
|
||||||
$cache->store($collection);
|
$cache->store($entries);
|
||||||
|
|
||||||
return $collection;
|
return $entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get period overview for index.
|
* This list shows the overview of a type of transaction, for the period blocks on the list of transactions.
|
||||||
*
|
|
||||||
* TODO refactor me.
|
|
||||||
*
|
*
|
||||||
* @param string $what
|
* @param string $what
|
||||||
* @param Carbon $date
|
* @param Carbon $date
|
||||||
@@ -315,42 +331,60 @@ trait PeriodOverview
|
|||||||
/** @var JournalRepositoryInterface $repository */
|
/** @var JournalRepositoryInterface $repository */
|
||||||
$repository = app(JournalRepositoryInterface::class);
|
$repository = app(JournalRepositoryInterface::class);
|
||||||
$range = app('preferences')->get('viewRange', '1M')->data;
|
$range = app('preferences')->get('viewRange', '1M')->data;
|
||||||
$first = $repository->firstNull();
|
$endJournal = $repository->firstNull();
|
||||||
$start = Carbon::now()->subYear();
|
$end = null === $endJournal ? new Carbon : $endJournal->date;
|
||||||
|
$start = clone $date;
|
||||||
$types = config('firefly.transactionTypesByWhat.' . $what);
|
$types = config('firefly.transactionTypesByWhat.' . $what);
|
||||||
$entries = new Collection;
|
|
||||||
if (null !== $first) {
|
|
||||||
$start = $first->date;
|
if ($end < $start) {
|
||||||
}
|
[$start, $end] = [$end, $start]; // @codeCoverageIgnore
|
||||||
if ($date < $start) {
|
|
||||||
[$start, $date] = [$date, $start]; // @codeCoverageIgnore
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// properties for entries with their amounts.
|
||||||
|
$cache = new CacheProperties;
|
||||||
|
$cache->addProperty($start);
|
||||||
|
$cache->addProperty($end);
|
||||||
|
$cache->addProperty('transactions-period-entries');
|
||||||
|
$cache->addProperty($what);
|
||||||
|
|
||||||
|
|
||||||
/** @var array $dates */
|
/** @var array $dates */
|
||||||
$dates = app('navigation')->blockPeriods($start, $date, $range);
|
$dates = app('navigation')->blockPeriods($start, $end, $range);
|
||||||
|
$entries = new Collection;
|
||||||
|
|
||||||
foreach ($dates as $currentDate) {
|
foreach ($dates as $currentDate) {
|
||||||
|
|
||||||
|
// get all expenses, income or transfers:
|
||||||
/** @var TransactionCollectorInterface $collector */
|
/** @var TransactionCollectorInterface $collector */
|
||||||
$collector = app(TransactionCollectorInterface::class);
|
$collector = app(TransactionCollectorInterface::class);
|
||||||
$collector->setAllAssetAccounts()->setRange($currentDate['start'], $currentDate['end'])->withOpposingAccount()->setTypes($types);
|
$collector->setAllAssetAccounts()->setRange($currentDate['start'], $currentDate['end'])->withOpposingAccount()->setTypes($types);
|
||||||
$collector->removeFilter(InternalTransferFilter::class);
|
$collector->removeFilter(InternalTransferFilter::class);
|
||||||
$transactions = $collector->getTransactions();
|
$transactions = $collector->getTransactions();
|
||||||
|
$title = app('navigation')->periodShow($currentDate['end'], $currentDate['period']);
|
||||||
if ($transactions->count() > 0) {
|
$grouped = $this->groupByCurrency($transactions);
|
||||||
$sums = $this->sumPerCurrency($transactions);
|
$spent = [];
|
||||||
$dateName = app('navigation')->periodShow($currentDate['start'], $currentDate['period']);
|
$earned = [];
|
||||||
$sum = $transactions->sum('transaction_amount');
|
$transferred = [];
|
||||||
/** @noinspection PhpUndefinedMethodInspection */
|
if ('expenses' === $what || 'withdrawal' === $what) {
|
||||||
$entries->push(
|
$spent = $grouped;
|
||||||
[
|
|
||||||
'name' => $dateName,
|
|
||||||
'sums' => $sums,
|
|
||||||
'sum' => $sum,
|
|
||||||
'start' => $currentDate['start']->format('Y-m-d'),
|
|
||||||
'end' => $currentDate['end']->format('Y-m-d'),
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
if ('revenue' === $what || 'deposit' === $what) {
|
||||||
|
$earned = $grouped;
|
||||||
|
}
|
||||||
|
if ('transfer' === $what || 'transfers' === $what) {
|
||||||
|
$transferred = $grouped;
|
||||||
|
}
|
||||||
|
$entries->push(
|
||||||
|
[
|
||||||
|
'transactions' => $transactions->count(),
|
||||||
|
'title' => $title,
|
||||||
|
'spent' => $spent,
|
||||||
|
'earned' => $earned,
|
||||||
|
'transferred' => $transferred,
|
||||||
|
'route' => route('transactions.index', [$what, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
|
||||||
|
]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $entries;
|
return $entries;
|
||||||
|
@@ -41,4 +41,5 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
@@ -154,33 +154,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{% if periods.count > 0 %}
|
{% if periods.count > 0 %}
|
||||||
<div class="col-lg-2 col-md-2 col-sm-12 col-xs-12">
|
<div class="col-lg-2 col-md-2 col-sm-12 col-xs-12">
|
||||||
{% for period in periods %}
|
{% include 'list.periods' %}
|
||||||
{% if period.spent != 0 or period.earned != 0 %}
|
|
||||||
<div class="box {% if period.date == start %}box-solid box-primary{% endif %}">
|
|
||||||
<div class="box-header with-border">
|
|
||||||
<h3 class="box-title"><a href="{{ route('tags.show',[tag.id, period.start.format('Y-m-d'), period.end.format('Y-m-d')]) }}">{{ period.name }}</a>
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
<div class="box-body no-padding">
|
|
||||||
<table class="table table-hover">
|
|
||||||
{% if period.spent != 0 %}
|
|
||||||
<tr>
|
|
||||||
<td style="width:33%;">{{ 'spent'|_ }}</td>
|
|
||||||
<td style="text-align: right;">{{ period.spent|formatAmount }}</td>
|
|
||||||
</tr>
|
|
||||||
{% endif %}
|
|
||||||
{% if period.earned != 0 %}
|
|
||||||
<tr>
|
|
||||||
<td style="width:33%;">{{ 'earned'|_ }}</td>
|
|
||||||
<td style="text-align: right;">{{ period.earned|formatAmount }}</td>
|
|
||||||
</tr>
|
|
||||||
{% endif %}
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
@@ -58,47 +58,7 @@
|
|||||||
{# boxes with info #}
|
{# boxes with info #}
|
||||||
{% if periods.count > 0 %}
|
{% if periods.count > 0 %}
|
||||||
<div class="col-lg-2 col-md-2 col-sm-12 col-xs-12">
|
<div class="col-lg-2 col-md-2 col-sm-12 col-xs-12">
|
||||||
{% for period in periods %}
|
{% include 'list.periods' %}
|
||||||
|
|
||||||
{% if period.sum != 0 %}
|
|
||||||
<div class="box">
|
|
||||||
<div class="box-header with-border">
|
|
||||||
<h3 class="box-title"><a href="{{ route('transactions.index',[what, period.start,period.end]) }}">{{ period.name }}</a>
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
<div class="box-body no-padding">
|
|
||||||
<table class="table table-hover">
|
|
||||||
<tbody>
|
|
||||||
{% for sum in period.sums %}
|
|
||||||
<tr>
|
|
||||||
<td style="width:33%;">
|
|
||||||
{% if what == 'withdrawal' %}
|
|
||||||
{{ 'spent'|_ }}
|
|
||||||
{% endif %}
|
|
||||||
{% if what == 'deposit' %}
|
|
||||||
{{ 'earned'|_ }}
|
|
||||||
{% endif %}
|
|
||||||
{% if what == 'transfers' or what == 'transfer' %}
|
|
||||||
{{ 'transferred'|_ }}
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
<td style="text-align: right;" title="{{ trans('list.number_of_transactions') }}: {{ sum.count }}">
|
|
||||||
{% if what == 'transfers' or what == 'transfer' %}
|
|
||||||
<span class="text-info">
|
|
||||||
{{ formatAmountBySymbol(Steam.positive(sum.sum), sum.currency.symbol, sum.currency.dp, false) }}
|
|
||||||
</span>
|
|
||||||
{% else %}
|
|
||||||
{{ formatAmountBySymbol(sum.sum, sum.currency.symbol, sum.currency.dp) }}
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user