mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-10-15 16:57:09 +00:00
Add table for period statistics, and see what happens re: performance.
This commit is contained in:
@@ -241,4 +241,12 @@ class Account extends Model
|
|||||||
get: static fn ($value) => (string)$value,
|
get: static fn ($value) => (string)$value,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function primaryPeriodStatistics(): MorphMany
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
return $this->morphMany(PeriodStatistic::class, 'primary_statable');
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
56
app/Models/PeriodStatistic.php
Normal file
56
app/Models/PeriodStatistic.php
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace FireflyIII\Models;
|
||||||
|
|
||||||
|
use FireflyIII\Casts\SeparateTimezoneCaster;
|
||||||
|
use FireflyIII\Support\Models\ReturnsIntegerUserIdTrait;
|
||||||
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class PeriodStatistic extends Model
|
||||||
|
{
|
||||||
|
use SoftDeletes;
|
||||||
|
use ReturnsIntegerUserIdTrait;
|
||||||
|
|
||||||
|
protected function casts(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'created_at' => 'datetime',
|
||||||
|
'updated_at' => 'datetime',
|
||||||
|
'deleted_at' => 'datetime',
|
||||||
|
'date' => SeparateTimezoneCaster::class,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function count(): Attribute
|
||||||
|
{
|
||||||
|
return Attribute::make(
|
||||||
|
get: static fn ($value) => (int)$value,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function primaryStatable(): MorphTo
|
||||||
|
{
|
||||||
|
|
||||||
|
return $this->morphTo();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function secondaryStatable(): MorphTo
|
||||||
|
{
|
||||||
|
|
||||||
|
return $this->morphTo();
|
||||||
|
|
||||||
|
}
|
||||||
|
public function tertiaryStatable(): MorphTo
|
||||||
|
{
|
||||||
|
|
||||||
|
return $this->morphTo();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
}
|
@@ -43,6 +43,8 @@ use FireflyIII\Repositories\AuditLogEntry\ALERepository;
|
|||||||
use FireflyIII\Repositories\AuditLogEntry\ALERepositoryInterface;
|
use FireflyIII\Repositories\AuditLogEntry\ALERepositoryInterface;
|
||||||
use FireflyIII\Repositories\ObjectGroup\ObjectGroupRepository;
|
use FireflyIII\Repositories\ObjectGroup\ObjectGroupRepository;
|
||||||
use FireflyIII\Repositories\ObjectGroup\ObjectGroupRepositoryInterface;
|
use FireflyIII\Repositories\ObjectGroup\ObjectGroupRepositoryInterface;
|
||||||
|
use FireflyIII\Repositories\PeriodStatistic\PeriodStatisticRepository;
|
||||||
|
use FireflyIII\Repositories\PeriodStatistic\PeriodStatisticRepositoryInterface;
|
||||||
use FireflyIII\Repositories\TransactionType\TransactionTypeRepository;
|
use FireflyIII\Repositories\TransactionType\TransactionTypeRepository;
|
||||||
use FireflyIII\Repositories\TransactionType\TransactionTypeRepositoryInterface;
|
use FireflyIII\Repositories\TransactionType\TransactionTypeRepositoryInterface;
|
||||||
use FireflyIII\Repositories\User\UserRepository;
|
use FireflyIII\Repositories\User\UserRepository;
|
||||||
@@ -161,6 +163,7 @@ class FireflyServiceProvider extends ServiceProvider
|
|||||||
|
|
||||||
$this->app->bind(AttachmentHelperInterface::class, AttachmentHelper::class);
|
$this->app->bind(AttachmentHelperInterface::class, AttachmentHelper::class);
|
||||||
$this->app->bind(ALERepositoryInterface::class, ALERepository::class);
|
$this->app->bind(ALERepositoryInterface::class, ALERepository::class);
|
||||||
|
$this->app->bind(PeriodStatisticRepositoryInterface::class, PeriodStatisticRepository::class);
|
||||||
|
|
||||||
$this->app->bind(
|
$this->app->bind(
|
||||||
static function (Application $app): ObjectGroupRepositoryInterface {
|
static function (Application $app): ObjectGroupRepositoryInterface {
|
||||||
|
@@ -0,0 +1,65 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* PeriodStatisticRepository.php
|
||||||
|
* Copyright (c) 2025 james@firefly-iii.org
|
||||||
|
*
|
||||||
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace FireflyIII\Repositories\PeriodStatistic;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use FireflyIII\Models\PeriodStatistic;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
class PeriodStatisticRepository implements PeriodStatisticRepositoryInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
public function findPeriodStatistics(Model $model, Carbon $start, Carbon $end, array $types): Collection
|
||||||
|
{
|
||||||
|
return $model->primaryPeriodStatistics()
|
||||||
|
->where('start', $start)
|
||||||
|
->where('end', $end)
|
||||||
|
->whereIn('type', $types)
|
||||||
|
->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findPeriodStatistic(Model $model, Carbon $start, Carbon $end, string $type): Collection
|
||||||
|
{
|
||||||
|
return $model->primaryPeriodStatistics()
|
||||||
|
->where('start', $start)
|
||||||
|
->where('end', $end)
|
||||||
|
->where('type', $type)
|
||||||
|
->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function saveStatistic(Model $model, int $currencyId, Carbon $start, Carbon $end, string $type, int $count, string $amount): PeriodStatistic
|
||||||
|
{
|
||||||
|
$stat = new PeriodStatistic;
|
||||||
|
$stat->primaryStatable()->associate($model);
|
||||||
|
$stat->transaction_currency_id = $currencyId;
|
||||||
|
$stat->start = $start;
|
||||||
|
$stat->start_tz = $start->format('e');
|
||||||
|
$stat->end = $end;
|
||||||
|
$stat->end_tz = $end->format('e');
|
||||||
|
$stat->amount = $amount;
|
||||||
|
$stat->count = $count;
|
||||||
|
$stat->type = $type;
|
||||||
|
$stat->save();
|
||||||
|
return $stat;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* PeriodStatisticRepositoryInterface.php
|
||||||
|
* Copyright (c) 2025 james@firefly-iii.org
|
||||||
|
*
|
||||||
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace FireflyIII\Repositories\PeriodStatistic;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use FireflyIII\Models\PeriodStatistic;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
interface PeriodStatisticRepositoryInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
public function findPeriodStatistics(Model $model, Carbon $start, Carbon $end, array $types): Collection;
|
||||||
|
|
||||||
|
public function findPeriodStatistic(Model $model, Carbon $start, Carbon $end, string $type): Collection;
|
||||||
|
|
||||||
|
public function saveStatistic(Model $model, int $currencyId, Carbon $start, Carbon $end, string $type, int $count, string $amount): PeriodStatistic;
|
||||||
|
|
||||||
|
}
|
@@ -30,11 +30,13 @@ use FireflyIII\Exceptions\FireflyException;
|
|||||||
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
|
||||||
use FireflyIII\Models\Account;
|
use FireflyIII\Models\Account;
|
||||||
use FireflyIII\Models\Category;
|
use FireflyIII\Models\Category;
|
||||||
|
use FireflyIII\Models\PeriodStatistic;
|
||||||
use FireflyIII\Models\Tag;
|
use FireflyIII\Models\Tag;
|
||||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||||
|
use FireflyIII\Repositories\PeriodStatistic\PeriodStatisticRepositoryInterface;
|
||||||
use FireflyIII\Support\CacheProperties;
|
use FireflyIII\Support\CacheProperties;
|
||||||
use FireflyIII\Support\Debug\Timer;
|
use FireflyIII\Support\Facades\Amount;
|
||||||
use FireflyIII\Support\Facades\Navigation;
|
use FireflyIII\Support\Facades\Navigation;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
@@ -67,8 +69,9 @@ use Illuminate\Support\Facades\Log;
|
|||||||
*/
|
*/
|
||||||
trait PeriodOverview
|
trait PeriodOverview
|
||||||
{
|
{
|
||||||
protected AccountRepositoryInterface $accountRepository;
|
protected AccountRepositoryInterface $accountRepository;
|
||||||
protected JournalRepositoryInterface $journalRepos;
|
protected JournalRepositoryInterface $journalRepos;
|
||||||
|
protected PeriodStatisticRepositoryInterface $periodStatisticRepo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns "period entries", so nov-2015, dec-2015, etc. (this depends on the users session range)
|
* This method returns "period entries", so nov-2015, dec-2015, etc. (this depends on the users session range)
|
||||||
@@ -79,71 +82,107 @@ trait PeriodOverview
|
|||||||
*/
|
*/
|
||||||
protected function getAccountPeriodOverview(Account $account, Carbon $start, Carbon $end): array
|
protected function getAccountPeriodOverview(Account $account, Carbon $start, Carbon $end): array
|
||||||
{
|
{
|
||||||
Log::debug('Now in getAccountPeriodOverview()');
|
Log::debug(sprintf('Now in getAccountPeriodOverview(#%d, %s %s)', $account->id, $start->format('Y-m-d'), $end->format('Y-m-d')));
|
||||||
$timer = Timer::getInstance();
|
$this->accountRepository = app(AccountRepositoryInterface::class);
|
||||||
$timer->start('account-period-total');
|
$this->periodStatisticRepo = app(PeriodStatisticRepositoryInterface::class);
|
||||||
$this->accountRepository = app(AccountRepositoryInterface::class);
|
$range = Navigation::getViewRange(true);
|
||||||
$range = Navigation::getViewRange(true);
|
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
|
||||||
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
|
|
||||||
|
|
||||||
// properties for cache
|
|
||||||
$cache = new CacheProperties();
|
|
||||||
$cache->addProperty($start);
|
|
||||||
$cache->addProperty($end);
|
|
||||||
$cache->addProperty('account-show-period-entries');
|
|
||||||
$cache->addProperty($account->id);
|
|
||||||
if ($cache->has()) {
|
|
||||||
Log::debug('Return CACHED in getAccountPeriodOverview()');
|
|
||||||
|
|
||||||
return $cache->get();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @var array $dates */
|
/** @var array $dates */
|
||||||
$dates = Navigation::blockPeriods($start, $end, $range);
|
$dates = Navigation::blockPeriods($start, $end, $range);
|
||||||
$entries = [];
|
$entries = [];
|
||||||
|
|
||||||
// run a custom query because doing this with the collector is MEGA slow.
|
|
||||||
$timer->start('account-period-collect');
|
|
||||||
$transactions = $this->accountRepository->periodCollection($account, $start, $end);
|
|
||||||
$timer->stop('account-period-collect');
|
|
||||||
// loop dates
|
|
||||||
Log::debug(sprintf('Count of loops: %d', count($dates)));
|
Log::debug(sprintf('Count of loops: %d', count($dates)));
|
||||||
$loops = 0;
|
|
||||||
// stop after 10 loops for memory reasons.
|
|
||||||
$timer->start('account-period-loop');
|
|
||||||
foreach ($dates as $currentDate) {
|
foreach ($dates as $currentDate) {
|
||||||
$title = Navigation::periodShow($currentDate['start'], $currentDate['period']);
|
$entries[] = $this->getSingleAccountPeriod($account, $currentDate['start'], $currentDate['end']);
|
||||||
[$transactions, $spent] = $this->filterTransactionsByType(TransactionTypeEnum::WITHDRAWAL, $transactions, $currentDate['start'], $currentDate['end']);
|
|
||||||
[$transactions, $earned] = $this->filterTransactionsByType(TransactionTypeEnum::DEPOSIT, $transactions, $currentDate['start'], $currentDate['end']);
|
|
||||||
[$transactions, $transferredAway] = $this->filterTransfers('away', $transactions, $currentDate['start'], $currentDate['end']);
|
|
||||||
[$transactions, $transferredIn] = $this->filterTransfers('in', $transactions, $currentDate['start'], $currentDate['end']);
|
|
||||||
$entries[]
|
|
||||||
= [
|
|
||||||
'title' => $title,
|
|
||||||
'route' => route('accounts.show', [$account->id, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
|
|
||||||
'total_transactions' => count($spent) + count($earned) + count($transferredAway) + count($transferredIn),
|
|
||||||
'spent' => $this->groupByCurrency($spent),
|
|
||||||
'earned' => $this->groupByCurrency($earned),
|
|
||||||
'transferred_away' => $this->groupByCurrency($transferredAway),
|
|
||||||
'transferred_in' => $this->groupByCurrency($transferredIn),
|
|
||||||
];
|
|
||||||
++$loops;
|
|
||||||
}
|
}
|
||||||
$timer->stop('account-period-loop');
|
|
||||||
$cache->store($entries);
|
|
||||||
$timer->stop('account-period-total');
|
|
||||||
Log::debug('End of getAccountPeriodOverview()');
|
Log::debug('End of getAccountPeriodOverview()');
|
||||||
|
|
||||||
return $entries;
|
return $entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function getSingleAccountPeriod(Account $account, Carbon $start, Carbon $end): array
|
||||||
|
{
|
||||||
|
Log::debug(sprintf('Now in getSingleAccountPeriod(#%d, %s %s)', $account->id, $start->format('Y-m-d'), $end->format('Y-m-d')));
|
||||||
|
$types = ['spent', 'earned', 'transferred_in', 'transferred_away'];
|
||||||
|
$return = [
|
||||||
|
'title' => Navigation::periodShow($start, $end),
|
||||||
|
'route' => route('accounts.show', [$account->id, $start->format('Y-m-d'), $start->format('Y-m-d')]),
|
||||||
|
'total_transactions' => 0,
|
||||||
|
];
|
||||||
|
foreach ($types as $type) {
|
||||||
|
$set = $this->getSingleAccountPeriodByType($account, $start, $end, $type);
|
||||||
|
$return['total_transactions'] += $set['count'];
|
||||||
|
unset($set['count']);
|
||||||
|
$return[$type] = $set;
|
||||||
|
}
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getSingleAccountPeriodByType(Account $account, Carbon $start, Carbon $end, string $type): array
|
||||||
|
{
|
||||||
|
Log::debug(sprintf('Now in getSingleAccountPeriodByType(#%d, %s %s, %s)', $account->id, $start->format('Y-m-d'), $end->format('Y-m-d'), $type));
|
||||||
|
$statistics = $this->periodStatisticRepo->findPeriodStatistic($account, $start, $end, $type);
|
||||||
|
|
||||||
|
// nothing found, regenerate them.
|
||||||
|
if (0 === $statistics->count()) {
|
||||||
|
$transactions = $this->accountRepository->periodCollection($account, $start, $end);
|
||||||
|
switch ($type) {
|
||||||
|
default:
|
||||||
|
throw new FireflyException(sprintf('Cannot deal with account period type %s', $type));
|
||||||
|
case 'spent':
|
||||||
|
$result = $this->filterTransactionsByType(TransactionTypeEnum::WITHDRAWAL, $transactions, $start, $end);
|
||||||
|
break;
|
||||||
|
case 'earned':
|
||||||
|
$result = $this->filterTransactionsByType(TransactionTypeEnum::DEPOSIT, $transactions, $start, $end);
|
||||||
|
break;
|
||||||
|
case 'transferred_in':
|
||||||
|
$result = $this->filterTransfers('in', $transactions, $start, $end);
|
||||||
|
break;
|
||||||
|
case 'transferred_away':
|
||||||
|
$result = $this->filterTransfers('away', $transactions, $start, $end);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// each result must be grouped by currency, then saved as period statistic.
|
||||||
|
$grouped = $this->groupByCurrency($result);
|
||||||
|
|
||||||
|
// TODO save as statistic.
|
||||||
|
$this->saveGroupedAsStatistics($account, $start, $end, $type, $grouped);
|
||||||
|
return $grouped;
|
||||||
|
}
|
||||||
|
$grouped = [
|
||||||
|
'count' => 0,
|
||||||
|
];
|
||||||
|
/** @var PeriodStatistic $statistic */
|
||||||
|
foreach($statistics as $statistic) {
|
||||||
|
$id = (int) $statistic->transaction_currency_id;
|
||||||
|
$currency = Amount::getTransactionCurrencyById($id);
|
||||||
|
$grouped[$id] = [
|
||||||
|
'amount' => (string) $statistic->amount,
|
||||||
|
'count' => (int) $statistic->count,
|
||||||
|
'currency_id' => $currency->id,
|
||||||
|
'currency_name' => $currency->name,
|
||||||
|
'currency_code' => $currency->code,
|
||||||
|
'currency_symbol' => $currency->symbol,
|
||||||
|
'currency_decimal_places' => $currency->decimal_places,
|
||||||
|
];
|
||||||
|
$grouped['count'] += (int) $statistic->count;
|
||||||
|
}
|
||||||
|
return $grouped;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function saveGroupedAsStatistics(Account $account, Carbon $start, Carbon $end, string $type, array $array): void
|
||||||
|
{
|
||||||
|
unset($array['count']);
|
||||||
|
foreach ($array as $entry) {
|
||||||
|
$this->periodStatisticRepo->saveStatistic($account, $entry['currency_id'], $start, $end, $type, $entry['count'], $entry['amount']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private function filterTransactionsByType(TransactionTypeEnum $type, array $transactions, Carbon $start, Carbon $end): array
|
private function filterTransactionsByType(TransactionTypeEnum $type, array $transactions, Carbon $start, Carbon $end): array
|
||||||
{
|
{
|
||||||
$result = [];
|
$result = [];
|
||||||
$filtered = [];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int $index
|
* @var int $index
|
||||||
* @var array $item
|
* @var array $item
|
||||||
*/
|
*/
|
||||||
foreach ($transactions as $index => $item) {
|
foreach ($transactions as $index => $item) {
|
||||||
@@ -153,25 +192,21 @@ trait PeriodOverview
|
|||||||
$result[] = $item;
|
$result[] = $item;
|
||||||
unset($transactions[$index]);
|
unset($transactions[$index]);
|
||||||
}
|
}
|
||||||
if (!$fits) {
|
|
||||||
$filtered[] = $item;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return [$filtered, $result];
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function filterTransfers(string $direction, array $transactions, Carbon $start, Carbon $end): array
|
private function filterTransfers(string $direction, array $transactions, Carbon $start, Carbon $end): array
|
||||||
{
|
{
|
||||||
$result = [];
|
$result = [];
|
||||||
$filtered = [];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int $index
|
* @var int $index
|
||||||
* @var array $item
|
* @var array $item
|
||||||
*/
|
*/
|
||||||
foreach ($transactions as $index => $item) {
|
foreach ($transactions as $index => $item) {
|
||||||
$date = Carbon::parse($item['date']);
|
$date = Carbon::parse($item['date']);
|
||||||
if ($date >= $start && $date <= $end) {
|
if ($date >= $start && $date <= $end) {
|
||||||
if ('away' === $direction && -1 === bccomp((string)$item['amount'], '0')) {
|
if ('away' === $direction && -1 === bccomp((string)$item['amount'], '0')) {
|
||||||
$result[] = $item;
|
$result[] = $item;
|
||||||
@@ -184,25 +219,34 @@ trait PeriodOverview
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$filtered[] = $item;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return [$filtered, $result];
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function groupByCurrency(array $journals): array
|
private function groupByCurrency(array $journals): array
|
||||||
{
|
{
|
||||||
$return = [];
|
Log::debug('groupByCurrency()');
|
||||||
|
$return = [
|
||||||
|
'count' => 0,
|
||||||
|
];
|
||||||
|
|
||||||
/** @var array $journal */
|
/** @var array $journal */
|
||||||
foreach ($journals as $journal) {
|
foreach ($journals as $journal) {
|
||||||
$currencyId = (int)$journal['currency_id'];
|
|
||||||
$currencyCode = $journal['currency_code'];
|
if (!array_key_exists('currency_id', $journal)) {
|
||||||
$currencyName = $journal['currency_name'];
|
Log::debug('very strange!');
|
||||||
$currencySymbol = $journal['currency_symbol'];
|
var_dump($journals);
|
||||||
$currencyDecimalPlaces = $journal['currency_decimal_places'];
|
exit;
|
||||||
$foreignCurrencyId = $journal['foreign_currency_id'];
|
}
|
||||||
$amount = $journal['amount'] ?? '0';
|
|
||||||
|
$currencyId = (int)$journal['currency_id'];
|
||||||
|
$currencyCode = $journal['currency_code'];
|
||||||
|
$currencyName = $journal['currency_name'];
|
||||||
|
$currencySymbol = $journal['currency_symbol'];
|
||||||
|
$currencyDecimalPlaces = $journal['currency_decimal_places'];
|
||||||
|
$foreignCurrencyId = $journal['foreign_currency_id'];
|
||||||
|
$amount = $journal['amount'] ?? '0';
|
||||||
|
|
||||||
if ($this->convertToPrimary && $currencyId !== $this->primaryCurrency->id && $foreignCurrencyId !== $this->primaryCurrency->id) {
|
if ($this->convertToPrimary && $currencyId !== $this->primaryCurrency->id && $foreignCurrencyId !== $this->primaryCurrency->id) {
|
||||||
$amount = $journal['pc_amount'] ?? '0';
|
$amount = $journal['pc_amount'] ?? '0';
|
||||||
@@ -233,6 +277,7 @@ trait PeriodOverview
|
|||||||
|
|
||||||
$return[$currencyId]['amount'] = bcadd($return[$currencyId]['amount'], $amount);
|
$return[$currencyId]['amount'] = bcadd($return[$currencyId]['amount'], $amount);
|
||||||
++$return[$currencyId]['count'];
|
++$return[$currencyId]['count'];
|
||||||
|
++$return['count'];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
@@ -245,11 +290,11 @@ trait PeriodOverview
|
|||||||
*/
|
*/
|
||||||
protected function getCategoryPeriodOverview(Category $category, Carbon $start, Carbon $end): array
|
protected function getCategoryPeriodOverview(Category $category, Carbon $start, Carbon $end): array
|
||||||
{
|
{
|
||||||
$range = Navigation::getViewRange(true);
|
$range = Navigation::getViewRange(true);
|
||||||
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
|
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
|
||||||
|
|
||||||
// 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($range);
|
$cache->addProperty($range);
|
||||||
@@ -261,32 +306,32 @@ trait PeriodOverview
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @var array $dates */
|
/** @var array $dates */
|
||||||
$dates = Navigation::blockPeriods($start, $end, $range);
|
$dates = Navigation::blockPeriods($start, $end, $range);
|
||||||
$entries = [];
|
$entries = [];
|
||||||
|
|
||||||
// collect all expenses in this period:
|
// collect all expenses in this period:
|
||||||
/** @var GroupCollectorInterface $collector */
|
/** @var GroupCollectorInterface $collector */
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->setCategory($category);
|
$collector->setCategory($category);
|
||||||
$collector->setRange($start, $end);
|
$collector->setRange($start, $end);
|
||||||
$collector->setTypes([TransactionTypeEnum::DEPOSIT->value]);
|
$collector->setTypes([TransactionTypeEnum::DEPOSIT->value]);
|
||||||
$earnedSet = $collector->getExtractedJournals();
|
$earnedSet = $collector->getExtractedJournals();
|
||||||
|
|
||||||
// collect all income in this period:
|
// collect all income in this period:
|
||||||
/** @var GroupCollectorInterface $collector */
|
/** @var GroupCollectorInterface $collector */
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->setCategory($category);
|
$collector->setCategory($category);
|
||||||
$collector->setRange($start, $end);
|
$collector->setRange($start, $end);
|
||||||
$collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value]);
|
$collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value]);
|
||||||
$spentSet = $collector->getExtractedJournals();
|
$spentSet = $collector->getExtractedJournals();
|
||||||
|
|
||||||
// collect all transfers in this period:
|
// collect all transfers in this period:
|
||||||
/** @var GroupCollectorInterface $collector */
|
/** @var GroupCollectorInterface $collector */
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->setCategory($category);
|
$collector->setCategory($category);
|
||||||
$collector->setRange($start, $end);
|
$collector->setRange($start, $end);
|
||||||
$collector->setTypes([TransactionTypeEnum::TRANSFER->value]);
|
$collector->setTypes([TransactionTypeEnum::TRANSFER->value]);
|
||||||
$transferSet = $collector->getExtractedJournals();
|
$transferSet = $collector->getExtractedJournals();
|
||||||
foreach ($dates as $currentDate) {
|
foreach ($dates as $currentDate) {
|
||||||
$spent = $this->filterJournalsByDate($spentSet, $currentDate['start'], $currentDate['end']);
|
$spent = $this->filterJournalsByDate($spentSet, $currentDate['start'], $currentDate['end']);
|
||||||
$earned = $this->filterJournalsByDate($earnedSet, $currentDate['start'], $currentDate['end']);
|
$earned = $this->filterJournalsByDate($earnedSet, $currentDate['start'], $currentDate['end']);
|
||||||
@@ -294,17 +339,17 @@ trait PeriodOverview
|
|||||||
$title = Navigation::periodShow($currentDate['end'], $currentDate['period']);
|
$title = Navigation::periodShow($currentDate['end'], $currentDate['period']);
|
||||||
$entries[]
|
$entries[]
|
||||||
= [
|
= [
|
||||||
'transactions' => 0,
|
'transactions' => 0,
|
||||||
'title' => $title,
|
'title' => $title,
|
||||||
'route' => route(
|
'route' => route(
|
||||||
'categories.show',
|
'categories.show',
|
||||||
[$category->id, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]
|
[$category->id, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]
|
||||||
),
|
),
|
||||||
'total_transactions' => count($spent) + count($earned) + count($transferred),
|
'total_transactions' => count($spent) + count($earned) + count($transferred),
|
||||||
'spent' => $this->groupByCurrency($spent),
|
'spent' => $this->groupByCurrency($spent),
|
||||||
'earned' => $this->groupByCurrency($earned),
|
'earned' => $this->groupByCurrency($earned),
|
||||||
'transferred' => $this->groupByCurrency($transferred),
|
'transferred' => $this->groupByCurrency($transferred),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
$cache->store($entries);
|
$cache->store($entries);
|
||||||
|
|
||||||
@@ -337,11 +382,11 @@ trait PeriodOverview
|
|||||||
*/
|
*/
|
||||||
protected function getNoBudgetPeriodOverview(Carbon $start, Carbon $end): array
|
protected function getNoBudgetPeriodOverview(Carbon $start, Carbon $end): array
|
||||||
{
|
{
|
||||||
$range = Navigation::getViewRange(true);
|
$range = Navigation::getViewRange(true);
|
||||||
|
|
||||||
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
|
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
|
||||||
|
|
||||||
$cache = new CacheProperties();
|
$cache = new CacheProperties();
|
||||||
$cache->addProperty($start);
|
$cache->addProperty($start);
|
||||||
$cache->addProperty($end);
|
$cache->addProperty($end);
|
||||||
$cache->addProperty($this->convertToPrimary);
|
$cache->addProperty($this->convertToPrimary);
|
||||||
@@ -352,28 +397,28 @@ trait PeriodOverview
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @var array $dates */
|
/** @var array $dates */
|
||||||
$dates = Navigation::blockPeriods($start, $end, $range);
|
$dates = Navigation::blockPeriods($start, $end, $range);
|
||||||
$entries = [];
|
$entries = [];
|
||||||
|
|
||||||
// get all expenses without a budget.
|
// get all expenses without a budget.
|
||||||
/** @var GroupCollectorInterface $collector */
|
/** @var GroupCollectorInterface $collector */
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->setRange($start, $end)->withoutBudget()->withAccountInformation()->setTypes([TransactionTypeEnum::WITHDRAWAL->value]);
|
$collector->setRange($start, $end)->withoutBudget()->withAccountInformation()->setTypes([TransactionTypeEnum::WITHDRAWAL->value]);
|
||||||
$journals = $collector->getExtractedJournals();
|
$journals = $collector->getExtractedJournals();
|
||||||
|
|
||||||
foreach ($dates as $currentDate) {
|
foreach ($dates as $currentDate) {
|
||||||
$set = $this->filterJournalsByDate($journals, $currentDate['start'], $currentDate['end']);
|
$set = $this->filterJournalsByDate($journals, $currentDate['start'], $currentDate['end']);
|
||||||
$title = Navigation::periodShow($currentDate['end'], $currentDate['period']);
|
$title = Navigation::periodShow($currentDate['end'], $currentDate['period']);
|
||||||
$entries[]
|
$entries[]
|
||||||
= [
|
= [
|
||||||
'title' => $title,
|
'title' => $title,
|
||||||
'route' => route('budgets.no-budget', [$currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
|
'route' => route('budgets.no-budget', [$currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
|
||||||
'total_transactions' => count($set),
|
'total_transactions' => count($set),
|
||||||
'spent' => $this->groupByCurrency($set),
|
'spent' => $this->groupByCurrency($set),
|
||||||
'earned' => [],
|
'earned' => [],
|
||||||
'transferred_away' => [],
|
'transferred_away' => [],
|
||||||
'transferred_in' => [],
|
'transferred_in' => [],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
$cache->store($entries);
|
$cache->store($entries);
|
||||||
|
|
||||||
@@ -390,38 +435,38 @@ trait PeriodOverview
|
|||||||
protected function getNoCategoryPeriodOverview(Carbon $theDate): array
|
protected function getNoCategoryPeriodOverview(Carbon $theDate): array
|
||||||
{
|
{
|
||||||
app('log')->debug(sprintf('Now in getNoCategoryPeriodOverview(%s)', $theDate->format('Y-m-d')));
|
app('log')->debug(sprintf('Now in getNoCategoryPeriodOverview(%s)', $theDate->format('Y-m-d')));
|
||||||
$range = Navigation::getViewRange(true);
|
$range = Navigation::getViewRange(true);
|
||||||
$first = $this->journalRepos->firstNull();
|
$first = $this->journalRepos->firstNull();
|
||||||
$start = null === $first ? new Carbon() : $first->date;
|
$start = null === $first ? new Carbon() : $first->date;
|
||||||
$end = clone $theDate;
|
$end = clone $theDate;
|
||||||
$end = Navigation::endOfPeriod($end, $range);
|
$end = Navigation::endOfPeriod($end, $range);
|
||||||
|
|
||||||
app('log')->debug(sprintf('Start for getNoCategoryPeriodOverview() is %s', $start->format('Y-m-d')));
|
app('log')->debug(sprintf('Start for getNoCategoryPeriodOverview() is %s', $start->format('Y-m-d')));
|
||||||
app('log')->debug(sprintf('End for getNoCategoryPeriodOverview() is %s', $end->format('Y-m-d')));
|
app('log')->debug(sprintf('End for getNoCategoryPeriodOverview() is %s', $end->format('Y-m-d')));
|
||||||
|
|
||||||
// properties for cache
|
// properties for cache
|
||||||
$dates = Navigation::blockPeriods($start, $end, $range);
|
$dates = Navigation::blockPeriods($start, $end, $range);
|
||||||
$entries = [];
|
$entries = [];
|
||||||
|
|
||||||
// collect all expenses in this period:
|
// collect all expenses in this period:
|
||||||
/** @var GroupCollectorInterface $collector */
|
/** @var GroupCollectorInterface $collector */
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->withoutCategory();
|
$collector->withoutCategory();
|
||||||
$collector->setRange($start, $end);
|
$collector->setRange($start, $end);
|
||||||
$collector->setTypes([TransactionTypeEnum::DEPOSIT->value]);
|
$collector->setTypes([TransactionTypeEnum::DEPOSIT->value]);
|
||||||
$earnedSet = $collector->getExtractedJournals();
|
$earnedSet = $collector->getExtractedJournals();
|
||||||
|
|
||||||
// collect all income in this period:
|
// collect all income in this period:
|
||||||
/** @var GroupCollectorInterface $collector */
|
/** @var GroupCollectorInterface $collector */
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->withoutCategory();
|
$collector->withoutCategory();
|
||||||
$collector->setRange($start, $end);
|
$collector->setRange($start, $end);
|
||||||
$collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value]);
|
$collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value]);
|
||||||
$spentSet = $collector->getExtractedJournals();
|
$spentSet = $collector->getExtractedJournals();
|
||||||
|
|
||||||
// collect all transfers in this period:
|
// collect all transfers in this period:
|
||||||
/** @var GroupCollectorInterface $collector */
|
/** @var GroupCollectorInterface $collector */
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->withoutCategory();
|
$collector->withoutCategory();
|
||||||
$collector->setRange($start, $end);
|
$collector->setRange($start, $end);
|
||||||
$collector->setTypes([TransactionTypeEnum::TRANSFER->value]);
|
$collector->setTypes([TransactionTypeEnum::TRANSFER->value]);
|
||||||
@@ -435,13 +480,13 @@ trait PeriodOverview
|
|||||||
$title = Navigation::periodShow($currentDate['end'], $currentDate['period']);
|
$title = Navigation::periodShow($currentDate['end'], $currentDate['period']);
|
||||||
$entries[]
|
$entries[]
|
||||||
= [
|
= [
|
||||||
'title' => $title,
|
'title' => $title,
|
||||||
'route' => route('categories.no-category', [$currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
|
'route' => route('categories.no-category', [$currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
|
||||||
'total_transactions' => count($spent) + count($earned) + count($transferred),
|
'total_transactions' => count($spent) + count($earned) + count($transferred),
|
||||||
'spent' => $this->groupByCurrency($spent),
|
'spent' => $this->groupByCurrency($spent),
|
||||||
'earned' => $this->groupByCurrency($earned),
|
'earned' => $this->groupByCurrency($earned),
|
||||||
'transferred' => $this->groupByCurrency($transferred),
|
'transferred' => $this->groupByCurrency($transferred),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
app('log')->debug('End of loops');
|
app('log')->debug('End of loops');
|
||||||
|
|
||||||
@@ -455,11 +500,11 @@ trait PeriodOverview
|
|||||||
*/
|
*/
|
||||||
protected function getTagPeriodOverview(Tag $tag, Carbon $start, Carbon $end): array // period overview for tags.
|
protected function getTagPeriodOverview(Tag $tag, Carbon $start, Carbon $end): array // period overview for tags.
|
||||||
{
|
{
|
||||||
$range = Navigation::getViewRange(true);
|
$range = Navigation::getViewRange(true);
|
||||||
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
|
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
|
||||||
|
|
||||||
// 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('tag-period-entries');
|
$cache->addProperty('tag-period-entries');
|
||||||
@@ -469,37 +514,37 @@ trait PeriodOverview
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @var array $dates */
|
/** @var array $dates */
|
||||||
$dates = Navigation::blockPeriods($start, $end, $range);
|
$dates = Navigation::blockPeriods($start, $end, $range);
|
||||||
$entries = [];
|
$entries = [];
|
||||||
|
|
||||||
// collect all expenses in this period:
|
// collect all expenses in this period:
|
||||||
/** @var GroupCollectorInterface $collector */
|
/** @var GroupCollectorInterface $collector */
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->setTag($tag);
|
$collector->setTag($tag);
|
||||||
$collector->setRange($start, $end);
|
$collector->setRange($start, $end);
|
||||||
$collector->setTypes([TransactionTypeEnum::DEPOSIT->value]);
|
$collector->setTypes([TransactionTypeEnum::DEPOSIT->value]);
|
||||||
$earnedSet = $collector->getExtractedJournals();
|
$earnedSet = $collector->getExtractedJournals();
|
||||||
|
|
||||||
// collect all income in this period:
|
// collect all income in this period:
|
||||||
/** @var GroupCollectorInterface $collector */
|
/** @var GroupCollectorInterface $collector */
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->setTag($tag);
|
$collector->setTag($tag);
|
||||||
$collector->setRange($start, $end);
|
$collector->setRange($start, $end);
|
||||||
$collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value]);
|
$collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value]);
|
||||||
$spentSet = $collector->getExtractedJournals();
|
$spentSet = $collector->getExtractedJournals();
|
||||||
|
|
||||||
// collect all transfers in this period:
|
// collect all transfers in this period:
|
||||||
/** @var GroupCollectorInterface $collector */
|
/** @var GroupCollectorInterface $collector */
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->setTag($tag);
|
$collector->setTag($tag);
|
||||||
$collector->setRange($start, $end);
|
$collector->setRange($start, $end);
|
||||||
$collector->setTypes([TransactionTypeEnum::TRANSFER->value]);
|
$collector->setTypes([TransactionTypeEnum::TRANSFER->value]);
|
||||||
$transferSet = $collector->getExtractedJournals();
|
$transferSet = $collector->getExtractedJournals();
|
||||||
|
|
||||||
// filer all of them:
|
// filer all of them:
|
||||||
$earnedSet = $this->filterJournalsByTag($earnedSet, $tag);
|
$earnedSet = $this->filterJournalsByTag($earnedSet, $tag);
|
||||||
$spentSet = $this->filterJournalsByTag($spentSet, $tag);
|
$spentSet = $this->filterJournalsByTag($spentSet, $tag);
|
||||||
$transferSet = $this->filterJournalsByTag($transferSet, $tag);
|
$transferSet = $this->filterJournalsByTag($transferSet, $tag);
|
||||||
|
|
||||||
foreach ($dates as $currentDate) {
|
foreach ($dates as $currentDate) {
|
||||||
$spent = $this->filterJournalsByDate($spentSet, $currentDate['start'], $currentDate['end']);
|
$spent = $this->filterJournalsByDate($spentSet, $currentDate['start'], $currentDate['end']);
|
||||||
@@ -508,17 +553,17 @@ trait PeriodOverview
|
|||||||
$title = Navigation::periodShow($currentDate['end'], $currentDate['period']);
|
$title = Navigation::periodShow($currentDate['end'], $currentDate['period']);
|
||||||
$entries[]
|
$entries[]
|
||||||
= [
|
= [
|
||||||
'transactions' => 0,
|
'transactions' => 0,
|
||||||
'title' => $title,
|
'title' => $title,
|
||||||
'route' => route(
|
'route' => route(
|
||||||
'tags.show',
|
'tags.show',
|
||||||
[$tag->id, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]
|
[$tag->id, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]
|
||||||
),
|
),
|
||||||
'total_transactions' => count($spent) + count($earned) + count($transferred),
|
'total_transactions' => count($spent) + count($earned) + count($transferred),
|
||||||
'spent' => $this->groupByCurrency($spent),
|
'spent' => $this->groupByCurrency($spent),
|
||||||
'earned' => $this->groupByCurrency($earned),
|
'earned' => $this->groupByCurrency($earned),
|
||||||
'transferred' => $this->groupByCurrency($transferred),
|
'transferred' => $this->groupByCurrency($transferred),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $entries;
|
return $entries;
|
||||||
@@ -528,7 +573,7 @@ trait PeriodOverview
|
|||||||
{
|
{
|
||||||
$return = [];
|
$return = [];
|
||||||
foreach ($set as $entry) {
|
foreach ($set as $entry) {
|
||||||
$found = false;
|
$found = false;
|
||||||
|
|
||||||
/** @var array $localTag */
|
/** @var array $localTag */
|
||||||
foreach ($entry['tags'] as $localTag) {
|
foreach ($entry['tags'] as $localTag) {
|
||||||
@@ -550,12 +595,12 @@ trait PeriodOverview
|
|||||||
*/
|
*/
|
||||||
protected function getTransactionPeriodOverview(string $transactionType, Carbon $start, Carbon $end): array
|
protected function getTransactionPeriodOverview(string $transactionType, Carbon $start, Carbon $end): array
|
||||||
{
|
{
|
||||||
$range = Navigation::getViewRange(true);
|
$range = Navigation::getViewRange(true);
|
||||||
$types = config(sprintf('firefly.transactionTypesByType.%s', $transactionType));
|
$types = config(sprintf('firefly.transactionTypesByType.%s', $transactionType));
|
||||||
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
|
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
|
||||||
|
|
||||||
// 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('transactions-period-entries');
|
$cache->addProperty('transactions-period-entries');
|
||||||
@@ -565,16 +610,16 @@ trait PeriodOverview
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @var array $dates */
|
/** @var array $dates */
|
||||||
$dates = Navigation::blockPeriods($start, $end, $range);
|
$dates = Navigation::blockPeriods($start, $end, $range);
|
||||||
$entries = [];
|
$entries = [];
|
||||||
$spent = [];
|
$spent = [];
|
||||||
$earned = [];
|
$earned = [];
|
||||||
$transferred = [];
|
$transferred = [];
|
||||||
// collect all journals in this period (regardless of type)
|
// collect all journals in this period (regardless of type)
|
||||||
$collector = app(GroupCollectorInterface::class);
|
$collector = app(GroupCollectorInterface::class);
|
||||||
$collector->setTypes($types)->setRange($start, $end);
|
$collector->setTypes($types)->setRange($start, $end);
|
||||||
$genericSet = $collector->getExtractedJournals();
|
$genericSet = $collector->getExtractedJournals();
|
||||||
$loops = 0;
|
$loops = 0;
|
||||||
|
|
||||||
foreach ($dates as $currentDate) {
|
foreach ($dates as $currentDate) {
|
||||||
$title = Navigation::periodShow($currentDate['end'], $currentDate['period']);
|
$title = Navigation::periodShow($currentDate['end'], $currentDate['period']);
|
||||||
@@ -592,14 +637,14 @@ trait PeriodOverview
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$entries[]
|
$entries[]
|
||||||
= [
|
= [
|
||||||
'title' => $title,
|
'title' => $title,
|
||||||
'route' => route('transactions.index', [$transactionType, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
|
'route' => route('transactions.index', [$transactionType, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
|
||||||
'total_transactions' => count($spent) + count($earned) + count($transferred),
|
'total_transactions' => count($spent) + count($earned) + count($transferred),
|
||||||
'spent' => $this->groupByCurrency($spent),
|
'spent' => $this->groupByCurrency($spent),
|
||||||
'earned' => $this->groupByCurrency($earned),
|
'earned' => $this->groupByCurrency($earned),
|
||||||
'transferred' => $this->groupByCurrency($transferred),
|
'transferred' => $this->groupByCurrency($transferred),
|
||||||
];
|
];
|
||||||
++$loops;
|
++$loops;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('period_statistics', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->timestamps();
|
||||||
|
$table->softDeletes();
|
||||||
|
$table->integer('primary_statable_id', false, true)->nullable();
|
||||||
|
$table->string('primary_statable_type', 255)->nullable();
|
||||||
|
|
||||||
|
$table->integer('secondary_statable_id', false, true)->nullable();
|
||||||
|
$table->string('secondary_statable_type', 255)->nullable();
|
||||||
|
|
||||||
|
$table->integer('tertiary_statable_id', false, true)->nullable();
|
||||||
|
$table->string('tertiary_statable_type', 255)->nullable();
|
||||||
|
|
||||||
|
$table->integer('transaction_currency_id', false, true);
|
||||||
|
$table->foreign('transaction_currency_id')->references('id')->on('transaction_currencies')->onDelete('cascade');
|
||||||
|
|
||||||
|
$table->dateTime('start')->nullable();
|
||||||
|
$table->string('start_tz', 50)->nullable();
|
||||||
|
$table->dateTime('end')->nullable();
|
||||||
|
$table->string('end_tz', 50)->nullable();
|
||||||
|
$table->string('type',255);
|
||||||
|
$table->integer('count', false, true)->default(0);
|
||||||
|
$table->decimal('amount', 32, 12);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('period_statistics');
|
||||||
|
}
|
||||||
|
};
|
Reference in New Issue
Block a user