mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-10-09 22:26:04 +00:00
Also add no budget and no category overview.
This commit is contained in:
@@ -92,7 +92,7 @@ class ShowController extends Controller
|
||||
// get first journal ever to set off the budget period overview.
|
||||
$first = $this->journalRepos->firstNull();
|
||||
$firstDate = $first instanceof TransactionJournal ? $first->date : $start;
|
||||
$periods = $this->getNoBudgetPeriodOverview($firstDate, $end);
|
||||
$periods = $this->getNoModelPeriodOverview('budget', $firstDate, $end);
|
||||
$page = (int) $request->get('page');
|
||||
$pageSize = (int) app('preferences')->get('listPageSize', 50)->data;
|
||||
|
||||
|
@@ -35,6 +35,7 @@ use FireflyIII\Support\Http\Controllers\PeriodOverview;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\View\View;
|
||||
|
||||
/**
|
||||
@@ -74,7 +75,7 @@ class NoCategoryController extends Controller
|
||||
*/
|
||||
public function show(Request $request, ?Carbon $start = null, ?Carbon $end = null)
|
||||
{
|
||||
app('log')->debug('Start of noCategory()');
|
||||
Log::debug('Start of noCategory()');
|
||||
$start ??= session('start');
|
||||
$end ??= session('end');
|
||||
|
||||
@@ -82,14 +83,12 @@ class NoCategoryController extends Controller
|
||||
/** @var Carbon $end */
|
||||
$page = (int) $request->get('page');
|
||||
$pageSize = (int) app('preferences')->get('listPageSize', 50)->data;
|
||||
$subTitle = trans(
|
||||
'firefly.without_category_between',
|
||||
['start' => $start->isoFormat($this->monthAndDayFormat), 'end' => $end->isoFormat($this->monthAndDayFormat)]
|
||||
);
|
||||
$periods = $this->getNoCategoryPeriodOverview($start);
|
||||
$subTitle = trans('firefly.without_category_between', ['start' => $start->isoFormat($this->monthAndDayFormat), 'end' => $end->isoFormat($this->monthAndDayFormat)]);
|
||||
$first = $this->journalRepos->firstNull()->date ?? clone $start;
|
||||
$periods = $this->getNoModelPeriodOverview('category', $first, $end);
|
||||
|
||||
app('log')->debug(sprintf('Start for noCategory() is %s', $start->format('Y-m-d')));
|
||||
app('log')->debug(sprintf('End for noCategory() is %s', $end->format('Y-m-d')));
|
||||
Log::debug(sprintf('Start for noCategory() is %s', $start->format('Y-m-d')));
|
||||
Log::debug(sprintf('End for noCategory() is %s', $end->format('Y-m-d')));
|
||||
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
@@ -117,13 +116,13 @@ class NoCategoryController extends Controller
|
||||
$periods = new Collection();
|
||||
$page = (int) $request->get('page');
|
||||
$pageSize = (int) app('preferences')->get('listPageSize', 50)->data;
|
||||
app('log')->debug('Start of noCategory()');
|
||||
Log::debug('Start of noCategory()');
|
||||
$subTitle = (string) trans('firefly.all_journals_without_category');
|
||||
$first = $this->journalRepos->firstNull();
|
||||
$start = $first instanceof TransactionJournal ? $first->date : new Carbon();
|
||||
$end = today(config('app.timezone'));
|
||||
app('log')->debug(sprintf('Start for noCategory() is %s', $start->format('Y-m-d')));
|
||||
app('log')->debug(sprintf('End for noCategory() is %s', $end->format('Y-m-d')));
|
||||
Log::debug(sprintf('Start for noCategory() is %s', $start->format('Y-m-d')));
|
||||
Log::debug(sprintf('End for noCategory() is %s', $end->format('Y-m-d')));
|
||||
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
|
@@ -8,6 +8,7 @@ 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\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||
|
||||
class PeriodStatistic extends Model
|
||||
@@ -24,6 +25,11 @@ class PeriodStatistic extends Model
|
||||
];
|
||||
}
|
||||
|
||||
public function userGroup(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(UserGroup::class);
|
||||
}
|
||||
|
||||
protected function count(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
|
@@ -76,6 +76,14 @@ class UserGroup extends Model
|
||||
return $this->hasMany(Account::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Link to accounts.
|
||||
*/
|
||||
public function periodStatistics(): HasMany
|
||||
{
|
||||
return $this->hasMany(PeriodStatistic::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Link to attachments.
|
||||
*/
|
||||
|
@@ -163,7 +163,6 @@ class FireflyServiceProvider extends ServiceProvider
|
||||
|
||||
$this->app->bind(AttachmentHelperInterface::class, AttachmentHelper::class);
|
||||
$this->app->bind(ALERepositoryInterface::class, ALERepository::class);
|
||||
$this->app->bind(PeriodStatisticRepositoryInterface::class, PeriodStatisticRepository::class);
|
||||
|
||||
$this->app->bind(
|
||||
static function (Application $app): ObjectGroupRepositoryInterface {
|
||||
@@ -177,6 +176,18 @@ class FireflyServiceProvider extends ServiceProvider
|
||||
}
|
||||
);
|
||||
|
||||
$this->app->bind(
|
||||
static function (Application $app): PeriodStatisticRepositoryInterface {
|
||||
/** @var PeriodStatisticRepository $repository */
|
||||
$repository = app(PeriodStatisticRepository::class);
|
||||
if ($app->auth->check()) { // @phpstan-ignore-line (phpstan does not understand the reference to auth)
|
||||
$repository->setUser(auth()->user());
|
||||
}
|
||||
|
||||
return $repository;
|
||||
}
|
||||
);
|
||||
|
||||
$this->app->bind(
|
||||
static function (Application $app): WebhookRepositoryInterface {
|
||||
/** @var WebhookRepository $repository */
|
||||
|
@@ -25,37 +25,40 @@ namespace FireflyIII\Repositories\PeriodStatistic;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\PeriodStatistic;
|
||||
use FireflyIII\Support\Repositories\UserGroup\UserGroupInterface;
|
||||
use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class PeriodStatisticRepository implements PeriodStatisticRepositoryInterface
|
||||
class PeriodStatisticRepository implements PeriodStatisticRepositoryInterface, UserGroupInterface
|
||||
{
|
||||
use UserGroupTrait;
|
||||
|
||||
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()
|
||||
;
|
||||
->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()
|
||||
;
|
||||
->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 = new PeriodStatistic();
|
||||
$stat->primaryStatable()->associate($model);
|
||||
$stat->transaction_currency_id = $currencyId;
|
||||
$stat->user_group_id = $this->getUserGroup()->id;
|
||||
$stat->start = $start;
|
||||
$stat->start_tz = $start->format('e');
|
||||
$stat->end = $end;
|
||||
@@ -66,16 +69,16 @@ class PeriodStatisticRepository implements PeriodStatisticRepositoryInterface
|
||||
$stat->save();
|
||||
|
||||
Log::debug(sprintf(
|
||||
'Saved #%d [currency #%d, Model %s #%d, %s to %s, %d, %s] as new statistic.',
|
||||
$stat->id,
|
||||
$model::class,
|
||||
$model->id,
|
||||
$stat->transaction_currency_id,
|
||||
$stat->start->toW3cString(),
|
||||
$stat->end->toW3cString(),
|
||||
$count,
|
||||
$amount
|
||||
));
|
||||
'Saved #%d [currency #%d, Model %s #%d, %s to %s, %d, %s] as new statistic.',
|
||||
$stat->id,
|
||||
$model::class,
|
||||
$model->id,
|
||||
$stat->transaction_currency_id,
|
||||
$stat->start->toW3cString(),
|
||||
$stat->end->toW3cString(),
|
||||
$count,
|
||||
$amount
|
||||
));
|
||||
|
||||
return $stat;
|
||||
}
|
||||
@@ -89,4 +92,41 @@ class PeriodStatisticRepository implements PeriodStatisticRepositoryInterface
|
||||
{
|
||||
$model->primaryPeriodStatistics()->where('start', '<=', $date)->where('end', '>=', $date)->delete();
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function allInRangeForPrefix(string $prefix, Carbon $start, Carbon $end): Collection
|
||||
{
|
||||
return $this->userGroup->periodStatistics()
|
||||
->where('type', 'LIKE', sprintf('%s%%', $prefix))
|
||||
->where('start', '>=', $start)->where('end', '<=', $end)->get();
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function savePrefixedStatistic(string $prefix, int $currencyId, Carbon $start, Carbon $end, string $type, int $count, string $amount): PeriodStatistic
|
||||
{
|
||||
$stat = new PeriodStatistic();
|
||||
$stat->transaction_currency_id = $currencyId;
|
||||
$stat->user_group_id = $this->getUserGroup()->id;
|
||||
$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 = sprintf('%s_%s',$prefix, $type);
|
||||
$stat->save();
|
||||
|
||||
Log::debug(sprintf(
|
||||
'Saved #%d [currency #%d, type "%s", %s to %s, %d, %s] as new statistic.',
|
||||
$stat->id,
|
||||
$stat->transaction_currency_id,
|
||||
$stat->type,
|
||||
$stat->start->toW3cString(),
|
||||
$stat->end->toW3cString(),
|
||||
$count,
|
||||
$amount
|
||||
));
|
||||
|
||||
return $stat;
|
||||
}
|
||||
}
|
||||
|
@@ -35,8 +35,10 @@ interface PeriodStatisticRepositoryInterface
|
||||
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;
|
||||
public function savePrefixedStatistic(string $prefix, int $currencyId, Carbon $start, Carbon $end, string $type, int $count, string $amount): PeriodStatistic;
|
||||
|
||||
public function allInRangeForModel(Model $model, Carbon $start, Carbon $end): Collection;
|
||||
public function allInRangeForPrefix(string $prefix, Carbon $start, Carbon $end): Collection;
|
||||
|
||||
public function deleteStatisticsForModel(Model $model, Carbon $date): void;
|
||||
}
|
||||
|
@@ -169,117 +169,129 @@ trait PeriodOverview
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
protected function getNoBudgetPeriodOverview(Carbon $start, Carbon $end): array
|
||||
protected function getNoModelPeriodOverview(string $model, Carbon $start, Carbon $end): array
|
||||
{
|
||||
$range = Navigation::getViewRange(true);
|
||||
|
||||
Log::debug(sprintf('Now in getNoModelPeriodOverview(%s, %s %s)', $model, $start->format('Y-m-d'), $end->format('Y-m-d')));
|
||||
$this->periodStatisticRepo = app(PeriodStatisticRepositoryInterface::class);
|
||||
$range = Navigation::getViewRange(true);
|
||||
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
|
||||
|
||||
$cache = new CacheProperties();
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty($this->convertToPrimary);
|
||||
$cache->addProperty('no-budget-period-entries');
|
||||
|
||||
if ($cache->has()) {
|
||||
return $cache->get();
|
||||
}
|
||||
|
||||
/** @var array $dates */
|
||||
$dates = Navigation::blockPeriods($start, $end, $range);
|
||||
$entries = [];
|
||||
|
||||
// get all expenses without a budget.
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setRange($start, $end)->withoutBudget()->withAccountInformation()->setTypes([TransactionTypeEnum::WITHDRAWAL->value]);
|
||||
$journals = $collector->getExtractedJournals();
|
||||
$dates = Navigation::blockPeriods($start, $end, $range);
|
||||
[$start, $end] = $this->getPeriodFromBlocks($dates, $start, $end);
|
||||
$entries = [];
|
||||
$this->statistics = $this->periodStatisticRepo->allInRangeForPrefix(sprintf('no_%s', $model), $start, $end);
|
||||
Log::debug(sprintf('Collected %d stats', $this->statistics->count()));
|
||||
|
||||
foreach ($dates as $currentDate) {
|
||||
$set = $this->filterJournalsByDate($journals, $currentDate['start'], $currentDate['end']);
|
||||
$title = Navigation::periodShow($currentDate['end'], $currentDate['period']);
|
||||
$entries[]
|
||||
= [
|
||||
'title' => $title,
|
||||
'route' => route('budgets.no-budget', [$currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
|
||||
'total_transactions' => count($set),
|
||||
'spent' => $this->groupByCurrency($set),
|
||||
'earned' => [],
|
||||
'transferred_away' => [],
|
||||
'transferred_in' => [],
|
||||
];
|
||||
$entries[] = $this->getSingleNoModelPeriodOverview($model, $currentDate['start'], $currentDate['end'], $currentDate['period']);
|
||||
}
|
||||
$cache->store($entries);
|
||||
|
||||
return $entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO fix the date.
|
||||
*
|
||||
* Show period overview for no category view.
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
protected function getNoCategoryPeriodOverview(Carbon $theDate): array
|
||||
private function getSingleNoModelPeriodOverview(string $model, Carbon $start, Carbon $end, string $period): array
|
||||
{
|
||||
Log::debug(sprintf('Now in getNoCategoryPeriodOverview(%s)', $theDate->format('Y-m-d')));
|
||||
$range = Navigation::getViewRange(true);
|
||||
$first = $this->journalRepos->firstNull();
|
||||
$start = null === $first ? new Carbon() : $first->date;
|
||||
$end = clone $theDate;
|
||||
$end = Navigation::endOfPeriod($end, $range);
|
||||
Log::debug(sprintf('getSingleNoModelPeriodOverview(%s, %s, %s, %s)', $model, $start->format('Y-m-d'), $end->format('Y-m-d'), $period));
|
||||
$statistics = $this->filterPrefixedStatistics($start, $end, sprintf('no_%s', $model));
|
||||
$title = Navigation::periodShow($end, $period);
|
||||
|
||||
Log::debug(sprintf('Start for getNoCategoryPeriodOverview() is %s', $start->format('Y-m-d')));
|
||||
Log::debug(sprintf('End for getNoCategoryPeriodOverview() is %s', $end->format('Y-m-d')));
|
||||
if (0 === $statistics->count()) {
|
||||
Log::debug(sprintf('Found no statistics in period %s - %s, regenerating them.', $start->format('Y-m-d'), $end->format('Y-m-d')));
|
||||
switch ($model) {
|
||||
default:
|
||||
throw new FireflyException(sprintf('Cannot deal with model of type "%s"', $model));
|
||||
case 'budget':
|
||||
// get all expenses without a budget.
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setRange($start, $end)->withoutBudget()->withAccountInformation()->setTypes([TransactionTypeEnum::WITHDRAWAL->value]);
|
||||
$spent = $collector->getExtractedJournals();
|
||||
$earned = [];
|
||||
$transferred = [];
|
||||
break;
|
||||
case 'category':
|
||||
// collect all expenses in this period:
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->withoutCategory();
|
||||
$collector->setRange($start, $end);
|
||||
$collector->setTypes([TransactionTypeEnum::DEPOSIT->value]);
|
||||
$earned = $collector->getExtractedJournals();
|
||||
|
||||
// properties for cache
|
||||
$dates = Navigation::blockPeriods($start, $end, $range);
|
||||
$entries = [];
|
||||
// collect all income in this period:
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->withoutCategory();
|
||||
$collector->setRange($start, $end);
|
||||
$collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value]);
|
||||
$spent = $collector->getExtractedJournals();
|
||||
|
||||
// collect all expenses in this period:
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->withoutCategory();
|
||||
$collector->setRange($start, $end);
|
||||
$collector->setTypes([TransactionTypeEnum::DEPOSIT->value]);
|
||||
$earnedSet = $collector->getExtractedJournals();
|
||||
|
||||
// collect all income in this period:
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->withoutCategory();
|
||||
$collector->setRange($start, $end);
|
||||
$collector->setTypes([TransactionTypeEnum::WITHDRAWAL->value]);
|
||||
$spentSet = $collector->getExtractedJournals();
|
||||
|
||||
// collect all transfers in this period:
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->withoutCategory();
|
||||
$collector->setRange($start, $end);
|
||||
$collector->setTypes([TransactionTypeEnum::TRANSFER->value]);
|
||||
$transferSet = $collector->getExtractedJournals();
|
||||
|
||||
/** @var array $currentDate */
|
||||
foreach ($dates as $currentDate) {
|
||||
$spent = $this->filterJournalsByDate($spentSet, $currentDate['start'], $currentDate['end']);
|
||||
$earned = $this->filterJournalsByDate($earnedSet, $currentDate['start'], $currentDate['end']);
|
||||
$transferred = $this->filterJournalsByDate($transferSet, $currentDate['start'], $currentDate['end']);
|
||||
$title = Navigation::periodShow($currentDate['end'], $currentDate['period']);
|
||||
$entries[]
|
||||
= [
|
||||
// collect all transfers in this period:
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->withoutCategory();
|
||||
$collector->setRange($start, $end);
|
||||
$collector->setTypes([TransactionTypeEnum::TRANSFER->value]);
|
||||
$transferred = $collector->getExtractedJournals();
|
||||
break;
|
||||
}
|
||||
$groupedSpent = $this->groupByCurrency($spent);
|
||||
$groupedEarned = $this->groupByCurrency($earned);
|
||||
$groupedTransferred = $this->groupByCurrency($transferred);
|
||||
$entry
|
||||
= [
|
||||
'title' => $title,
|
||||
'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),
|
||||
'spent' => $this->groupByCurrency($spent),
|
||||
'earned' => $this->groupByCurrency($earned),
|
||||
'transferred' => $this->groupByCurrency($transferred),
|
||||
'route' => route(sprintf('%s.no-%s', Str::plural($model), $model), [$start->format('Y-m-d'), $end->format('Y-m-d')]),
|
||||
'total_transactions' => count($spent),
|
||||
'spent' => $groupedSpent,
|
||||
'earned' => $groupedEarned,
|
||||
'transferred' => $groupedTransferred,
|
||||
];
|
||||
$this->saveGroupedForPrefix(sprintf('no_%s', $model), $start, $end, 'spent', $groupedSpent);
|
||||
$this->saveGroupedForPrefix(sprintf('no_%s', $model), $start, $end, 'earned', $groupedEarned);
|
||||
$this->saveGroupedForPrefix(sprintf('no_%s', $model), $start, $end, 'transferred', $groupedTransferred);
|
||||
return $entry;
|
||||
}
|
||||
Log::debug('End of loops');
|
||||
Log::debug(sprintf('Found %d statistics in period %s - %s.', count($statistics), $start->format('Y-m-d'), $end->format('Y-m-d')));
|
||||
|
||||
return $entries;
|
||||
$entry
|
||||
= [
|
||||
'title' => $title,
|
||||
'route' => route(sprintf('%s.no-%s', Str::plural($model), $model), [$start->format('Y-m-d'), $end->format('Y-m-d')]),
|
||||
'total_transactions' => 0,
|
||||
'spent' => [],
|
||||
'earned' => [],
|
||||
'transferred' => [],
|
||||
];
|
||||
$grouped = [];
|
||||
/** @var PeriodStatistic $statistic */
|
||||
foreach ($statistics as $statistic) {
|
||||
$type = str_replace(sprintf('no_%s_', $model), '', $statistic->type);
|
||||
$id = (int)$statistic->transaction_currency_id;
|
||||
$currency = Amount::getTransactionCurrencyById($id);
|
||||
$grouped[$type]['count'] ??= 0;
|
||||
$grouped[$type][$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[$type]['count'] += (int)$statistic->count;
|
||||
}
|
||||
$types = ['spent', 'earned', 'transferred'];
|
||||
foreach ($types as $type) {
|
||||
if (array_key_exists($type, $grouped)) {
|
||||
$entry['total_transactions'] += $grouped[$type]['count'];
|
||||
unset($grouped[$type]['count']);
|
||||
$entry[$type] = $grouped[$type];
|
||||
}
|
||||
|
||||
}
|
||||
return $entry;
|
||||
}
|
||||
|
||||
protected function getSingleModelPeriod(Model $model, string $period, Carbon $start, Carbon $end): array
|
||||
@@ -303,30 +315,34 @@ trait PeriodOverview
|
||||
}
|
||||
|
||||
|
||||
protected function filterStatistics(Carbon $start, Carbon $end, string $type): Collection
|
||||
private function filterStatistics(Carbon $start, Carbon $end, string $type): Collection
|
||||
{
|
||||
if (0 === $this->statistics->count()) {
|
||||
Log::warning('Have no statistic to filter!');
|
||||
return new Collection;
|
||||
}
|
||||
return $this->statistics->filter(
|
||||
function (PeriodStatistic $statistic) use ($start, $end, $type) {
|
||||
if (
|
||||
!$statistic->end->equalTo($end)
|
||||
&& $statistic->end->format('Y-m-d H:i:s') === $end->format('Y-m-d H:i:s')
|
||||
) {
|
||||
echo sprintf('End: "%s" vs "%s": %s', $statistic->end->toW3cString(), $end->toW3cString(), var_export($statistic->end->eq($end), true));
|
||||
var_dump($statistic->end);
|
||||
var_dump($end);
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
return $statistic->start->eq($start) && $statistic->end->eq($end) && $statistic->type === $type;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private function filterPrefixedStatistics(Carbon $start, Carbon $end, string $prefix): Collection
|
||||
{
|
||||
if (0 === $this->statistics->count()) {
|
||||
Log::warning('Have no statistic to filter!');
|
||||
return new Collection;
|
||||
}
|
||||
return $this->statistics->filter(
|
||||
function (PeriodStatistic $statistic) use ($start, $end, $prefix) {
|
||||
return $statistic->start->eq($start) && $statistic->end->eq($end) && str_starts_with($statistic->type, $prefix);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
protected function getSingleModelPeriodByType(Model $model, Carbon $start, Carbon $end, string $type): array
|
||||
private function getSingleModelPeriodByType(Model $model, Carbon $start, Carbon $end, string $type): array
|
||||
{
|
||||
Log::debug(sprintf('Now in getSingleModelPeriodByType(%s #%d, %s %s, %s)', $model::class, $model->id, $start->format('Y-m-d'), $end->format('Y-m-d'), $type));
|
||||
$statistics = $this->filterStatistics($start, $end, $type);
|
||||
@@ -497,7 +513,7 @@ trait PeriodOverview
|
||||
return $entries;
|
||||
}
|
||||
|
||||
protected function saveGroupedAsStatistics(Model $model, Carbon $start, Carbon $end, string $type, array $array): void
|
||||
private function saveGroupedAsStatistics(Model $model, Carbon $start, Carbon $end, string $type, array $array): void
|
||||
{
|
||||
unset($array['count']);
|
||||
Log::debug(sprintf('saveGroupedAsStatistics(%s #%d, %s, %s, "%s", array(%d))', $model::class, $model->id, $start->format('Y-m-d'), $end->format('Y-m-d'), $type, count($array)));
|
||||
@@ -510,6 +526,19 @@ trait PeriodOverview
|
||||
}
|
||||
}
|
||||
|
||||
private function saveGroupedForPrefix(string $prefix, Carbon $start, Carbon $end, string $type, array $array): void
|
||||
{
|
||||
unset($array['count']);
|
||||
Log::debug(sprintf('saveGroupedForPrefix("%s", %s, %s, "%s", array(%d))', $prefix, $start->format('Y-m-d'), $end->format('Y-m-d'), $type, count($array)));
|
||||
foreach ($array as $entry) {
|
||||
$this->periodStatisticRepo->savePrefixedStatistic($prefix, $entry['currency_id'], $start, $end, $type, $entry['count'], $entry['amount']);
|
||||
}
|
||||
if (0 === count($array)) {
|
||||
Log::debug('Save empty statistic.');
|
||||
$this->periodStatisticRepo->savePrefixedStatistic($prefix, $this->primaryCurrency->id, $start, $end, $type, 0, '0');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter a list of journals by a set of dates, and then group them by currency.
|
||||
*/
|
||||
@@ -584,6 +613,9 @@ trait PeriodOverview
|
||||
$return = [
|
||||
'count' => 0,
|
||||
];
|
||||
if (0 === count($journals)) {
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** @var array $journal */
|
||||
foreach ($journals as $journal) {
|
||||
|
@@ -14,6 +14,10 @@ return new class extends Migration
|
||||
Schema::create('period_statistics', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->timestamps();
|
||||
|
||||
// reference to user group id.
|
||||
$table->bigInteger('user_group_id', false, true);
|
||||
|
||||
$table->integer('primary_statable_id', false, true)->nullable();
|
||||
$table->string('primary_statable_type', 255)->nullable();
|
||||
|
||||
@@ -33,6 +37,7 @@ return new class extends Migration
|
||||
$table->string('type',255);
|
||||
$table->integer('count', false, true)->default(0);
|
||||
$table->decimal('amount', 32, 12);
|
||||
$table->foreign('user_group_id')->references('id')->on('user_groups')->onDelete('cascade');
|
||||
});
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user