Compare commits

...

20 Commits

Author SHA1 Message Date
github-actions[bot]
ae3d0a3e49 Merge pull request #10964 from firefly-iii/release-1758820271
🤖 Automatically merge the PR into the develop branch.
2025-09-25 19:11:21 +02:00
JC5
61e8d7d7a2 🤖 Auto commit for release 'develop' on 2025-09-25 2025-09-25 19:11:11 +02:00
James Cole
62c5440605 Add table for period statistics, and see what happens re: performance. 2025-09-25 19:07:02 +02:00
James Cole
0aa90b9453 Fix #10960 2025-09-24 19:51:39 +02:00
Sander Dorigo
855bc2f8e7 attempted fix for #10956 2025-09-24 14:39:54 +02:00
github-actions[bot]
d8f05492c3 Merge pull request #10955 from firefly-iii/release-1758652896
🤖 Automatically merge the PR into the develop branch.
2025-09-23 20:41:46 +02:00
JC5
4a264f34fa 🤖 Auto commit for release 'develop' on 2025-09-23 2025-09-23 20:41:36 +02:00
James Cole
5a1413e758 Fix #10954 2025-09-23 20:22:58 +02:00
github-actions[bot]
84dbeeb0ce Merge pull request #10946 from firefly-iii/release-1758511378
🤖 Automatically merge the PR into the develop branch.
2025-09-22 05:23:04 +02:00
JC5
d868dc0945 🤖 Auto commit for release 'develop' on 2025-09-22 2025-09-22 05:22:58 +02:00
James Cole
beecf9c229 Make sure demo user cannot send notifications. 2025-09-21 18:00:23 +02:00
github-actions[bot]
e39ba46398 Merge pull request #10943 from firefly-iii/release-1758470243
🤖 Automatically merge the PR into the develop branch.
2025-09-21 17:57:31 +02:00
JC5
e6b6a3cee5 🤖 Auto commit for release 'develop' on 2025-09-21 2025-09-21 17:57:23 +02:00
James Cole
b5483f6ad3 Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2025-09-21 17:52:16 +02:00
James Cole
a751218d53 Fix rule order for #10938 2025-09-21 17:52:07 +02:00
github-actions[bot]
2af5e6eeef Merge pull request #10942 from firefly-iii/release-1758460508
🤖 Automatically merge the PR into the develop branch.
2025-09-21 15:15:17 +02:00
JC5
013c43f9f2 🤖 Auto commit for release 'develop' on 2025-09-21 2025-09-21 15:15:08 +02:00
James Cole
7e08a1f33c Possible fix for #10940, not sure. 2025-09-21 15:11:16 +02:00
James Cole
e592b56d7a Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2025-09-21 15:06:32 +02:00
James Cole
90623101a3 Add earned + spent, needs cleaning up still. 2025-09-21 08:54:26 +02:00
18 changed files with 781 additions and 404 deletions

View File

@@ -402,16 +402,16 @@
}, },
{ {
"name": "friendsofphp/php-cs-fixer", "name": "friendsofphp/php-cs-fixer",
"version": "v3.87.2", "version": "v3.88.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
"reference": "da5f0a7858c79b56fc0b8c36d3efcfe5f37f0992" "reference": "f23469674ae50d40e398bfff8018911a2a2b0dbe"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/da5f0a7858c79b56fc0b8c36d3efcfe5f37f0992", "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/f23469674ae50d40e398bfff8018911a2a2b0dbe",
"reference": "da5f0a7858c79b56fc0b8c36d3efcfe5f37f0992", "reference": "f23469674ae50d40e398bfff8018911a2a2b0dbe",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -438,12 +438,13 @@
"symfony/polyfill-mbstring": "^1.33", "symfony/polyfill-mbstring": "^1.33",
"symfony/polyfill-php80": "^1.33", "symfony/polyfill-php80": "^1.33",
"symfony/polyfill-php81": "^1.33", "symfony/polyfill-php81": "^1.33",
"symfony/polyfill-php84": "^1.33",
"symfony/process": "^5.4.47 || ^6.4.24 || ^7.2", "symfony/process": "^5.4.47 || ^6.4.24 || ^7.2",
"symfony/stopwatch": "^5.4.45 || ^6.4.24 || ^7.0" "symfony/stopwatch": "^5.4.45 || ^6.4.24 || ^7.0"
}, },
"require-dev": { "require-dev": {
"facile-it/paraunit": "^1.3.1 || ^2.7", "facile-it/paraunit": "^1.3.1 || ^2.7",
"infection/infection": "^0.29.14", "infection/infection": "^0.31.0",
"justinrainbow/json-schema": "^6.5", "justinrainbow/json-schema": "^6.5",
"keradus/cli-executor": "^2.2", "keradus/cli-executor": "^2.2",
"mikey179/vfsstream": "^1.6.12", "mikey179/vfsstream": "^1.6.12",
@@ -451,7 +452,6 @@
"php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.6", "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.6",
"php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.6", "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.6",
"phpunit/phpunit": "^9.6.25 || ^10.5.53 || ^11.5.34", "phpunit/phpunit": "^9.6.25 || ^10.5.53 || ^11.5.34",
"symfony/polyfill-php84": "^1.33",
"symfony/var-dumper": "^5.4.48 || ^6.4.24 || ^7.3.2", "symfony/var-dumper": "^5.4.48 || ^6.4.24 || ^7.3.2",
"symfony/yaml": "^5.4.45 || ^6.4.24 || ^7.3.2" "symfony/yaml": "^5.4.45 || ^6.4.24 || ^7.3.2"
}, },
@@ -494,7 +494,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.87.2" "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.88.0"
}, },
"funding": [ "funding": [
{ {
@@ -502,7 +502,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2025-09-10T09:51:40+00:00" "time": "2025-09-24T21:31:42+00:00"
}, },
{ {
"name": "psr/container", "name": "psr/container",
@@ -2283,6 +2283,86 @@
], ],
"time": "2024-09-09T11:45:10+00:00" "time": "2024-09-09T11:45:10+00:00"
}, },
{
"name": "symfony/polyfill-php84",
"version": "v1.33.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php84.git",
"reference": "d8ced4d875142b6a7426000426b8abc631d6b191"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/d8ced4d875142b6a7426000426b8abc631d6b191",
"reference": "d8ced4d875142b6a7426000426b8abc631d6b191",
"shasum": ""
},
"require": {
"php": ">=7.2"
},
"type": "library",
"extra": {
"thanks": {
"url": "https://github.com/symfony/polyfill",
"name": "symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Php84\\": ""
},
"classmap": [
"Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 8.4+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php84/tree/v1.33.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://github.com/nicolas-grekas",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2025-06-24T13:30:11+00:00"
},
{ {
"name": "symfony/process", "name": "symfony/process",
"version": "v7.3.3", "version": "v7.3.3",

View File

@@ -158,18 +158,23 @@ class ShowController extends Controller
Log::debug(sprintf('Now in triggerTransaction(%d, %d)', $webhook->id, $group->id)); Log::debug(sprintf('Now in triggerTransaction(%d, %d)', $webhook->id, $group->id));
Log::channel('audit')->info(sprintf('User triggers webhook #%d on transaction group #%d.', $webhook->id, $group->id)); Log::channel('audit')->info(sprintf('User triggers webhook #%d on transaction group #%d.', $webhook->id, $group->id));
/** @var MessageGeneratorInterface $engine */
$engine = app(MessageGeneratorInterface::class);
$engine->setUser(auth()->user());
// tell the generator which trigger it should look for /** @var \FireflyIII\Models\WebhookTrigger $trigger */
$engine->setTrigger(WebhookTrigger::tryFrom($webhook->trigger)); foreach ($webhook->webhookTriggers as $trigger) {
// tell the generator which objects to process /** @var MessageGeneratorInterface $engine */
$engine->setObjects(new Collection()->push($group)); $engine = app(MessageGeneratorInterface::class);
// set the webhook to trigger $engine->setUser(auth()->user());
$engine->setWebhooks(new Collection()->push($webhook));
// tell the generator to generate the messages // tell the generator which trigger it should look for
$engine->generateMessages(); $engine->setTrigger(WebhookTrigger::tryFrom((int)$trigger->key));
// tell the generator which objects to process
$engine->setObjects(new Collection()->push($group));
// set the webhook to trigger
$engine->setWebhooks(new Collection()->push($webhook));
// tell the generator to generate the messages
$engine->generateMessages();
}
// trigger event to send them: // trigger event to send them:
Log::debug('send event RequestedSendWebhookMessages from ShowController::triggerTransaction()'); Log::debug('send event RequestedSendWebhookMessages from ShowController::triggerTransaction()');

View File

@@ -86,6 +86,7 @@ class GracefulNotFoundHandler extends ExceptionHandler
return $this->handleAttachment($request, $e); return $this->handleAttachment($request, $e);
case 'bills.show': case 'bills.show':
case 'subscriptions.show':
$request->session()->reflash(); $request->session()->reflash();
return redirect(route('bills.index')); return redirect(route('bills.index'));

View File

@@ -122,6 +122,11 @@ class NotificationController extends Controller
public function testNotification(Request $request): RedirectResponse public function testNotification(Request $request): RedirectResponse
{ {
if (true === auth()->user()->hasRole('demo')) {
session()->flash('error', (string) trans('firefly.not_available_demo_user'));
return redirect(route('settings.notification.index'));
}
$all = $request->all(); $all = $request->all();
$channel = $all['test_submit'] ?? ''; $channel = $all['test_submit'] ?? '';

View File

@@ -241,4 +241,11 @@ 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');
}
} }

View File

@@ -0,0 +1,58 @@
<?php
declare(strict_types=1);
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 ReturnsIntegerUserIdTrait;
use SoftDeletes;
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();
}
}

View File

@@ -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 {

View File

@@ -0,0 +1,69 @@
<?php
declare(strict_types=1);
/*
* 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;
}
}

View File

@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
/*
* 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;
}

View File

@@ -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,68 +82,118 @@ 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
@@ -153,25 +206,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,18 +233,28 @@ 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) {
if (!array_key_exists('currency_id', $journal)) {
Log::debug('very strange!');
var_dump($journals);
exit;
}
$currencyId = (int)$journal['currency_id']; $currencyId = (int)$journal['currency_id'];
$currencyCode = $journal['currency_code']; $currencyCode = $journal['currency_code'];
$currencyName = $journal['currency_name']; $currencyName = $journal['currency_name'];
@@ -233,6 +292,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;
@@ -593,13 +653,13 @@ 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;
} }

View File

@@ -130,7 +130,7 @@ class PiggyBankEnrichment implements EnrichmentInterface
} }
$this->amounts[$id][$accountId]['current_amount'] = bcadd($this->amounts[$id][$accountId]['current_amount'], (string) $item->current_amount); $this->amounts[$id][$accountId]['current_amount'] = bcadd($this->amounts[$id][$accountId]['current_amount'], (string) $item->current_amount);
if (null !== $this->amounts[$id][$accountId]['pc_current_amount'] && null !== $item->native_current_amount) { if (null !== $this->amounts[$id][$accountId]['pc_current_amount'] && null !== $item->native_current_amount) {
$this->amounts[$id][$accountId]['pc_current_amount'] = bcadd($this->amounts[$id][$accountId]['pc_current_amount'], $item->native_current_amount); $this->amounts[$id][$accountId]['pc_current_amount'] = bcadd($this->amounts[$id][$accountId]['pc_current_amount'], (string) $item->native_current_amount);
} }
} }

View File

@@ -508,9 +508,11 @@ class SearchRuleEngine implements RuleEngineInterface
{ {
Log::debug(sprintf('Going to fire group #%d with %d rule(s)', $group->id, $group->rules->count())); Log::debug(sprintf('Going to fire group #%d with %d rule(s)', $group->id, $group->rules->count()));
$rules = $group->rules()->orderBy('order', 'ASC')->get();
/** @var Rule $rule */ /** @var Rule $rule */
foreach ($group->rules as $rule) { foreach ($rules as $rule) {
Log::debug(sprintf('Going to fire rule #%d from group #%d', $rule->id, $group->id)); Log::debug(sprintf('Going to fire rule #%d with order #%d from group #%d', $rule->id, $rule->order, $group->id));
$result = $this->fireRule($rule); $result = $this->fireRule($rule);
if (true === $result && true === $rule->stop_processing) { if (true === $result && true === $rule->stop_processing) {
Log::debug(sprintf('The rule was triggered and rule->stop_processing = true, so group #%d will stop processing further rules.', $group->id)); Log::debug(sprintf('The rule was triggered and rule->stop_processing = true, so group #%d will stop processing further rules.', $group->id));

132
composer.lock generated
View File

@@ -1878,16 +1878,16 @@
}, },
{ {
"name": "laravel/framework", "name": "laravel/framework",
"version": "v12.30.1", "version": "v12.31.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laravel/framework.git", "url": "https://github.com/laravel/framework.git",
"reference": "7f61e8679f9142f282a0184ac7ef9e3834bfd023" "reference": "281b711710c245dd8275d73132e92635be3094df"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/7f61e8679f9142f282a0184ac7ef9e3834bfd023", "url": "https://api.github.com/repos/laravel/framework/zipball/281b711710c245dd8275d73132e92635be3094df",
"reference": "7f61e8679f9142f282a0184ac7ef9e3834bfd023", "reference": "281b711710c245dd8275d73132e92635be3094df",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2094,7 +2094,7 @@
"issues": "https://github.com/laravel/framework/issues", "issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework" "source": "https://github.com/laravel/framework"
}, },
"time": "2025-09-18T21:07:07+00:00" "time": "2025-09-23T15:33:04+00:00"
}, },
{ {
"name": "laravel/passport", "name": "laravel/passport",
@@ -2174,16 +2174,16 @@
}, },
{ {
"name": "laravel/prompts", "name": "laravel/prompts",
"version": "v0.3.6", "version": "v0.3.7",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laravel/prompts.git", "url": "https://github.com/laravel/prompts.git",
"reference": "86a8b692e8661d0fb308cec64f3d176821323077" "reference": "a1891d362714bc40c8d23b0b1d7090f022ea27cc"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laravel/prompts/zipball/86a8b692e8661d0fb308cec64f3d176821323077", "url": "https://api.github.com/repos/laravel/prompts/zipball/a1891d362714bc40c8d23b0b1d7090f022ea27cc",
"reference": "86a8b692e8661d0fb308cec64f3d176821323077", "reference": "a1891d362714bc40c8d23b0b1d7090f022ea27cc",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2200,8 +2200,8 @@
"illuminate/collections": "^10.0|^11.0|^12.0", "illuminate/collections": "^10.0|^11.0|^12.0",
"mockery/mockery": "^1.5", "mockery/mockery": "^1.5",
"pestphp/pest": "^2.3|^3.4", "pestphp/pest": "^2.3|^3.4",
"phpstan/phpstan": "^1.11", "phpstan/phpstan": "^1.12.28",
"phpstan/phpstan-mockery": "^1.1" "phpstan/phpstan-mockery": "^1.1.3"
}, },
"suggest": { "suggest": {
"ext-pcntl": "Required for the spinner to be animated." "ext-pcntl": "Required for the spinner to be animated."
@@ -2227,9 +2227,9 @@
"description": "Add beautiful and user-friendly forms to your command-line applications.", "description": "Add beautiful and user-friendly forms to your command-line applications.",
"support": { "support": {
"issues": "https://github.com/laravel/prompts/issues", "issues": "https://github.com/laravel/prompts/issues",
"source": "https://github.com/laravel/prompts/tree/v0.3.6" "source": "https://github.com/laravel/prompts/tree/v0.3.7"
}, },
"time": "2025-07-07T14:17:42+00:00" "time": "2025-09-19T13:47:56+00:00"
}, },
{ {
"name": "laravel/sanctum", "name": "laravel/sanctum",
@@ -2297,16 +2297,16 @@
}, },
{ {
"name": "laravel/serializable-closure", "name": "laravel/serializable-closure",
"version": "v2.0.4", "version": "v2.0.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laravel/serializable-closure.git", "url": "https://github.com/laravel/serializable-closure.git",
"reference": "b352cf0534aa1ae6b4d825d1e762e35d43f8a841" "reference": "3832547db6e0e2f8bb03d4093857b378c66eceed"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laravel/serializable-closure/zipball/b352cf0534aa1ae6b4d825d1e762e35d43f8a841", "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/3832547db6e0e2f8bb03d4093857b378c66eceed",
"reference": "b352cf0534aa1ae6b4d825d1e762e35d43f8a841", "reference": "3832547db6e0e2f8bb03d4093857b378c66eceed",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2354,7 +2354,7 @@
"issues": "https://github.com/laravel/serializable-closure/issues", "issues": "https://github.com/laravel/serializable-closure/issues",
"source": "https://github.com/laravel/serializable-closure" "source": "https://github.com/laravel/serializable-closure"
}, },
"time": "2025-03-19T13:51:03+00:00" "time": "2025-09-22T17:29:40+00:00"
}, },
{ {
"name": "laravel/slack-notification-channel", "name": "laravel/slack-notification-channel",
@@ -4235,24 +4235,26 @@
}, },
{ {
"name": "paragonie/constant_time_encoding", "name": "paragonie/constant_time_encoding",
"version": "v3.0.0", "version": "v3.1.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/paragonie/constant_time_encoding.git", "url": "https://github.com/paragonie/constant_time_encoding.git",
"reference": "df1e7fde177501eee2037dd159cf04f5f301a512" "reference": "d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/df1e7fde177501eee2037dd159cf04f5f301a512", "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77",
"reference": "df1e7fde177501eee2037dd159cf04f5f301a512", "reference": "d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^8" "php": "^8"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^9", "infection/infection": "^0",
"vimeo/psalm": "^4|^5" "nikic/php-fuzzer": "^0",
"phpunit/phpunit": "^9|^10|^11",
"vimeo/psalm": "^4|^5|^6"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
@@ -4298,7 +4300,7 @@
"issues": "https://github.com/paragonie/constant_time_encoding/issues", "issues": "https://github.com/paragonie/constant_time_encoding/issues",
"source": "https://github.com/paragonie/constant_time_encoding" "source": "https://github.com/paragonie/constant_time_encoding"
}, },
"time": "2024-05-08T12:36:18+00:00" "time": "2025-09-24T15:06:41+00:00"
}, },
{ {
"name": "paragonie/random_compat", "name": "paragonie/random_compat",
@@ -4352,16 +4354,16 @@
}, },
{ {
"name": "phiki/phiki", "name": "phiki/phiki",
"version": "v2.0.3", "version": "v2.0.4",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phikiphp/phiki.git", "url": "https://github.com/phikiphp/phiki.git",
"reference": "fe51fe6dc31856cd776fd1b04ee74053a4271644" "reference": "160785c50c01077780ab217e5808f00ab8f05a13"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phikiphp/phiki/zipball/fe51fe6dc31856cd776fd1b04ee74053a4271644", "url": "https://api.github.com/repos/phikiphp/phiki/zipball/160785c50c01077780ab217e5808f00ab8f05a13",
"reference": "fe51fe6dc31856cd776fd1b04ee74053a4271644", "reference": "160785c50c01077780ab217e5808f00ab8f05a13",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -4407,7 +4409,7 @@
"description": "Syntax highlighting using TextMate grammars in PHP.", "description": "Syntax highlighting using TextMate grammars in PHP.",
"support": { "support": {
"issues": "https://github.com/phikiphp/phiki/issues", "issues": "https://github.com/phikiphp/phiki/issues",
"source": "https://github.com/phikiphp/phiki/tree/v2.0.3" "source": "https://github.com/phikiphp/phiki/tree/v2.0.4"
}, },
"funding": [ "funding": [
{ {
@@ -4419,7 +4421,7 @@
"type": "other" "type": "other"
} }
], ],
"time": "2025-09-19T11:50:41+00:00" "time": "2025-09-20T17:21:02+00:00"
}, },
{ {
"name": "php-http/client-common", "name": "php-http/client-common",
@@ -11404,16 +11406,16 @@
}, },
{ {
"name": "phpstan/phpstan", "name": "phpstan/phpstan",
"version": "2.1.28", "version": "2.1.29",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpstan/phpstan.git", "url": "https://github.com/phpstan/phpstan-phar-composer-source.git",
"reference": "578fa296a166605d97b94091f724f1257185d278" "reference": "git"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/578fa296a166605d97b94091f724f1257185d278", "url": "https://api.github.com/repos/phpstan/phpstan/zipball/d618573eed4a1b6b75e37b2e0b65ac65c885d88e",
"reference": "578fa296a166605d97b94091f724f1257185d278", "reference": "d618573eed4a1b6b75e37b2e0b65ac65c885d88e",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -11458,7 +11460,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2025-09-19T08:58:49+00:00" "time": "2025-09-25T06:58:18+00:00"
}, },
{ {
"name": "phpstan/phpstan-deprecation-rules", "name": "phpstan/phpstan-deprecation-rules",
@@ -11557,16 +11559,16 @@
}, },
{ {
"name": "phpunit/php-code-coverage", "name": "phpunit/php-code-coverage",
"version": "12.3.8", "version": "12.4.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "99e692c6a84708211f7536ba322bbbaef57ac7fc" "reference": "67e8aed88f93d0e6e1cb7effe1a2dfc2fee6022c"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/99e692c6a84708211f7536ba322bbbaef57ac7fc", "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/67e8aed88f93d0e6e1cb7effe1a2dfc2fee6022c",
"reference": "99e692c6a84708211f7536ba322bbbaef57ac7fc", "reference": "67e8aed88f93d0e6e1cb7effe1a2dfc2fee6022c",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -11593,7 +11595,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "12.3.x-dev" "dev-main": "12.4.x-dev"
} }
}, },
"autoload": { "autoload": {
@@ -11622,7 +11624,7 @@
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
"security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/12.3.8" "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/12.4.0"
}, },
"funding": [ "funding": [
{ {
@@ -11642,7 +11644,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2025-09-17T11:31:43+00:00" "time": "2025-09-24T13:44:41+00:00"
}, },
{ {
"name": "phpunit/php-file-iterator", "name": "phpunit/php-file-iterator",
@@ -11891,16 +11893,16 @@
}, },
{ {
"name": "phpunit/phpunit", "name": "phpunit/phpunit",
"version": "12.3.11", "version": "12.3.14",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git", "url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "6a62f2b394e042884e4997ddc8b8db1ce56a0009" "reference": "13e9b2bea9327b094176147250d2c10319a10f5b"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/6a62f2b394e042884e4997ddc8b8db1ce56a0009", "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/13e9b2bea9327b094176147250d2c10319a10f5b",
"reference": "6a62f2b394e042884e4997ddc8b8db1ce56a0009", "reference": "13e9b2bea9327b094176147250d2c10319a10f5b",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -11914,16 +11916,16 @@
"phar-io/manifest": "^2.0.4", "phar-io/manifest": "^2.0.4",
"phar-io/version": "^3.2.1", "phar-io/version": "^3.2.1",
"php": ">=8.3", "php": ">=8.3",
"phpunit/php-code-coverage": "^12.3.7", "phpunit/php-code-coverage": "^12.3.8",
"phpunit/php-file-iterator": "^6.0.0", "phpunit/php-file-iterator": "^6.0.0",
"phpunit/php-invoker": "^6.0.0", "phpunit/php-invoker": "^6.0.0",
"phpunit/php-text-template": "^5.0.0", "phpunit/php-text-template": "^5.0.0",
"phpunit/php-timer": "^8.0.0", "phpunit/php-timer": "^8.0.0",
"sebastian/cli-parser": "^4.1.0", "sebastian/cli-parser": "^4.2.0",
"sebastian/comparator": "^7.1.3", "sebastian/comparator": "^7.1.3",
"sebastian/diff": "^7.0.0", "sebastian/diff": "^7.0.0",
"sebastian/environment": "^8.0.3", "sebastian/environment": "^8.0.3",
"sebastian/exporter": "^7.0.0", "sebastian/exporter": "^7.0.2",
"sebastian/global-state": "^8.0.2", "sebastian/global-state": "^8.0.2",
"sebastian/object-enumerator": "^7.0.0", "sebastian/object-enumerator": "^7.0.0",
"sebastian/type": "^6.0.3", "sebastian/type": "^6.0.3",
@@ -11968,7 +11970,7 @@
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues", "issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy", "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
"source": "https://github.com/sebastianbergmann/phpunit/tree/12.3.11" "source": "https://github.com/sebastianbergmann/phpunit/tree/12.3.14"
}, },
"funding": [ "funding": [
{ {
@@ -11992,7 +11994,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2025-09-14T06:21:44+00:00" "time": "2025-09-24T06:34:27+00:00"
}, },
{ {
"name": "rector/rector", "name": "rector/rector",
@@ -12418,16 +12420,16 @@
}, },
{ {
"name": "sebastian/exporter", "name": "sebastian/exporter",
"version": "7.0.0", "version": "7.0.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/exporter.git", "url": "https://github.com/sebastianbergmann/exporter.git",
"reference": "76432aafc58d50691a00d86d0632f1217a47b688" "reference": "016951ae10980765e4e7aee491eb288c64e505b7"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/76432aafc58d50691a00d86d0632f1217a47b688", "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/016951ae10980765e4e7aee491eb288c64e505b7",
"reference": "76432aafc58d50691a00d86d0632f1217a47b688", "reference": "016951ae10980765e4e7aee491eb288c64e505b7",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -12484,15 +12486,27 @@
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/exporter/issues", "issues": "https://github.com/sebastianbergmann/exporter/issues",
"security": "https://github.com/sebastianbergmann/exporter/security/policy", "security": "https://github.com/sebastianbergmann/exporter/security/policy",
"source": "https://github.com/sebastianbergmann/exporter/tree/7.0.0" "source": "https://github.com/sebastianbergmann/exporter/tree/7.0.2"
}, },
"funding": [ "funding": [
{ {
"url": "https://github.com/sebastianbergmann", "url": "https://github.com/sebastianbergmann",
"type": "github" "type": "github"
},
{
"url": "https://liberapay.com/sebastianbergmann",
"type": "liberapay"
},
{
"url": "https://thanks.dev/u/gh/sebastianbergmann",
"type": "thanks_dev"
},
{
"url": "https://tidelift.com/funding/github/packagist/sebastian/exporter",
"type": "tidelift"
} }
], ],
"time": "2025-02-07T04:56:42+00:00" "time": "2025-09-24T06:16:11+00:00"
}, },
{ {
"name": "sebastian/global-state", "name": "sebastian/global-state",

View File

@@ -78,10 +78,10 @@ return [
'running_balance_column' => env('USE_RUNNING_BALANCE', false), 'running_balance_column' => env('USE_RUNNING_BALANCE', false),
// see cer.php for exchange rates feature flag. // see cer.php for exchange rates feature flag.
], ],
'version' => 'develop/2025-09-21', 'version' => 'develop/2025-09-25',
'build_time' => 1758437799, 'build_time' => 1758820163,
'api_version' => '2.1.0', // field is no longer used. 'api_version' => '2.1.0', // field is no longer used.
'db_version' => 26, 'db_version' => 27,
// generic settings // generic settings
'maxUploadSize' => 1073741824, // 1 GB 'maxUploadSize' => 1073741824, // 1 GB

View File

@@ -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');
}
};

415
package-lock.json generated
View File

@@ -2589,9 +2589,9 @@
} }
}, },
"node_modules/@rollup/rollup-android-arm-eabi": { "node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.52.0", "version": "4.52.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.2.tgz",
"integrity": "sha512-VxDYCDqOaR7NXzAtvRx7G1u54d2kEHopb28YH/pKzY6y0qmogP3gG7CSiWsq9WvDFxOQMpNEyjVAHZFXfH3o/A==", "integrity": "sha512-o3pcKzJgSGt4d74lSZ+OCnHwkKBeAbFDmbEm5gg70eA8VkyCuC/zV9TwBnmw6VjDlRdF4Pshfb+WE9E6XY1PoQ==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@@ -2603,9 +2603,9 @@
] ]
}, },
"node_modules/@rollup/rollup-android-arm64": { "node_modules/@rollup/rollup-android-arm64": {
"version": "4.52.0", "version": "4.52.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.2.tgz",
"integrity": "sha512-pqDirm8koABIKvzL59YI9W9DWbRlTX7RWhN+auR8HXJxo89m4mjqbah7nJZjeKNTNYopqL+yGg+0mhCpf3xZtQ==", "integrity": "sha512-cqFSWO5tX2vhC9hJTK8WAiPIm4Q8q/cU8j2HQA0L3E1uXvBYbOZMhE2oFL8n2pKB5sOCHY6bBuHaRwG7TkfJyw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -2617,9 +2617,9 @@
] ]
}, },
"node_modules/@rollup/rollup-darwin-arm64": { "node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.52.0", "version": "4.52.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.2.tgz",
"integrity": "sha512-YCdWlY/8ltN6H78HnMsRHYlPiKvqKagBP1r+D7SSylxX+HnsgXGCmLiV3Y4nSyY9hW8qr8U9LDUx/Lo7M6MfmQ==", "integrity": "sha512-vngduywkkv8Fkh3wIZf5nFPXzWsNsVu1kvtLETWxTFf/5opZmflgVSeLgdHR56RQh71xhPhWoOkEBvbehwTlVA==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -2631,9 +2631,9 @@
] ]
}, },
"node_modules/@rollup/rollup-darwin-x64": { "node_modules/@rollup/rollup-darwin-x64": {
"version": "4.52.0", "version": "4.52.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.2.tgz",
"integrity": "sha512-z4nw6y1j+OOSGzuVbSWdIp1IUks9qNw4dc7z7lWuWDKojY38VMWBlEN7F9jk5UXOkUcp97vA1N213DF+Lz8BRg==", "integrity": "sha512-h11KikYrUCYTrDj6h939hhMNlqU2fo/X4NB0OZcys3fya49o1hmFaczAiJWVAFgrM1NCP6RrO7lQKeVYSKBPSQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -2645,9 +2645,9 @@
] ]
}, },
"node_modules/@rollup/rollup-freebsd-arm64": { "node_modules/@rollup/rollup-freebsd-arm64": {
"version": "4.52.0", "version": "4.52.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.2.tgz",
"integrity": "sha512-Q/dv9Yvyr5rKlK8WQJZVrp5g2SOYeZUs9u/t2f9cQ2E0gJjYB/BWoedXfUT0EcDJefi2zzVfhcOj8drWCzTviw==", "integrity": "sha512-/eg4CI61ZUkLXxMHyVlmlGrSQZ34xqWlZNW43IAU4RmdzWEx0mQJ2mN/Cx4IHLVZFL6UBGAh+/GXhgvGb+nVxw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -2659,9 +2659,9 @@
] ]
}, },
"node_modules/@rollup/rollup-freebsd-x64": { "node_modules/@rollup/rollup-freebsd-x64": {
"version": "4.52.0", "version": "4.52.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.2.tgz",
"integrity": "sha512-kdBsLs4Uile/fbjZVvCRcKB4q64R+1mUq0Yd7oU1CMm1Av336ajIFqNFovByipciuUQjBCPMxwJhCgfG2re3rg==", "integrity": "sha512-QOWgFH5X9+p+S1NAfOqc0z8qEpJIoUHf7OWjNUGOeW18Mx22lAUOiA9b6r2/vpzLdfxi/f+VWsYjUOMCcYh0Ng==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -2673,9 +2673,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm-gnueabihf": { "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.52.0", "version": "4.52.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.2.tgz",
"integrity": "sha512-aL6hRwu0k7MTUESgkg7QHY6CoqPgr6gdQXRJI1/VbFlUMwsSzPGSR7sG5d+MCbYnJmJwThc2ol3nixj1fvI/zQ==", "integrity": "sha512-kDWSPafToDd8LcBYd1t5jw7bD5Ojcu12S3uT372e5HKPzQt532vW+rGFFOaiR0opxePyUkHrwz8iWYEyH1IIQA==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@@ -2687,9 +2687,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm-musleabihf": { "node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.52.0", "version": "4.52.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.2.tgz",
"integrity": "sha512-BTs0M5s1EJejgIBJhCeiFo7GZZ2IXWkFGcyZhxX4+8usnIo5Mti57108vjXFIQmmJaRyDwmV59Tw64Ap1dkwMw==", "integrity": "sha512-gKm7Mk9wCv6/rkzwCiUC4KnevYhlf8ztBrDRT9g/u//1fZLapSRc+eDZj2Eu2wpJ+0RzUKgtNijnVIB4ZxyL+w==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@@ -2701,9 +2701,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm64-gnu": { "node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.52.0", "version": "4.52.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.2.tgz",
"integrity": "sha512-uj672IVOU9m08DBGvoPKPi/J8jlVgjh12C9GmjjBxCTQc3XtVmRkRKyeHSmIKQpvJ7fIm1EJieBUcnGSzDVFyw==", "integrity": "sha512-66lA8vnj5mB/rtDNwPgrrKUOtCLVQypkyDa2gMfOefXK6rcZAxKLO9Fy3GkW8VkPnENv9hBkNOFfGLf6rNKGUg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -2715,9 +2715,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm64-musl": { "node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.52.0", "version": "4.52.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.2.tgz",
"integrity": "sha512-/+IVbeDMDCtB/HP/wiWsSzduD10SEGzIZX2945KSgZRNi4TSkjHqRJtNTVtVb8IRwhJ65ssI56krlLik+zFWkw==", "integrity": "sha512-s+OPucLNdJHvuZHuIz2WwncJ+SfWHFEmlC5nKMUgAelUeBUnlB4wt7rXWiyG4Zn07uY2Dd+SGyVa9oyLkVGOjA==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -2729,9 +2729,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-loong64-gnu": { "node_modules/@rollup/rollup-linux-loong64-gnu": {
"version": "4.52.0", "version": "4.52.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.2.tgz",
"integrity": "sha512-U1vVzvSWtSMWKKrGoROPBXMh3Vwn93TA9V35PldokHGqiUbF6erSzox/5qrSMKp6SzakvyjcPiVF8yB1xKr9Pg==", "integrity": "sha512-8wTRM3+gVMDLLDdaT6tKmOE3lJyRy9NpJUS/ZRWmLCmOPIJhVyXwjBo+XbrrwtV33Em1/eCTd5TuGJm4+DmYjw==",
"cpu": [ "cpu": [
"loong64" "loong64"
], ],
@@ -2743,9 +2743,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-ppc64-gnu": { "node_modules/@rollup/rollup-linux-ppc64-gnu": {
"version": "4.52.0", "version": "4.52.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.2.tgz",
"integrity": "sha512-X/4WfuBAdQRH8cK3DYl8zC00XEE6aM472W+QCycpQJeLWVnHfkv7RyBFVaTqNUMsTgIX8ihMjCvFF9OUgeABzw==", "integrity": "sha512-6yqEfgJ1anIeuP2P/zhtfBlDpXUb80t8DpbYwXQ3bQd95JMvUaqiX+fKqYqUwZXqdJDd8xdilNtsHM2N0cFm6A==",
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
@@ -2757,9 +2757,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-riscv64-gnu": { "node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.52.0", "version": "4.52.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.2.tgz",
"integrity": "sha512-xIRYc58HfWDBZoLmWfWXg2Sq8VCa2iJ32B7mqfWnkx5mekekl0tMe7FHpY8I72RXEcUkaWawRvl3qA55og+cwQ==", "integrity": "sha512-sshYUiYVSEI2B6dp4jMncwxbrUqRdNApF2c3bhtLAU0qA8Lrri0p0NauOsTWh3yCCCDyBOjESHMExonp7Nzc0w==",
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
@@ -2771,9 +2771,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-riscv64-musl": { "node_modules/@rollup/rollup-linux-riscv64-musl": {
"version": "4.52.0", "version": "4.52.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.2.tgz",
"integrity": "sha512-mbsoUey05WJIOz8U1WzNdf+6UMYGwE3fZZnQqsM22FZ3wh1N887HT6jAOjXs6CNEK3Ntu2OBsyQDXfIjouI4dw==", "integrity": "sha512-duBLgd+3pqC4MMwBrKkFxaZerUxZcYApQVC5SdbF5/e/589GwVvlRUnyqMFbM8iUSb1BaoX/3fRL7hB9m2Pj8Q==",
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
@@ -2785,9 +2785,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-s390x-gnu": { "node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.52.0", "version": "4.52.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.2.tgz",
"integrity": "sha512-qP6aP970bucEi5KKKR4AuPFd8aTx9EF6BvutvYxmZuWLJHmnq4LvBfp0U+yFDMGwJ+AIJEH5sIP+SNypauMWzg==", "integrity": "sha512-tzhYJJidDUVGMgVyE+PmxENPHlvvqm1KILjjZhB8/xHYqAGeizh3GBGf9u6WdJpZrz1aCpIIHG0LgJgH9rVjHQ==",
"cpu": [ "cpu": [
"s390x" "s390x"
], ],
@@ -2799,9 +2799,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-x64-gnu": { "node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.52.0", "version": "4.52.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.2.tgz",
"integrity": "sha512-nmSVN+F2i1yKZ7rJNKO3G7ZzmxJgoQBQZ/6c4MuS553Grmr7WqR7LLDcYG53Z2m9409z3JLt4sCOhLdbKQ3HmA==", "integrity": "sha512-opH8GSUuVcCSSyHHcl5hELrmnk4waZoVpgn/4FDao9iyE4WpQhyWJ5ryl5M3ocp4qkRuHfyXnGqg8M9oKCEKRA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -2813,9 +2813,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-x64-musl": { "node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.52.0", "version": "4.52.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.2.tgz",
"integrity": "sha512-2d0qRo33G6TfQVjaMR71P+yJVGODrt5V6+T0BDYH4EMfGgdC/2HWDVjSSFw888GSzAZUwuska3+zxNUCDco6rQ==", "integrity": "sha512-LSeBHnGli1pPKVJ79ZVJgeZWWZXkEe/5o8kcn23M8eMKCUANejchJbF/JqzM4RRjOJfNRhKJk8FuqL1GKjF5oQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -2827,9 +2827,9 @@
] ]
}, },
"node_modules/@rollup/rollup-openharmony-arm64": { "node_modules/@rollup/rollup-openharmony-arm64": {
"version": "4.52.0", "version": "4.52.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.2.tgz",
"integrity": "sha512-A1JalX4MOaFAAyGgpO7XP5khquv/7xKzLIyLmhNrbiCxWpMlnsTYr8dnsWM7sEeotNmxvSOEL7F65j0HXFcFsw==", "integrity": "sha512-uPj7MQ6/s+/GOpolavm6BPo+6CbhbKYyZHUDvZ/SmJM7pfDBgdGisFX3bY/CBDMg2ZO4utfhlApkSfZ92yXw7Q==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -2841,9 +2841,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-arm64-msvc": { "node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.52.0", "version": "4.52.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.2.tgz",
"integrity": "sha512-YQugafP/rH0eOOHGjmNgDURrpYHrIX0yuojOI8bwCyXwxC9ZdTd3vYkmddPX0oHONLXu9Rb1dDmT0VNpjkzGGw==", "integrity": "sha512-Z9MUCrSgIaUeeHAiNkm3cQyst2UhzjPraR3gYYfOjAuZI7tcFRTOD+4cHLPoS/3qinchth+V56vtqz1Tv+6KPA==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -2855,9 +2855,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-ia32-msvc": { "node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.52.0", "version": "4.52.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.2.tgz",
"integrity": "sha512-zYdUYhi3Qe2fndujBqL5FjAFzvNeLxtIqfzNEVKD1I7C37/chv1VxhscWSQHTNfjPCrBFQMnynwA3kpZpZ8w4A==", "integrity": "sha512-+GnYBmpjldD3XQd+HMejo+0gJGwYIOfFeoBQv32xF/RUIvccUz20/V6Otdv+57NE70D5pa8W/jVGDoGq0oON4A==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@@ -2869,9 +2869,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-x64-gnu": { "node_modules/@rollup/rollup-win32-x64-gnu": {
"version": "4.52.0", "version": "4.52.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.2.tgz",
"integrity": "sha512-fGk03kQylNaCOQ96HDMeT7E2n91EqvCDd3RwvT5k+xNdFCeMGnj5b5hEgTGrQuyidqSsD3zJDQ21QIaxXqTBJw==", "integrity": "sha512-ApXFKluSB6kDQkAqZOKXBjiaqdF1BlKi+/eqnYe9Ee7U2K3pUDKsIyr8EYm/QDHTJIM+4X+lI0gJc3TTRhd+dA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -2883,9 +2883,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-x64-msvc": { "node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.52.0", "version": "4.52.2",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.0.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.2.tgz",
"integrity": "sha512-6iKDCVSIUQ8jPMoIV0OytRKniaYyy5EbY/RRydmLW8ZR3cEBhxbWl5ro0rkUNe0ef6sScvhbY79HrjRm8i3vDQ==", "integrity": "sha512-ARz+Bs8kY6FtitYM96PqPEVvPXqEZmPZsSkXvyX19YzDqkCaIlhCieLLMI5hxO9SRZ2XtCtm8wxhy0iJ2jxNfw==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -3281,57 +3281,57 @@
} }
}, },
"node_modules/@vue/compiler-core": { "node_modules/@vue/compiler-core": {
"version": "3.5.21", "version": "3.5.22",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.21.tgz", "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.22.tgz",
"integrity": "sha512-8i+LZ0vf6ZgII5Z9XmUvrCyEzocvWT+TeR2VBUVlzIH6Tyv57E20mPZ1bCS+tbejgUgmjrEh7q/0F0bibskAmw==", "integrity": "sha512-jQ0pFPmZwTEiRNSb+i9Ow/I/cHv2tXYqsnHKKyCQ08irI2kdF5qmYedmF8si8mA7zepUFmJ2hqzS8CQmNOWOkQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/parser": "^7.28.3", "@babel/parser": "^7.28.4",
"@vue/shared": "3.5.21", "@vue/shared": "3.5.22",
"entities": "^4.5.0", "entities": "^4.5.0",
"estree-walker": "^2.0.2", "estree-walker": "^2.0.2",
"source-map-js": "^1.2.1" "source-map-js": "^1.2.1"
} }
}, },
"node_modules/@vue/compiler-dom": { "node_modules/@vue/compiler-dom": {
"version": "3.5.21", "version": "3.5.22",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.21.tgz", "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.22.tgz",
"integrity": "sha512-jNtbu/u97wiyEBJlJ9kmdw7tAr5Vy0Aj5CgQmo+6pxWNQhXZDPsRr1UWPN4v3Zf82s2H3kF51IbzZ4jMWAgPlQ==", "integrity": "sha512-W8RknzUM1BLkypvdz10OVsGxnMAuSIZs9Wdx1vzA3mL5fNMN15rhrSCLiTm6blWeACwUwizzPVqGJgOGBEN/hA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vue/compiler-core": "3.5.21", "@vue/compiler-core": "3.5.22",
"@vue/shared": "3.5.21" "@vue/shared": "3.5.22"
} }
}, },
"node_modules/@vue/compiler-sfc": { "node_modules/@vue/compiler-sfc": {
"version": "3.5.21", "version": "3.5.22",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.21.tgz", "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.22.tgz",
"integrity": "sha512-SXlyk6I5eUGBd2v8Ie7tF6ADHE9kCR6mBEuPyH1nUZ0h6Xx6nZI29i12sJKQmzbDyr2tUHMhhTt51Z6blbkTTQ==", "integrity": "sha512-tbTR1zKGce4Lj+JLzFXDq36K4vcSZbJ1RBu8FxcDv1IGRz//Dh2EBqksyGVypz3kXpshIfWKGOCcqpSbyGWRJQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/parser": "^7.28.3", "@babel/parser": "^7.28.4",
"@vue/compiler-core": "3.5.21", "@vue/compiler-core": "3.5.22",
"@vue/compiler-dom": "3.5.21", "@vue/compiler-dom": "3.5.22",
"@vue/compiler-ssr": "3.5.21", "@vue/compiler-ssr": "3.5.22",
"@vue/shared": "3.5.21", "@vue/shared": "3.5.22",
"estree-walker": "^2.0.2", "estree-walker": "^2.0.2",
"magic-string": "^0.30.18", "magic-string": "^0.30.19",
"postcss": "^8.5.6", "postcss": "^8.5.6",
"source-map-js": "^1.2.1" "source-map-js": "^1.2.1"
} }
}, },
"node_modules/@vue/compiler-ssr": { "node_modules/@vue/compiler-ssr": {
"version": "3.5.21", "version": "3.5.22",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.21.tgz", "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.22.tgz",
"integrity": "sha512-vKQ5olH5edFZdf5ZrlEgSO1j1DMA4u23TVK5XR1uMhvwnYvVdDF0nHXJUblL/GvzlShQbjhZZ2uvYmDlAbgo9w==", "integrity": "sha512-GdgyLvg4R+7T8Nk2Mlighx7XGxq/fJf9jaVofc3IL0EPesTE86cP/8DD1lT3h1JeZr2ySBvyqKQJgbS54IX1Ww==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vue/compiler-dom": "3.5.21", "@vue/compiler-dom": "3.5.22",
"@vue/shared": "3.5.21" "@vue/shared": "3.5.22"
} }
}, },
"node_modules/@vue/component-compiler-utils": { "node_modules/@vue/component-compiler-utils": {
@@ -3413,9 +3413,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@vue/shared": { "node_modules/@vue/shared": {
"version": "3.5.21", "version": "3.5.22",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.21.tgz", "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.22.tgz",
"integrity": "sha512-+2k1EQpnYuVuu3N7atWyG3/xoFWIVJZq4Mz8XNOdScFI0etES75fbny/oU4lKWk/577P1zmg0ioYvpGEDZ3DLw==", "integrity": "sha512-F4yc6palwq3TT0u+FYf0Ns4Tfl9GRFURDN2gWG7L1ecIaS/4fCIuFOjMTnCyjsu/OK6vaDKLCrGAa+KvvH+h4w==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
@@ -4075,9 +4075,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/baseline-browser-mapping": { "node_modules/baseline-browser-mapping": {
"version": "2.8.6", "version": "2.8.7",
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.6.tgz", "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.7.tgz",
"integrity": "sha512-wrH5NNqren/QMtKUEEJf7z86YjfqW/2uw3IL3/xpqZUC95SSVIFXYQeeGjL6FT/X68IROu6RMehZQS5foy2BXw==", "integrity": "sha512-bxxN2M3a4d1CRoQC//IqsR5XrLh0IJ8TCv2x6Y9N0nckNz/rTjZB3//GGscZziZOxmjP55rzxg/ze7usFI9FqQ==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"bin": { "bin": {
@@ -4329,25 +4329,24 @@
} }
}, },
"node_modules/browserify-sign": { "node_modules/browserify-sign": {
"version": "4.2.3", "version": "4.2.5",
"resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.3.tgz", "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.5.tgz",
"integrity": "sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==", "integrity": "sha512-C2AUdAJg6rlM2W5QMp2Q4KGQMVBwR1lIimTsUnutJ8bMpW5B52pGpR2gEnNBNwijumDo5FojQ0L9JrXA8m4YEw==",
"dev": true, "dev": true,
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"bn.js": "^5.2.1", "bn.js": "^5.2.2",
"browserify-rsa": "^4.1.0", "browserify-rsa": "^4.1.1",
"create-hash": "^1.2.0", "create-hash": "^1.2.0",
"create-hmac": "^1.1.7", "create-hmac": "^1.1.7",
"elliptic": "^6.5.5", "elliptic": "^6.6.1",
"hash-base": "~3.0",
"inherits": "^2.0.4", "inherits": "^2.0.4",
"parse-asn1": "^5.1.7", "parse-asn1": "^5.1.9",
"readable-stream": "^2.3.8", "readable-stream": "^2.3.8",
"safe-buffer": "^5.2.1" "safe-buffer": "^5.2.1"
}, },
"engines": { "engines": {
"node": ">= 0.12" "node": ">= 0.10"
} }
}, },
"node_modules/browserify-zlib": { "node_modules/browserify-zlib": {
@@ -4522,9 +4521,9 @@
} }
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001743", "version": "1.0.30001745",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001743.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001745.tgz",
"integrity": "sha512-e6Ojr7RV14Un7dz6ASD0aZDmQPT/A+eZU+nuTNfjqmRrmkmQlnTNWH0SKmqagx9PeW87UVqapSurtAXifmtdmw==", "integrity": "sha512-ywt6i8FzvdgrrrGbr1jZVObnVv6adj+0if2/omv9cmR2oiZs30zL4DIyaptKcbOrBdOIc74QTMoJvSE2QHh5UQ==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@@ -4652,14 +4651,15 @@
} }
}, },
"node_modules/cipher-base": { "node_modules/cipher-base": {
"version": "1.0.6", "version": "1.0.7",
"resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.6.tgz", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.7.tgz",
"integrity": "sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==", "integrity": "sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"inherits": "^2.0.4", "inherits": "^2.0.4",
"safe-buffer": "^5.2.1" "safe-buffer": "^5.2.1",
"to-buffer": "^1.2.2"
}, },
"engines": { "engines": {
"node": ">= 0.10" "node": ">= 0.10"
@@ -5736,9 +5736,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/electron-to-chromium": { "node_modules/electron-to-chromium": {
"version": "1.5.222", "version": "1.5.223",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.222.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.223.tgz",
"integrity": "sha512-gA7psSwSwQRE60CEoLz6JBCQPIxNeuzB2nL8vE03GK/OHxlvykbLyeiumQy1iH5C2f3YbRAZpGCMT12a/9ih9w==", "integrity": "sha512-qKm55ic6nbEmagFlTFczML33rF90aU+WtrJ9MdTCThrcvDNdUHN4p6QfVN78U06ZmguqXIyMPyYhw2TrbDUwPQ==",
"dev": true, "dev": true,
"license": "ISC" "license": "ISC"
}, },
@@ -8761,17 +8761,16 @@
} }
}, },
"node_modules/parse-asn1": { "node_modules/parse-asn1": {
"version": "5.1.7", "version": "5.1.9",
"resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.7.tgz", "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.9.tgz",
"integrity": "sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==", "integrity": "sha512-fIYNuZ/HastSb80baGOuPRo1O9cf4baWw5WsAp7dBuUzeTD/BoaG8sVTdlPFksBE2lF21dN+A1AnrpIjSWqHHg==",
"dev": true, "dev": true,
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"asn1.js": "^4.10.1", "asn1.js": "^4.10.1",
"browserify-aes": "^1.2.0", "browserify-aes": "^1.2.0",
"evp_bytestokey": "^1.0.3", "evp_bytestokey": "^1.0.3",
"hash-base": "~3.0", "pbkdf2": "^3.1.5",
"pbkdf2": "^3.1.2",
"safe-buffer": "^5.2.1" "safe-buffer": "^5.2.1"
}, },
"engines": { "engines": {
@@ -8937,55 +8936,21 @@
} }
}, },
"node_modules/pbkdf2": { "node_modules/pbkdf2": {
"version": "3.1.3", "version": "3.1.5",
"resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.3.tgz", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.5.tgz",
"integrity": "sha512-wfRLBZ0feWRhCIkoMB6ete7czJcnNnqRpcoWQBLqatqXXmelSRqfdDK4F3u9T2s2cXas/hQJcryI/4lAL+XTlA==", "integrity": "sha512-Q3CG/cYvCO1ye4QKkuH7EXxs3VC/rI1/trd+qX2+PolbaKG0H+bgcZzrTt96mMyRtejk+JMCiLUn3y29W8qmFQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"create-hash": "~1.1.3", "create-hash": "^1.2.0",
"create-hmac": "^1.1.7", "create-hmac": "^1.1.7",
"ripemd160": "=2.0.1", "ripemd160": "^2.0.3",
"safe-buffer": "^5.2.1", "safe-buffer": "^5.2.1",
"sha.js": "^2.4.11", "sha.js": "^2.4.12",
"to-buffer": "^1.2.0" "to-buffer": "^1.2.1"
}, },
"engines": { "engines": {
"node": ">=0.12" "node": ">= 0.10"
}
},
"node_modules/pbkdf2/node_modules/create-hash": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz",
"integrity": "sha512-snRpch/kwQhcdlnZKYanNF1m0RDlrCdSKQaH87w1FCFPVPNCQ/Il9QJKAX2jVBZddRdaHBMC+zXa9Gw9tmkNUA==",
"dev": true,
"license": "MIT",
"dependencies": {
"cipher-base": "^1.0.1",
"inherits": "^2.0.1",
"ripemd160": "^2.0.0",
"sha.js": "^2.4.0"
}
},
"node_modules/pbkdf2/node_modules/hash-base": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz",
"integrity": "sha512-0TROgQ1/SxE6KmxWSvXHvRj90/Xo1JvZShofnYF+f6ZsGtR4eES7WfrQzPalmyagfKZCXpVnitiRebZulWsbiw==",
"dev": true,
"license": "MIT",
"dependencies": {
"inherits": "^2.0.1"
}
},
"node_modules/pbkdf2/node_modules/ripemd160": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz",
"integrity": "sha512-J7f4wutN8mdbV08MJnXibYpCOPHR+yzy+iQ/AsjMv2j8cLavQ8VGagDFUwwTAdF8FmRKVeNpbTTEwNHCW1g94w==",
"dev": true,
"license": "MIT",
"dependencies": {
"hash-base": "^2.0.0",
"inherits": "^2.0.1"
} }
}, },
"node_modules/picocolors": { "node_modules/picocolors": {
@@ -9961,16 +9926,16 @@
} }
}, },
"node_modules/regexpu-core": { "node_modules/regexpu-core": {
"version": "6.3.1", "version": "6.4.0",
"resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.3.1.tgz", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz",
"integrity": "sha512-DzcswPr252wEr7Qz8AyAVbfyBDKLoYp6eRA1We2Fa9qirRFSdtkP5sHr3yglDKy2BbA0fd2T+j/CUSKes3FeVQ==", "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"regenerate": "^1.4.2", "regenerate": "^1.4.2",
"regenerate-unicode-properties": "^10.2.2", "regenerate-unicode-properties": "^10.2.2",
"regjsgen": "^0.8.0", "regjsgen": "^0.8.0",
"regjsparser": "^0.12.0", "regjsparser": "^0.13.0",
"unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-ecmascript": "^2.0.0",
"unicode-match-property-value-ecmascript": "^2.2.1" "unicode-match-property-value-ecmascript": "^2.2.1"
}, },
@@ -9986,31 +9951,18 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/regjsparser": { "node_modules/regjsparser": {
"version": "0.12.0", "version": "0.13.0",
"resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.0.tgz",
"integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", "integrity": "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==",
"dev": true, "dev": true,
"license": "BSD-2-Clause", "license": "BSD-2-Clause",
"dependencies": { "dependencies": {
"jsesc": "~3.0.2" "jsesc": "~3.1.0"
}, },
"bin": { "bin": {
"regjsparser": "bin/parser" "regjsparser": "bin/parser"
} }
}, },
"node_modules/regjsparser/node_modules/jsesc": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz",
"integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==",
"dev": true,
"license": "MIT",
"bin": {
"jsesc": "bin/jsesc"
},
"engines": {
"node": ">=6"
}
},
"node_modules/relateurl": { "node_modules/relateurl": {
"version": "0.2.7", "version": "0.2.7",
"resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",
@@ -10148,20 +10100,39 @@
} }
}, },
"node_modules/ripemd160": { "node_modules/ripemd160": {
"version": "2.0.2", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.3.tgz",
"integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", "integrity": "sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"hash-base": "^3.0.0", "hash-base": "^3.1.2",
"inherits": "^2.0.1" "inherits": "^2.0.4"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/ripemd160/node_modules/hash-base": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.2.tgz",
"integrity": "sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==",
"dev": true,
"license": "MIT",
"dependencies": {
"inherits": "^2.0.4",
"readable-stream": "^2.3.8",
"safe-buffer": "^5.2.1",
"to-buffer": "^1.2.1"
},
"engines": {
"node": ">= 0.8"
} }
}, },
"node_modules/rollup": { "node_modules/rollup": {
"version": "4.52.0", "version": "4.52.2",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.0.tgz", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.2.tgz",
"integrity": "sha512-+IuescNkTJQgX7AkIDtITipZdIGcWF0pnVvZTWStiazUmcGA2ag8dfg0urest2XlXUi9kuhfQ+qmdc5Stc3z7g==", "integrity": "sha512-I25/2QgoROE1vYV+NQ1En9T9UFB9Cmfm2CJ83zZOlaDpvz29wGQSZXWKw7MiNXau7wYgB/T9fVIdIuEQ+KbiiA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@@ -10175,28 +10146,28 @@
"npm": ">=8.0.0" "npm": ">=8.0.0"
}, },
"optionalDependencies": { "optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.52.0", "@rollup/rollup-android-arm-eabi": "4.52.2",
"@rollup/rollup-android-arm64": "4.52.0", "@rollup/rollup-android-arm64": "4.52.2",
"@rollup/rollup-darwin-arm64": "4.52.0", "@rollup/rollup-darwin-arm64": "4.52.2",
"@rollup/rollup-darwin-x64": "4.52.0", "@rollup/rollup-darwin-x64": "4.52.2",
"@rollup/rollup-freebsd-arm64": "4.52.0", "@rollup/rollup-freebsd-arm64": "4.52.2",
"@rollup/rollup-freebsd-x64": "4.52.0", "@rollup/rollup-freebsd-x64": "4.52.2",
"@rollup/rollup-linux-arm-gnueabihf": "4.52.0", "@rollup/rollup-linux-arm-gnueabihf": "4.52.2",
"@rollup/rollup-linux-arm-musleabihf": "4.52.0", "@rollup/rollup-linux-arm-musleabihf": "4.52.2",
"@rollup/rollup-linux-arm64-gnu": "4.52.0", "@rollup/rollup-linux-arm64-gnu": "4.52.2",
"@rollup/rollup-linux-arm64-musl": "4.52.0", "@rollup/rollup-linux-arm64-musl": "4.52.2",
"@rollup/rollup-linux-loong64-gnu": "4.52.0", "@rollup/rollup-linux-loong64-gnu": "4.52.2",
"@rollup/rollup-linux-ppc64-gnu": "4.52.0", "@rollup/rollup-linux-ppc64-gnu": "4.52.2",
"@rollup/rollup-linux-riscv64-gnu": "4.52.0", "@rollup/rollup-linux-riscv64-gnu": "4.52.2",
"@rollup/rollup-linux-riscv64-musl": "4.52.0", "@rollup/rollup-linux-riscv64-musl": "4.52.2",
"@rollup/rollup-linux-s390x-gnu": "4.52.0", "@rollup/rollup-linux-s390x-gnu": "4.52.2",
"@rollup/rollup-linux-x64-gnu": "4.52.0", "@rollup/rollup-linux-x64-gnu": "4.52.2",
"@rollup/rollup-linux-x64-musl": "4.52.0", "@rollup/rollup-linux-x64-musl": "4.52.2",
"@rollup/rollup-openharmony-arm64": "4.52.0", "@rollup/rollup-openharmony-arm64": "4.52.2",
"@rollup/rollup-win32-arm64-msvc": "4.52.0", "@rollup/rollup-win32-arm64-msvc": "4.52.2",
"@rollup/rollup-win32-ia32-msvc": "4.52.0", "@rollup/rollup-win32-ia32-msvc": "4.52.2",
"@rollup/rollup-win32-x64-gnu": "4.52.0", "@rollup/rollup-win32-x64-gnu": "4.52.2",
"@rollup/rollup-win32-x64-msvc": "4.52.0", "@rollup/rollup-win32-x64-msvc": "4.52.2",
"fsevents": "~2.3.2" "fsevents": "~2.3.2"
} }
}, },
@@ -10252,9 +10223,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/sass": { "node_modules/sass": {
"version": "1.93.0", "version": "1.93.2",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.93.0.tgz", "resolved": "https://registry.npmjs.org/sass/-/sass-1.93.2.tgz",
"integrity": "sha512-CQi5/AzCwiubU3dSqRDJ93RfOfg/hhpW1l6wCIvolmehfwgCI35R/0QDs1+R+Ygrl8jFawwwIojE2w47/mf94A==", "integrity": "sha512-t+YPtOQHpGW1QWsh1CHQ5cPIr9lbbGZLZnbihP/D/qZj/yuV68m8qarcV17nvkOX81BCrvzAlq2klCQFZghyTg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@@ -11263,9 +11234,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/to-buffer": { "node_modules/to-buffer": {
"version": "1.2.1", "version": "1.2.2",
"resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.1.tgz", "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz",
"integrity": "sha512-tB82LpAIWjhLYbqjx3X4zEeHN6M8CiuOEy2JY8SEQVdYRe3CCHOFaqrBW1doLDrfpWhplcW7BL+bO3/6S3pcDQ==", "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@@ -11569,9 +11540,9 @@
} }
}, },
"node_modules/vite": { "node_modules/vite": {
"version": "7.1.6", "version": "7.1.7",
"resolved": "https://registry.npmjs.org/vite/-/vite-7.1.6.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.7.tgz",
"integrity": "sha512-SRYIB8t/isTwNn8vMB3MR6E+EQZM/WG1aKmmIUCfDXfVvKfc20ZpamngWHKzAmmu9ppsgxsg4b2I7c90JZudIQ==", "integrity": "sha512-VbA8ScMvAISJNJVbRDTJdCwqQoAareR/wutevKanhR2/1EkoXVZVkkORaYm/tNVCjP/UDTKtcw3bAkwOUdedmA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {

View File

@@ -54,12 +54,21 @@ export default () => ({
if (data.hasOwnProperty(i)) { if (data.hasOwnProperty(i)) {
let current = data[i]; let current = data[i];
let code = current.currency_code; let code = current.currency_code;
if (!series.hasOwnProperty(code)) {
series[code] = { // create two series, "spent" and "earned".
name: code, for(const type of ['spent', 'earned']) {
yAxisID: '', let typeCode = code + '_' + type;
data: {}, if (!series.hasOwnProperty(typeCode)) {
}; series[typeCode] = {
name: typeCode,
code: code,
type: type,
yAxisID: '',
data: {},
};
}
}
if (!currencies.includes(code)) {
currencies.push(code); currencies.push(code);
} }
} }
@@ -76,31 +85,38 @@ export default () => ({
code = current.primary_currency_code; code = current.primary_currency_code;
} }
// loop series, add 0 if not present or add actual amount. // twice again, for speny AND earned.
for (const ii in series) { for(const type of ['spent', 'earned']) {
if (series.hasOwnProperty(ii)) { let typeCode = code + '_' + type;
let amount = 0.0; // loop series, add 0 if not present or add actual amount.
if (code === ii) { for (const ii in series) {
// this series' currency matches this column's currency. if (series.hasOwnProperty(typeCode)) {
amount = parseFloat(current.entries.spent); let amount = 0.0;
if(this.convertToPrimary) { if (typeCode === ii) {
amount = parseFloat(current.entries.pc_entries.spent); // this series' currency matches this column's currency.
amount = parseFloat(current.entries[type]);
if(this.convertToPrimary) {
amount = parseFloat(current.entries.pc_entries[type]);
}
yAxis = 'y' + typeCode;
}
if (series[typeCode].data.hasOwnProperty(current.label)) {
// there is a value for this particular currency. The amount from this column will be added.
// (even if this column isn't recorded in this currency and a new filler value is written)
// this is so currency conversion works.
series[typeCode].data[current.label] = series[typeCode].data[current.label] + amount;
} }
yAxis = 'y' + code;
}
if (series[ii].data.hasOwnProperty(current.label)) {
// there is a value for this particular currency. The amount from this column will be added.
// (even if this column isn't recorded in this currency and a new filler value is written)
// this is so currency conversion works.
series[ii].data[current.label] = series[ii].data[current.label] + amount;
}
if (!series[ii].data.hasOwnProperty(current.label)) { if (!series[typeCode].data.hasOwnProperty(current.label)) {
// this column's amount is not yet set in this series. // this column's amount is not yet set in this series.
series[ii].data[current.label] = amount; series[typeCode].data[current.label] = amount;
}
} }
} }
} }
// add label to x-axis, not unimportant. // add label to x-axis, not unimportant.
if (!options.data.labels.includes(current.label)) { if (!options.data.labels.includes(current.label)) {
options.data.labels.push(current.label); options.data.labels.push(current.label);
@@ -111,9 +127,10 @@ export default () => ({
let count = 0; let count = 0;
for (const i in series) { for (const i in series) {
let yAxisID = 'y' + i; let yAxisID = 'y' + i;
let currencyCode = i.replace('_spent', '').replace('_earned', '');
let dataset = { let dataset = {
label: i, label: i,
currency_code: i, currency_code: currencyCode,
yAxisID: yAxisID, yAxisID: yAxisID,
data: [], data: [],
// backgroundColor: getColors(null, 'background'), // backgroundColor: getColors(null, 'background'),

View File

@@ -268,7 +268,7 @@
</td> </td>
{% if config('firefly.feature_flags.running_balance_column') %} {% if config('firefly.feature_flags.running_balance_column') %}
<td> <td>
{% if null == transaction.balance_dirty or false == transaction.balance_dirty and null != transaction.destination_balance_after %} {% if (null == transaction.balance_dirty or false == transaction.balance_dirty) and null != transaction.destination_balance_after and null != transaction.source_balance_after %}
{% if transaction.transaction_type_type == 'Deposit' %} {% if transaction.transaction_type_type == 'Deposit' %}
{{ formatAmountBySymbol(transaction.destination_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }} {{ formatAmountBySymbol(transaction.destination_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}
{% elseif transaction.transaction_type_type == 'Withdrawal' %} {% elseif transaction.transaction_type_type == 'Withdrawal' %}