mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-10-29 06:34:37 +00:00
Compare commits
21 Commits
develop-20
...
develop-20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
667cbb1332 | ||
|
|
d1bae875f7 | ||
|
|
c5cf529413 | ||
|
|
62b9f2785f | ||
|
|
3b85f87502 | ||
|
|
87d3d14504 | ||
|
|
5637573fd0 | ||
|
|
48255ae6ee | ||
|
|
ea02986170 | ||
|
|
f4fbc15ac6 | ||
|
|
a02c4b42a4 | ||
|
|
1ff47441ce | ||
|
|
2cc8568077 | ||
|
|
408687ec6b | ||
|
|
308abffb0b | ||
|
|
6743b3fe83 | ||
|
|
ac0113e445 | ||
|
|
0f0a28c3d9 | ||
|
|
79f2d70211 | ||
|
|
8a06c0f7ec | ||
|
|
c54da62005 |
49
.ci/php-cs-fixer/composer.lock
generated
49
.ci/php-cs-fixer/composer.lock
generated
@@ -402,16 +402,16 @@
|
||||
},
|
||||
{
|
||||
"name": "friendsofphp/php-cs-fixer",
|
||||
"version": "v3.88.0",
|
||||
"version": "v3.88.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
|
||||
"reference": "f23469674ae50d40e398bfff8018911a2a2b0dbe"
|
||||
"reference": "a8d15584bafb0f0d9d938827840060fd4a3ebc99"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/f23469674ae50d40e398bfff8018911a2a2b0dbe",
|
||||
"reference": "f23469674ae50d40e398bfff8018911a2a2b0dbe",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/a8d15584bafb0f0d9d938827840060fd4a3ebc99",
|
||||
"reference": "a8d15584bafb0f0d9d938827840060fd4a3ebc99",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -494,7 +494,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
|
||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.88.0"
|
||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.88.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -502,7 +502,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-09-24T21:31:42+00:00"
|
||||
"time": "2025-09-27T00:24:15+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/container",
|
||||
@@ -1252,16 +1252,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v7.3.3",
|
||||
"version": "v7.3.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "cb0102a1c5ac3807cf3fdf8bea96007df7fdbea7"
|
||||
"reference": "2b9c5fafbac0399a20a2e82429e2bd735dcfb7db"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/cb0102a1c5ac3807cf3fdf8bea96007df7fdbea7",
|
||||
"reference": "cb0102a1c5ac3807cf3fdf8bea96007df7fdbea7",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/2b9c5fafbac0399a20a2e82429e2bd735dcfb7db",
|
||||
"reference": "2b9c5fafbac0399a20a2e82429e2bd735dcfb7db",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1326,7 +1326,7 @@
|
||||
"terminal"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/console/tree/v7.3.3"
|
||||
"source": "https://github.com/symfony/console/tree/v7.3.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1346,7 +1346,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-08-25T06:35:40+00:00"
|
||||
"time": "2025-09-22T15:31:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/deprecation-contracts",
|
||||
@@ -2365,16 +2365,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v7.3.3",
|
||||
"version": "v7.3.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/process.git",
|
||||
"reference": "32241012d521e2e8a9d713adb0812bb773b907f1"
|
||||
"reference": "f24f8f316367b30810810d4eb30c543d7003ff3b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/32241012d521e2e8a9d713adb0812bb773b907f1",
|
||||
"reference": "32241012d521e2e8a9d713adb0812bb773b907f1",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/f24f8f316367b30810810d4eb30c543d7003ff3b",
|
||||
"reference": "f24f8f316367b30810810d4eb30c543d7003ff3b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2406,7 +2406,7 @@
|
||||
"description": "Executes commands in sub-processes",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/process/tree/v7.3.3"
|
||||
"source": "https://github.com/symfony/process/tree/v7.3.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -2426,7 +2426,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-08-18T09:42:54+00:00"
|
||||
"time": "2025-09-11T10:12:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/service-contracts",
|
||||
@@ -2575,16 +2575,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/string",
|
||||
"version": "v7.3.3",
|
||||
"version": "v7.3.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/string.git",
|
||||
"reference": "17a426cce5fd1f0901fefa9b2a490d0038fd3c9c"
|
||||
"reference": "f96476035142921000338bad71e5247fbc138872"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/17a426cce5fd1f0901fefa9b2a490d0038fd3c9c",
|
||||
"reference": "17a426cce5fd1f0901fefa9b2a490d0038fd3c9c",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/f96476035142921000338bad71e5247fbc138872",
|
||||
"reference": "f96476035142921000338bad71e5247fbc138872",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2599,7 +2599,6 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/emoji": "^7.1",
|
||||
"symfony/error-handler": "^6.4|^7.0",
|
||||
"symfony/http-client": "^6.4|^7.0",
|
||||
"symfony/intl": "^6.4|^7.0",
|
||||
"symfony/translation-contracts": "^2.5|^3.0",
|
||||
@@ -2642,7 +2641,7 @@
|
||||
"utf8"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/string/tree/v7.3.3"
|
||||
"source": "https://github.com/symfony/string/tree/v7.3.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -2662,7 +2661,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-08-25T06:35:40+00:00"
|
||||
"time": "2025-09-11T14:36:48+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
|
||||
@@ -28,8 +28,10 @@ use FireflyIII\Api\V1\Controllers\Controller;
|
||||
use FireflyIII\Api\V1\Requests\Autocomplete\AutocompleteRequest;
|
||||
use FireflyIII\Enums\UserRoleEnum;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use FireflyIII\Support\Facades\Amount;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
@@ -96,6 +98,7 @@ class PiggyBankController extends Controller
|
||||
|
||||
/** @var PiggyBank $piggy */
|
||||
foreach ($piggies as $piggy) {
|
||||
/** @var TransactionCurrency $currency */
|
||||
$currency = $piggy->transactionCurrency;
|
||||
$currentAmount = $this->piggyRepository->getCurrentAmount($piggy);
|
||||
$objectGroup = $piggy->objectGroups()->first();
|
||||
@@ -105,8 +108,8 @@ class PiggyBankController extends Controller
|
||||
'name_with_balance' => sprintf(
|
||||
'%s (%s / %s)',
|
||||
$piggy->name,
|
||||
app('amount')->formatAnything($currency, $currentAmount, false),
|
||||
app('amount')->formatAnything($currency, $piggy->target_amount, false),
|
||||
Amount::formatAnything($currency, $currentAmount, false),
|
||||
Amount::formatAnything($currency, $piggy->target_amount, false),
|
||||
),
|
||||
'currency_id' => (string) $currency->id,
|
||||
'currency_name' => $currency->name,
|
||||
|
||||
@@ -72,7 +72,7 @@ class DestroyController extends Controller
|
||||
public function destroySingleByDate(TransactionCurrency $from, TransactionCurrency $to, Carbon $date): JsonResponse
|
||||
{
|
||||
$exchangeRate = $this->repository->getSpecificRateOnDate($from, $to, $date);
|
||||
if (null !== $exchangeRate) {
|
||||
if ($exchangeRate instanceof CurrencyExchangeRate) {
|
||||
$this->repository->deleteRate($exchangeRate);
|
||||
}
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ class ShowController extends Controller
|
||||
$transformer->setParameters($this->parameters);
|
||||
|
||||
$exchangeRate = $this->repository->getSpecificRateOnDate($from, $to, $date);
|
||||
if (null === $exchangeRate) {
|
||||
if (!$exchangeRate instanceof CurrencyExchangeRate) {
|
||||
throw new NotFoundHttpException();
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ class UpdateController extends Controller
|
||||
public function updateByDate(UpdateRequest $request, TransactionCurrency $from, TransactionCurrency $to, Carbon $date): JsonResponse
|
||||
{
|
||||
$exchangeRate = $this->repository->getSpecificRateOnDate($from, $to, $date);
|
||||
if (null === $exchangeRate) {
|
||||
if (!$exchangeRate instanceof CurrencyExchangeRate) {
|
||||
throw new NotFoundHttpException();
|
||||
}
|
||||
$date = $request->getDate();
|
||||
|
||||
@@ -68,10 +68,6 @@ class UpdateController extends Controller
|
||||
$data = $request->getAll();
|
||||
$piggyBank = $this->repository->update($piggyBank, $data);
|
||||
|
||||
if (array_key_exists('current_amount', $data) && '' !== $data['current_amount']) {
|
||||
$this->repository->setCurrentAmount($piggyBank, $data['current_amount']);
|
||||
}
|
||||
|
||||
// enrich
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
||||
@@ -64,7 +64,7 @@ class UpdateRequest extends FormRequest
|
||||
*/
|
||||
public function getAll(): array
|
||||
{
|
||||
app('log')->debug(sprintf('Now in %s', __METHOD__));
|
||||
Log::debug(sprintf('Now in %s', __METHOD__));
|
||||
$this->integerFields = ['order', 'currency_id', 'foreign_currency_id', 'transaction_journal_id', 'source_id', 'destination_id', 'budget_id', 'category_id', 'bill_id', 'recurrence_id'];
|
||||
$this->dateFields = ['date', 'interest_date', 'book_date', 'process_date', 'due_date', 'payment_date', 'invoice_date'];
|
||||
$this->textareaFields = ['notes'];
|
||||
@@ -97,7 +97,7 @@ class UpdateRequest extends FormRequest
|
||||
*/
|
||||
private function getTransactionData(): array
|
||||
{
|
||||
app('log')->debug(sprintf('Now in %s', __METHOD__));
|
||||
Log::debug(sprintf('Now in %s', __METHOD__));
|
||||
$return = [];
|
||||
|
||||
/** @var null|array $transactions */
|
||||
@@ -181,7 +181,7 @@ class UpdateRequest extends FormRequest
|
||||
private function getDateData(array $current, array $transaction): array
|
||||
{
|
||||
foreach ($this->dateFields as $fieldName) {
|
||||
app('log')->debug(sprintf('Now at date field %s', $fieldName));
|
||||
Log::debug(sprintf('Now at date field %s', $fieldName));
|
||||
if (array_key_exists($fieldName, $transaction)) {
|
||||
Log::debug(sprintf('New value: "%s"', $transaction[$fieldName]));
|
||||
$current[$fieldName] = $this->dateFromValue((string) $transaction[$fieldName]);
|
||||
@@ -247,7 +247,7 @@ class UpdateRequest extends FormRequest
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
app('log')->debug(sprintf('Now in %s', __METHOD__));
|
||||
Log::debug(sprintf('Now in %s', __METHOD__));
|
||||
$validProtocols = config('firefly.valid_url_protocols');
|
||||
|
||||
return [
|
||||
@@ -330,7 +330,7 @@ class UpdateRequest extends FormRequest
|
||||
*/
|
||||
public function withValidator(Validator $validator): void
|
||||
{
|
||||
app('log')->debug('Now in withValidator');
|
||||
Log::debug('Now in withValidator');
|
||||
|
||||
/** @var TransactionGroup $transactionGroup */
|
||||
$transactionGroup = $this->route()->parameter('transactionGroup');
|
||||
|
||||
@@ -28,7 +28,6 @@ namespace FireflyIII\Casts;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Class SeparateTimezoneCaster
|
||||
|
||||
@@ -26,12 +26,14 @@ namespace FireflyIII\Console\Commands\System;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Support\System\GeneratesInstallationId;
|
||||
use FireflyIII\Support\System\IsOldVersion;
|
||||
use Illuminate\Console\Command;
|
||||
use Random\RandomException;
|
||||
|
||||
class OutputsInstructions extends Command
|
||||
{
|
||||
use GeneratesInstallationId;
|
||||
use IsOldVersion;
|
||||
|
||||
protected $description = 'Instructions in case of upgrade trouble.';
|
||||
|
||||
@@ -58,7 +60,7 @@ class OutputsInstructions extends Command
|
||||
*/
|
||||
private function updateInstructions(): void
|
||||
{
|
||||
$version = (string) config('firefly.version');
|
||||
$version = (string)config('firefly.version');
|
||||
|
||||
/** @var array $config */
|
||||
$config = config('upgrade.text.upgrade');
|
||||
@@ -68,12 +70,12 @@ class OutputsInstructions extends Command
|
||||
foreach (array_keys($config) as $compare) {
|
||||
// if string starts with:
|
||||
if (str_starts_with($version, $compare)) {
|
||||
$text = (string) $config[$compare];
|
||||
$text = (string)$config[$compare];
|
||||
}
|
||||
}
|
||||
|
||||
// validate some settings.
|
||||
if ('' === $text && 'local' === (string) config('app.env')) {
|
||||
if ('' === $text && 'local' === (string)config('app.env')) {
|
||||
$text = 'Please set APP_ENV=production for a safer environment.';
|
||||
}
|
||||
|
||||
@@ -191,7 +193,7 @@ class OutputsInstructions extends Command
|
||||
*/
|
||||
private function installInstructions(): void
|
||||
{
|
||||
$version = (string) config('firefly.version');
|
||||
$version = (string)config('firefly.version');
|
||||
|
||||
/** @var array $config */
|
||||
$config = config('upgrade.text.install');
|
||||
@@ -201,12 +203,12 @@ class OutputsInstructions extends Command
|
||||
foreach (array_keys($config) as $compare) {
|
||||
// if string starts with:
|
||||
if (str_starts_with($version, $compare)) {
|
||||
$text = (string) $config[$compare];
|
||||
$text = (string)$config[$compare];
|
||||
}
|
||||
}
|
||||
|
||||
// validate some settings.
|
||||
if ('' === $text && 'local' === (string) config('app.env')) {
|
||||
if ('' === $text && 'local' === (string)config('app.env')) {
|
||||
$text = 'Please set APP_ENV=production for a safer environment.';
|
||||
}
|
||||
|
||||
@@ -242,14 +244,15 @@ class OutputsInstructions extends Command
|
||||
|
||||
private function someQuote(): void
|
||||
{
|
||||
$lines = [
|
||||
'Forgive yourself for not being at peace.',
|
||||
'Doesn\'t look like anything to me.',
|
||||
'Be proud of what you make.',
|
||||
'Be there or forever wonder.',
|
||||
'A year from now you will wish you had started today.',
|
||||
$lines = [
|
||||
'"Forgive yourself for not being at peace."',
|
||||
'"Doesn\'t look like anything to me."',
|
||||
'"Be proud of what you make."',
|
||||
'"Be there or forever wonder."',
|
||||
'"A year from now you will wish you had started today."',
|
||||
'🇺🇦 Слава Україні!',
|
||||
'🇺🇦 Slava Ukraini!',
|
||||
];
|
||||
$addQuotes = true;
|
||||
|
||||
// fuck the Russian aggression in Ukraine.
|
||||
|
||||
@@ -260,8 +263,7 @@ class OutputsInstructions extends Command
|
||||
// going on, to allow that to happen.
|
||||
|
||||
if ('ru_RU' === config('firefly.default_language')) {
|
||||
$addQuotes = false;
|
||||
$lines = [
|
||||
$lines = [
|
||||
'🇺🇦 Слава Україні!',
|
||||
'🇺🇦 Slava Ukraini!',
|
||||
];
|
||||
@@ -272,11 +274,6 @@ class OutputsInstructions extends Command
|
||||
} catch (RandomException) {
|
||||
$random = 0;
|
||||
}
|
||||
if ($addQuotes) {
|
||||
$this->line(sprintf(' "%s"', $lines[$random]));
|
||||
|
||||
return;
|
||||
}
|
||||
$this->line(sprintf(' %s', $lines[$random]));
|
||||
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Console\Commands\System;
|
||||
|
||||
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
|
||||
use FireflyIII\Support\Facades\FireflyConfig;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class SetsLatestVersion extends Command
|
||||
@@ -45,8 +46,7 @@ class SetsLatestVersion extends Command
|
||||
|
||||
return 0;
|
||||
}
|
||||
app('fireflyconfig')->set('db_version', config('firefly.db_version'));
|
||||
app('fireflyconfig')->set('ff3_version', config('firefly.version'));
|
||||
FireflyConfig::set('ff3_version', config('firefly.version'));
|
||||
$this->friendlyInfo('Updated version.');
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -283,7 +283,7 @@ class ApplyRules extends Command
|
||||
if (null !== $endString && '' !== $endString) {
|
||||
$inputEnd = Carbon::createFromFormat('Y-m-d', $endString);
|
||||
}
|
||||
if (null === $inputEnd || null === $inputStart) {
|
||||
if (!$inputEnd instanceof Carbon || null === $inputStart) {
|
||||
Log::error('Could not parse start or end date in verifyInputDate().');
|
||||
|
||||
return;
|
||||
|
||||
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Console\Commands\Upgrade;
|
||||
|
||||
use FireflyIII\Support\Facades\FireflyConfig;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Safe\Exceptions\InfoException;
|
||||
|
||||
@@ -86,10 +87,8 @@ class UpgradesDatabase extends Command
|
||||
$this->friendlyLine(sprintf('Now executing %s', $command));
|
||||
$this->call($command, $args);
|
||||
}
|
||||
// set new DB version.
|
||||
app('fireflyconfig')->set('db_version', (int) config('firefly.db_version'));
|
||||
// index will set FF3 version.
|
||||
app('fireflyconfig')->set('ff3_version', (string) config('firefly.version'));
|
||||
FireflyConfig::set('ff3_version', (string) config('firefly.version'));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -242,6 +242,7 @@ class PiggyBankFactory
|
||||
}
|
||||
}
|
||||
}
|
||||
Log::debug('Looping all accounts.');
|
||||
|
||||
/** @var array $info */
|
||||
foreach ($accounts as $info) {
|
||||
@@ -251,6 +252,7 @@ class PiggyBankFactory
|
||||
|
||||
continue;
|
||||
}
|
||||
Log::debug(sprintf('Working on account #%d', $account->id));
|
||||
if (array_key_exists('current_amount', $info) && null !== $info['current_amount']) {
|
||||
// an amount is set, first check out if there is a difference with the previous amount.
|
||||
$previous = $toBeLinked[$account->id]['current_amount'] ?? '0';
|
||||
@@ -258,22 +260,24 @@ class PiggyBankFactory
|
||||
|
||||
// create event for difference.
|
||||
if (0 !== bccomp($diff, '0')) {
|
||||
// 2025-10-01 for issue #10990 disable this event.
|
||||
Log::debug(sprintf('[a] Will save event for difference %s (previous value was %s)', $diff, $previous));
|
||||
event(new ChangedAmount($piggyBank, $diff, null, null));
|
||||
// event(new ChangedAmount($piggyBank, $diff, null, null));
|
||||
}
|
||||
|
||||
$toBeLinked[$account->id] = ['current_amount' => $info['current_amount']];
|
||||
Log::debug(sprintf('[a] Will link account #%d with amount %s', $account->id, $info['current_amount']));
|
||||
}
|
||||
if (array_key_exists('current_amount', $info) && null === $info['current_amount']) {
|
||||
// an amount is set, first check out if there is a difference with the previous amount.
|
||||
// no amount is set, first check out if there is a difference with the previous amount.
|
||||
$previous = $toBeLinked[$account->id]['current_amount'] ?? '0';
|
||||
$diff = bcsub('0', $previous);
|
||||
|
||||
// create event for difference.
|
||||
if (0 !== bccomp($diff, '0')) {
|
||||
// 2025-10-01 for issue #10990 disable this event.
|
||||
Log::debug(sprintf('[b] Will save event for difference %s (previous value was %s)', $diff, $previous));
|
||||
event(new ChangedAmount($piggyBank, $diff, null, null));
|
||||
// event(new ChangedAmount($piggyBank, $diff, null, null));
|
||||
}
|
||||
|
||||
// no amount set, use previous amount or go to ZERO.
|
||||
@@ -282,7 +286,8 @@ class PiggyBankFactory
|
||||
|
||||
// create event:
|
||||
Log::debug('linkToAccountIds: Trigger change for positive amount [b].');
|
||||
event(new ChangedAmount($piggyBank, $toBeLinked[$account->id]['current_amount'] ?? '0', null, null));
|
||||
// 2025-10-01 for issue #10990 disable this event.
|
||||
// event(new ChangedAmount($piggyBank, $toBeLinked[$account->id]['current_amount'] ?? '0', null, null));
|
||||
}
|
||||
if (!array_key_exists('current_amount', $info)) {
|
||||
$toBeLinked[$account->id] ??= [];
|
||||
|
||||
@@ -109,6 +109,12 @@ class StoredGroupEventHandler
|
||||
$dest = $journal->transactions()->where('amount', '>', '0')->first();
|
||||
$repository->deleteStatisticsForModel($source->account, $journal->date);
|
||||
$repository->deleteStatisticsForModel($dest->account, $journal->date);
|
||||
foreach ($journal->categories as $category) {
|
||||
$repository->deleteStatisticsForModel($category, $journal->date);
|
||||
}
|
||||
foreach ($journal->tags as $tag) {
|
||||
$repository->deleteStatisticsForModel($tag, $journal->date);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +58,9 @@ class UpdatedGroupEventHandler
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO duplicate
|
||||
*/
|
||||
private function removePeriodStatistics(UpdatedTransactionGroup $event): void
|
||||
{
|
||||
/** @var PeriodStatisticRepositoryInterface $repository */
|
||||
@@ -69,6 +72,12 @@ class UpdatedGroupEventHandler
|
||||
$dest = $journal->transactions()->where('amount', '>', '0')->first();
|
||||
$repository->deleteStatisticsForModel($source->account, $journal->date);
|
||||
$repository->deleteStatisticsForModel($dest->account, $journal->date);
|
||||
foreach ($journal->categories as $category) {
|
||||
$repository->deleteStatisticsForModel($category, $journal->date);
|
||||
}
|
||||
foreach ($journal->tags as $tag) {
|
||||
$repository->deleteStatisticsForModel($tag, $journal->date);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -62,5 +62,8 @@ class WebhookEventHandler
|
||||
Log::debug(sprintf('Skip message #%d', $message->id));
|
||||
}
|
||||
}
|
||||
|
||||
// clean up sent messages table:
|
||||
WebhookMessage::where('webhook_messages.sent', true)->where('webhook_messages.created_at', '<', now()->subDays(30))->delete();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -184,7 +184,6 @@ class DebugController extends Controller
|
||||
$currentDriver = DB::getDriverName();
|
||||
|
||||
return [
|
||||
'db_version' => app('fireflyconfig')->get('db_version', 1)->data,
|
||||
'php_version' => PHP_VERSION,
|
||||
'php_os' => PHP_OS,
|
||||
'uname' => php_uname('m'),
|
||||
|
||||
@@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Controllers\System;
|
||||
|
||||
use FireflyIII\Support\Facades\FireflyConfig;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Exception;
|
||||
@@ -81,10 +82,7 @@ class InstallController extends Controller
|
||||
{
|
||||
app('view')->share('FF_VERSION', config('firefly.version'));
|
||||
// index will set FF3 version.
|
||||
app('fireflyconfig')->set('ff3_version', (string) config('firefly.version'));
|
||||
|
||||
// set new DB version.
|
||||
app('fireflyconfig')->set('db_version', (int) config('firefly.db_version'));
|
||||
FireflyConfig::set('ff3_version', (string) config('firefly.version'));
|
||||
|
||||
return view('install.index');
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface;
|
||||
use FireflyIII\Services\Internal\Update\GroupCloneService;
|
||||
use FireflyIII\Support\Facades\Preferences;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
@@ -76,7 +77,7 @@ class CreateController extends Controller
|
||||
// event!
|
||||
event(new StoredTransactionGroup($newGroup, true, true));
|
||||
|
||||
app('preferences')->mark();
|
||||
Preferences::mark();
|
||||
|
||||
$title = $newGroup->title ?? $newGroup->transactionJournals->first()->description;
|
||||
$link = route('transactions.show', [$newGroup->id]);
|
||||
@@ -103,7 +104,7 @@ class CreateController extends Controller
|
||||
* */
|
||||
public function create(?string $objectType)
|
||||
{
|
||||
app('preferences')->mark();
|
||||
Preferences::mark();
|
||||
|
||||
$sourceId = (int) request()->get('source');
|
||||
$destinationId = (int) request()->get('destination');
|
||||
@@ -114,7 +115,9 @@ class CreateController extends Controller
|
||||
$preFilled = session()->has('preFilled') ? session('preFilled') : [];
|
||||
$subTitle = (string) trans(sprintf('breadcrumbs.create_%s', strtolower((string) $objectType)));
|
||||
$subTitleIcon = 'fa-plus';
|
||||
$optionalFields = app('preferences')->get('transaction_journal_optional_fields', [])->data;
|
||||
|
||||
/** @var null|array $optionalFields */
|
||||
$optionalFields = Preferences::get('transaction_journal_optional_fields', [])->data;
|
||||
$allowedOpposingTypes = config('firefly.allowed_opposing_types');
|
||||
$accountToTypes = config('firefly.account_to_transaction');
|
||||
$previousUrl = $this->rememberPreviousUrl('transactions.create.url');
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace FireflyIII\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Support\System\IsOldVersion;
|
||||
use FireflyIII\Support\System\OAuthKeys;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -37,6 +38,8 @@ use Illuminate\Support\Facades\Log;
|
||||
*/
|
||||
class Installer
|
||||
{
|
||||
use IsOldVersion;
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
@@ -65,7 +68,7 @@ class Installer
|
||||
// run installer when no tables are present,
|
||||
// or when old scheme version
|
||||
// or when old firefly version
|
||||
if ($this->hasNoTables() || $this->oldDBVersion() || $this->oldVersion()) {
|
||||
if ($this->hasNoTables() || $this->isOldVersionInstalled()) {
|
||||
return response()->redirectTo(route('installer.index'));
|
||||
}
|
||||
OAuthKeys::verifyKeysRoutine();
|
||||
@@ -126,59 +129,4 @@ class Installer
|
||||
{
|
||||
return false !== stripos($message, 'Base table or view not found');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the "db_version" variable is correct.
|
||||
*/
|
||||
private function oldDBVersion(): bool
|
||||
{
|
||||
// older version in config than database?
|
||||
$configVersion = (int) config('firefly.db_version');
|
||||
$dbVersion = (int) app('fireflyconfig')->getFresh('db_version', 1)->data;
|
||||
if ($configVersion > $dbVersion) {
|
||||
Log::warning(
|
||||
sprintf(
|
||||
'The current configured version (%d) is older than the required version (%d). Redirect to migrate routine.',
|
||||
$dbVersion,
|
||||
$configVersion
|
||||
)
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Log::info(sprintf('Configured DB version (%d) equals expected DB version (%d)', $dbVersion, $configVersion));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the "firefly_version" variable is correct.
|
||||
*/
|
||||
private function oldVersion(): bool
|
||||
{
|
||||
// version compare thing.
|
||||
$configVersion = (string) config('firefly.version');
|
||||
$dbVersion = (string) app('fireflyconfig')->getFresh('ff3_version', '1.0')->data;
|
||||
if (str_starts_with($configVersion, 'develop')) {
|
||||
Log::debug('Skipping version check for develop version.');
|
||||
|
||||
return false;
|
||||
}
|
||||
if (1 === version_compare($configVersion, $dbVersion)) {
|
||||
Log::warning(
|
||||
sprintf(
|
||||
'The current configured Firefly III version (%s) is older than the required version (%s). Redirect to migrate routine.',
|
||||
$dbVersion,
|
||||
$configVersion
|
||||
)
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Log::info(sprintf('Installed Firefly III version (%s) equals expected Firefly III version (%s)', $dbVersion, $configVersion));
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,4 +109,9 @@ class Category extends Model
|
||||
'user_group_id' => 'integer',
|
||||
];
|
||||
}
|
||||
|
||||
public function primaryPeriodStatistics(): MorphMany
|
||||
{
|
||||
return $this->morphMany(PeriodStatistic::class, 'primary_statable');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -104,4 +104,9 @@ class Tag extends Model
|
||||
'user_group_id' => 'integer',
|
||||
];
|
||||
}
|
||||
|
||||
public function primaryPeriodStatistics(): MorphMany
|
||||
{
|
||||
return $this->morphMany(PeriodStatistic::class, 'primary_statable');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -358,4 +358,43 @@ class CategoryRepository implements CategoryRepositoryInterface, UserGroupInterf
|
||||
|
||||
return $service->update($category, $data);
|
||||
}
|
||||
|
||||
public function periodCollection(Category $category, Carbon $start, Carbon $end): array
|
||||
{
|
||||
Log::debug(sprintf('periodCollection(#%d, %s, %s)', $category->id, $start->format('Y-m-d'), $end->format('Y-m-d')));
|
||||
|
||||
return $category->transactionJournals()
|
||||
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
|
||||
->leftJoin('transaction_currencies', 'transaction_currencies.id', '=', 'transactions.transaction_currency_id')
|
||||
->leftJoin('transaction_currencies as foreign_currencies', 'foreign_currencies.id', '=', 'transactions.foreign_currency_id')
|
||||
->where('transaction_journals.date', '>=', $start)
|
||||
->where('transaction_journals.date', '<=', $end)
|
||||
->where('transactions.amount', '>', 0)
|
||||
->get([
|
||||
// currencies
|
||||
'transaction_currencies.id as currency_id',
|
||||
'transaction_currencies.code as currency_code',
|
||||
'transaction_currencies.name as currency_name',
|
||||
'transaction_currencies.symbol as currency_symbol',
|
||||
'transaction_currencies.decimal_places as currency_decimal_places',
|
||||
|
||||
// foreign
|
||||
'foreign_currencies.id as foreign_currency_id',
|
||||
'foreign_currencies.code as foreign_currency_code',
|
||||
'foreign_currencies.name as foreign_currency_name',
|
||||
'foreign_currencies.symbol as foreign_currency_symbol',
|
||||
'foreign_currencies.decimal_places as foreign_currency_decimal_places',
|
||||
|
||||
// fields
|
||||
'transaction_journals.date',
|
||||
'transaction_types.type',
|
||||
'transaction_journals.transaction_currency_id',
|
||||
'transactions.amount',
|
||||
'transactions.native_amount as pc_amount',
|
||||
'transactions.foreign_amount',
|
||||
])
|
||||
->toArray()
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,8 @@ interface CategoryRepositoryInterface
|
||||
|
||||
public function categoryStartsWith(string $query, int $limit): Collection;
|
||||
|
||||
public function periodCollection(Category $category, Carbon $start, Carbon $end): array;
|
||||
|
||||
public function destroy(Category $category): bool;
|
||||
|
||||
/**
|
||||
|
||||
@@ -510,9 +510,7 @@ class OperationsRepository implements OperationsRepositoryInterface, UserGroupIn
|
||||
$summarizer->setConvertToPrimary($convertToPrimary);
|
||||
|
||||
// filter $journals by range AND currency if it is present.
|
||||
$expenses = array_filter($expenses, static function (array $expense) use ($category): bool {
|
||||
return $expense['category_id'] === $category->id;
|
||||
});
|
||||
$expenses = array_filter($expenses, static fn (array $expense): bool => $expense['category_id'] === $category->id);
|
||||
|
||||
return $summarizer->groupByCurrencyId($expenses, $method, false);
|
||||
}
|
||||
|
||||
@@ -25,12 +25,17 @@ 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;
|
||||
use Override;
|
||||
|
||||
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()
|
||||
@@ -56,6 +61,7 @@ class PeriodStatisticRepository implements PeriodStatisticRepositoryInterface
|
||||
$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;
|
||||
@@ -68,7 +74,7 @@ class PeriodStatisticRepository implements PeriodStatisticRepositoryInterface
|
||||
Log::debug(sprintf(
|
||||
'Saved #%d [currency #%d, Model %s #%d, %s to %s, %d, %s] as new statistic.',
|
||||
$stat->id,
|
||||
get_class($model),
|
||||
$model::class,
|
||||
$model->id,
|
||||
$stat->transaction_currency_id,
|
||||
$stat->start->toW3cString(),
|
||||
@@ -89,4 +95,42 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,11 @@ interface PeriodStatisticRepositoryInterface
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Repositories\ObjectGroup\CreatesObjectGroups;
|
||||
use FireflyIII\Support\Facades\Amount;
|
||||
use FireflyIII\Support\Facades\Steam;
|
||||
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
@@ -67,7 +68,7 @@ trait ModifiesPiggyBanks
|
||||
{
|
||||
$currentAmount = $this->getCurrentAmount($piggyBank, $account);
|
||||
$pivot = $piggyBank->accounts()->where('accounts.id', $account->id)->first()->pivot;
|
||||
$pivot->current_amount = bcsub($currentAmount, $amount);
|
||||
$pivot->current_amount = bcsub((string) $currentAmount, $amount);
|
||||
$pivot->native_current_amount = null;
|
||||
|
||||
// also update native_current_amount.
|
||||
@@ -90,7 +91,7 @@ trait ModifiesPiggyBanks
|
||||
{
|
||||
$currentAmount = $this->getCurrentAmount($piggyBank, $account);
|
||||
$pivot = $piggyBank->accounts()->where('accounts.id', $account->id)->first()->pivot;
|
||||
$pivot->current_amount = bcadd($currentAmount, $amount);
|
||||
$pivot->current_amount = bcadd((string) $currentAmount, $amount);
|
||||
$pivot->native_current_amount = null;
|
||||
|
||||
// also update native_current_amount.
|
||||
@@ -122,13 +123,13 @@ trait ModifiesPiggyBanks
|
||||
|
||||
|
||||
if (0 !== bccomp($piggyBank->target_amount, '0')) {
|
||||
$leftToSave = bcsub($piggyBank->target_amount, $savedSoFar);
|
||||
$maxAmount = 1 === bccomp($leftOnAccount, $leftToSave) ? $leftToSave : $leftOnAccount;
|
||||
$leftToSave = bcsub($piggyBank->target_amount, (string) $savedSoFar);
|
||||
$maxAmount = 1 === bccomp((string) $leftOnAccount, $leftToSave) ? $leftToSave : $leftOnAccount;
|
||||
Log::debug(sprintf('Left to save: %s', $leftToSave));
|
||||
Log::debug(sprintf('Maximum amount: %s', $maxAmount));
|
||||
}
|
||||
|
||||
$compare = bccomp($amount, $maxAmount);
|
||||
$compare = bccomp($amount, (string) $maxAmount);
|
||||
$result = $compare <= 0;
|
||||
|
||||
Log::debug(sprintf('Compare <= 0? %d, so canAddAmount is %s', $compare, var_export($result, true)));
|
||||
@@ -140,7 +141,7 @@ trait ModifiesPiggyBanks
|
||||
{
|
||||
$savedSoFar = $this->getCurrentAmount($piggyBank, $account);
|
||||
|
||||
return bccomp($amount, $savedSoFar) <= 0;
|
||||
return bccomp($amount, (string) $savedSoFar) <= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -227,16 +228,15 @@ trait ModifiesPiggyBanks
|
||||
$factory->user = $this->user;
|
||||
|
||||
// the piggy bank currency is set or updated FIRST, if it exists.
|
||||
|
||||
$factory->linkToAccountIds($piggyBank, $data['accounts'] ?? []);
|
||||
|
||||
|
||||
// if the piggy bank is now smaller than the sum of the money saved,
|
||||
// remove money from all accounts until the piggy bank is the right amount.
|
||||
$currentAmount = $this->getCurrentAmount($piggyBank);
|
||||
if (1 === bccomp($currentAmount, (string)$piggyBank->target_amount) && 0 !== bccomp((string)$piggyBank->target_amount, '0')) {
|
||||
if (1 === bccomp((string) $currentAmount, (string)$piggyBank->target_amount) && 0 !== bccomp((string)$piggyBank->target_amount, '0')) {
|
||||
Log::debug(sprintf('Current amount is %s, target amount is %s', $currentAmount, $piggyBank->target_amount));
|
||||
$difference = bcsub((string)$piggyBank->target_amount, $currentAmount);
|
||||
$difference = bcsub((string)$piggyBank->target_amount, (string) $currentAmount);
|
||||
|
||||
// an amount will be removed, create "negative" event:
|
||||
// Log::debug(sprintf('ChangedAmount: is triggered with difference "%s"', $difference));
|
||||
@@ -244,7 +244,7 @@ trait ModifiesPiggyBanks
|
||||
|
||||
// question is, from which account(s) to remove the difference?
|
||||
// solution: just start from the top until there is no more money left to remove.
|
||||
$this->removeAmountFromAll($piggyBank, app('steam')->positive($difference));
|
||||
$this->removeAmountFromAll($piggyBank, Steam::positive($difference));
|
||||
}
|
||||
|
||||
// update using name:
|
||||
|
||||
@@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Repositories\Tag;
|
||||
|
||||
use Override;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Enums\TransactionTypeEnum;
|
||||
use FireflyIII\Factory\TagFactory;
|
||||
@@ -379,4 +380,44 @@ class TagRepository implements TagRepositoryInterface, UserGroupInterface
|
||||
/** @var null|Location */
|
||||
return $tag->locations()->first();
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function periodCollection(Tag $tag, Carbon $start, Carbon $end): array
|
||||
{
|
||||
Log::debug(sprintf('periodCollection(#%d, %s, %s)', $tag->id, $start->format('Y-m-d'), $end->format('Y-m-d')));
|
||||
|
||||
return $tag->transactionJournals()
|
||||
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
|
||||
->leftJoin('transaction_currencies', 'transaction_currencies.id', '=', 'transactions.transaction_currency_id')
|
||||
->leftJoin('transaction_currencies as foreign_currencies', 'foreign_currencies.id', '=', 'transactions.foreign_currency_id')
|
||||
->where('transaction_journals.date', '>=', $start)
|
||||
->where('transaction_journals.date', '<=', $end)
|
||||
->where('transactions.amount', '>', 0)
|
||||
->get([
|
||||
// currencies
|
||||
'transaction_currencies.id as currency_id',
|
||||
'transaction_currencies.code as currency_code',
|
||||
'transaction_currencies.name as currency_name',
|
||||
'transaction_currencies.symbol as currency_symbol',
|
||||
'transaction_currencies.decimal_places as currency_decimal_places',
|
||||
|
||||
// foreign
|
||||
'foreign_currencies.id as foreign_currency_id',
|
||||
'foreign_currencies.code as foreign_currency_code',
|
||||
'foreign_currencies.name as foreign_currency_name',
|
||||
'foreign_currencies.symbol as foreign_currency_symbol',
|
||||
'foreign_currencies.decimal_places as foreign_currency_decimal_places',
|
||||
|
||||
// fields
|
||||
'transaction_journals.date',
|
||||
'transaction_types.type',
|
||||
'transaction_journals.transaction_currency_id',
|
||||
'transactions.amount',
|
||||
'transactions.native_amount as pc_amount',
|
||||
'transactions.foreign_amount',
|
||||
])
|
||||
->toArray()
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,8 @@ interface TagRepositoryInterface
|
||||
*/
|
||||
public function destroy(Tag $tag): bool;
|
||||
|
||||
public function periodCollection(Tag $tag, Carbon $start, Carbon $end): array;
|
||||
|
||||
/**
|
||||
* Destroy all tags.
|
||||
*/
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace FireflyIII\Services\FireflyIIIOrg\Update;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Events\NewVersionAvailable;
|
||||
use FireflyIII\Support\System\IsOldVersion;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
@@ -38,6 +39,8 @@ use function Safe\json_decode;
|
||||
*/
|
||||
class UpdateRequest implements UpdateRequestInterface
|
||||
{
|
||||
use IsOldVersion;
|
||||
|
||||
public function getUpdateInformation(string $channel): array
|
||||
{
|
||||
Log::debug(sprintf('Now in getUpdateInformation(%s)', $channel));
|
||||
@@ -183,20 +186,15 @@ class UpdateRequest implements UpdateRequestInterface
|
||||
private function parseResultDevelop(string $current, string $latest, array $information): array
|
||||
{
|
||||
Log::debug(sprintf('User is running develop version "%s"', $current));
|
||||
$parts = explode('/', $current);
|
||||
$compare = $this->compareDevelopVersions($current, $latest);
|
||||
$return = [];
|
||||
|
||||
/** @var Carbon $devDate */
|
||||
$devDate = Carbon::createFromFormat('Y-m-d', $parts[1]);
|
||||
|
||||
if ($devDate->lte($information['date'])) {
|
||||
Log::debug(sprintf('This development release is older, release = %s, latest version %s = %s', $devDate->format('Y-m-d'), $latest, $information['date']->format('Y-m-d')));
|
||||
if (-1 === $compare) {
|
||||
$return['level'] = 'info';
|
||||
$return['message'] = (string) trans('firefly.update_current_dev_older', ['version' => $current, 'new_version' => $latest]);
|
||||
|
||||
return $return;
|
||||
}
|
||||
Log::debug(sprintf('This development release is newer, release = %s, latest version %s = %s', $devDate->format('Y-m-d'), $latest, $information['date']->format('Y-m-d')));
|
||||
$return['level'] = 'info';
|
||||
$return['message'] = (string) trans('firefly.update_current_dev_newer', ['version' => $current, 'new_version' => $latest]);
|
||||
|
||||
|
||||
@@ -276,66 +276,66 @@ class CreditRecalculateService
|
||||
if ($isSameAccount && $isCredit && $this->isWithdrawalIn($usedAmount, $type)) { // case 1
|
||||
$usedAmount = app('steam')->positive($usedAmount);
|
||||
|
||||
return bcadd($leftOfDebt, $usedAmount);
|
||||
return bcadd($leftOfDebt, (string) $usedAmount);
|
||||
// Log::debug(sprintf('Case 1 (withdrawal into credit liability): %s + %s = %s', app('steam')->bcround($leftOfDebt, 2), app('steam')->bcround($usedAmount, 2), app('steam')->bcround($result, 2)));
|
||||
}
|
||||
|
||||
if ($isSameAccount && $isCredit && $this->isWithdrawalOut($usedAmount, $type)) { // case 2
|
||||
$usedAmount = app('steam')->positive($usedAmount);
|
||||
|
||||
return bcsub($leftOfDebt, $usedAmount);
|
||||
return bcsub($leftOfDebt, (string) $usedAmount);
|
||||
// Log::debug(sprintf('Case 2 (withdrawal away from liability): %s - %s = %s', app('steam')->bcround($leftOfDebt, 2), app('steam')->bcround($usedAmount, 2), app('steam')->bcround($result, 2)));
|
||||
}
|
||||
|
||||
if ($isSameAccount && $isCredit && $this->isDepositOut($usedAmount, $type)) { // case 3
|
||||
$usedAmount = app('steam')->positive($usedAmount);
|
||||
|
||||
return bcsub($leftOfDebt, $usedAmount);
|
||||
return bcsub($leftOfDebt, (string) $usedAmount);
|
||||
// Log::debug(sprintf('Case 3 (deposit away from liability): %s - %s = %s', app('steam')->bcround($leftOfDebt, 2), app('steam')->bcround($usedAmount, 2), app('steam')->bcround($result, 2)));
|
||||
}
|
||||
|
||||
if ($isSameAccount && $isCredit && $this->isDepositIn($usedAmount, $type)) { // case 4
|
||||
$usedAmount = app('steam')->positive($usedAmount);
|
||||
|
||||
return bcadd($leftOfDebt, $usedAmount);
|
||||
return bcadd($leftOfDebt, (string) $usedAmount);
|
||||
// Log::debug(sprintf('Case 4 (deposit into credit liability): %s + %s = %s', app('steam')->bcround($leftOfDebt, 2), app('steam')->bcround($usedAmount, 2), app('steam')->bcround($result, 2)));
|
||||
}
|
||||
if ($isSameAccount && $isCredit && $this->isTransferIn($usedAmount, $type)) { // case 5
|
||||
$usedAmount = app('steam')->positive($usedAmount);
|
||||
|
||||
return bcadd($leftOfDebt, $usedAmount);
|
||||
return bcadd($leftOfDebt, (string) $usedAmount);
|
||||
// Log::debug(sprintf('Case 5 (transfer into credit liability): %s + %s = %s', app('steam')->bcround($leftOfDebt, 2), app('steam')->bcround($usedAmount, 2), app('steam')->bcround($result, 2)));
|
||||
}
|
||||
if ($isSameAccount && $isDebit && $this->isWithdrawalIn($usedAmount, $type)) { // case 6
|
||||
$usedAmount = app('steam')->positive($usedAmount);
|
||||
|
||||
return bcsub($leftOfDebt, $usedAmount);
|
||||
return bcsub($leftOfDebt, (string) $usedAmount);
|
||||
// Log::debug(sprintf('Case 6 (withdrawal into debit liability): %s - %s = %s', app('steam')->bcround($leftOfDebt, 2), app('steam')->bcround($usedAmount, 2), app('steam')->bcround($result, 2)));
|
||||
}
|
||||
if ($isSameAccount && $isDebit && $this->isDepositOut($usedAmount, $type)) { // case 7
|
||||
$usedAmount = app('steam')->positive($usedAmount);
|
||||
|
||||
return bcadd($leftOfDebt, $usedAmount);
|
||||
return bcadd($leftOfDebt, (string) $usedAmount);
|
||||
// Log::debug(sprintf('Case 7 (deposit away from liability): %s + %s = %s', app('steam')->bcround($leftOfDebt, 2), app('steam')->bcround($usedAmount, 2), app('steam')->bcround($result, 2)));
|
||||
}
|
||||
if ($isSameAccount && $isDebit && $this->isWithdrawalOut($usedAmount, $type)) { // case 8
|
||||
$usedAmount = app('steam')->positive($usedAmount);
|
||||
|
||||
return bcadd($leftOfDebt, $usedAmount);
|
||||
return bcadd($leftOfDebt, (string) $usedAmount);
|
||||
// Log::debug(sprintf('Case 8 (withdrawal away from liability): %s + %s = %s', app('steam')->bcround($leftOfDebt, 2), app('steam')->bcround($usedAmount, 2), app('steam')->bcround($result, 2)));
|
||||
}
|
||||
|
||||
if ($isSameAccount && $isDebit && $this->isTransferIn($usedAmount, $type)) { // case 9
|
||||
$usedAmount = app('steam')->positive($usedAmount);
|
||||
|
||||
return bcsub($leftOfDebt, $usedAmount);
|
||||
return bcsub($leftOfDebt, (string) $usedAmount);
|
||||
// 2024-10-05, #9225 this used to say you would owe more, but a transfer INTO a debit from wherever means you owe LESS.
|
||||
// Log::debug(sprintf('Case 9 (transfer into debit liability, means you owe LESS): %s - %s = %s', app('steam')->bcround($leftOfDebt, 2), app('steam')->bcround($usedAmount, 2), app('steam')->bcround($result, 2)));
|
||||
}
|
||||
if ($isSameAccount && $isDebit && $this->isTransferOut($usedAmount, $type)) { // case 10
|
||||
$usedAmount = app('steam')->positive($usedAmount);
|
||||
|
||||
return bcadd($leftOfDebt, $usedAmount);
|
||||
return bcadd($leftOfDebt, (string) $usedAmount);
|
||||
// 2024-10-05, #9225 this used to say you would owe less, but a transfer OUT OF a debit from wherever means you owe MORE.
|
||||
// Log::debug(sprintf('Case 10 (transfer out of debit liability, means you owe MORE): %s + %s = %s', app('steam')->bcround($leftOfDebt, 2), app('steam')->bcround($usedAmount, 2), app('steam')->bcround($result, 2)));
|
||||
}
|
||||
@@ -344,7 +344,7 @@ class CreditRecalculateService
|
||||
if (in_array($type, [TransactionTypeEnum::WITHDRAWAL->value, TransactionTypeEnum::DEPOSIT->value, TransactionTypeEnum::TRANSFER->value], true)) {
|
||||
$usedAmount = app('steam')->negative($usedAmount);
|
||||
|
||||
return bcadd($leftOfDebt, $usedAmount);
|
||||
return bcadd($leftOfDebt, (string) $usedAmount);
|
||||
// Log::debug(sprintf('Case X (all other cases): %s + %s = %s', app('steam')->bcround($leftOfDebt, 2), app('steam')->bcround($usedAmount, 2), app('steam')->bcround($result, 2)));
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ class Timer
|
||||
|
||||
public static function getInstance(): self
|
||||
{
|
||||
if (null === self::$instance) {
|
||||
if (!self::$instance instanceof self) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
|
||||
@@ -33,13 +33,18 @@ use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\PeriodStatistic;
|
||||
use FireflyIII\Models\Tag;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||
use FireflyIII\Repositories\PeriodStatistic\PeriodStatisticRepositoryInterface;
|
||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use FireflyIII\Support\Facades\Amount;
|
||||
use FireflyIII\Support\Facades\Navigation;
|
||||
use FireflyIII\Support\Facades\Steam;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* Trait PeriodOverview.
|
||||
@@ -71,6 +76,8 @@ use Illuminate\Support\Facades\Log;
|
||||
trait PeriodOverview
|
||||
{
|
||||
protected AccountRepositoryInterface $accountRepository;
|
||||
protected CategoryRepositoryInterface $categoryRepository;
|
||||
protected TagRepositoryInterface $tagRepository;
|
||||
protected JournalRepositoryInterface $journalRepos;
|
||||
protected PeriodStatisticRepositoryInterface $periodStatisticRepo;
|
||||
private Collection $statistics; // temp data holder
|
||||
@@ -87,6 +94,7 @@ trait PeriodOverview
|
||||
{
|
||||
Log::debug(sprintf('Now in getAccountPeriodOverview(#%d, %s %s)', $account->id, $start->format('Y-m-d H:i:s.u'), $end->format('Y-m-d H:i:s.u')));
|
||||
$this->accountRepository = app(AccountRepositoryInterface::class);
|
||||
$this->accountRepository->setUser($account->user);
|
||||
$this->periodStatisticRepo = app(PeriodStatisticRepositoryInterface::class);
|
||||
$range = Navigation::getViewRange(true);
|
||||
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
|
||||
@@ -96,16 +104,10 @@ trait PeriodOverview
|
||||
[$start, $end] = $this->getPeriodFromBlocks($dates, $start, $end);
|
||||
$this->statistics = $this->periodStatisticRepo->allInRangeForModel($account, $start, $end);
|
||||
|
||||
// TODO needs to be re-arranged:
|
||||
// get all period stats for entire range.
|
||||
// loop blocks, an loop the types, and select the missing ones.
|
||||
// create new ones, or use collected.
|
||||
|
||||
|
||||
$entries = [];
|
||||
Log::debug(sprintf('Count of loops: %d', count($dates)));
|
||||
foreach ($dates as $currentDate) {
|
||||
$entries[] = $this->getSingleAccountPeriod($account, $currentDate['period'], $currentDate['start'], $currentDate['end']);
|
||||
$entries[] = $this->getSingleModelPeriod($account, $currentDate['period'], $currentDate['start'], $currentDate['end']);
|
||||
}
|
||||
Log::debug('End of getAccountPeriodOverview()');
|
||||
|
||||
@@ -138,68 +140,24 @@ trait PeriodOverview
|
||||
*/
|
||||
protected function getCategoryPeriodOverview(Category $category, Carbon $start, Carbon $end): array
|
||||
{
|
||||
$range = Navigation::getViewRange(true);
|
||||
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
|
||||
$this->categoryRepository = app(CategoryRepositoryInterface::class);
|
||||
$this->categoryRepository->setUser($category->user);
|
||||
$this->periodStatisticRepo = app(PeriodStatisticRepositoryInterface::class);
|
||||
|
||||
// properties for entries with their amounts.
|
||||
$cache = new CacheProperties();
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty($range);
|
||||
$cache->addProperty('category-show-period-entries');
|
||||
$cache->addProperty($category->id);
|
||||
|
||||
if ($cache->has()) {
|
||||
return $cache->get();
|
||||
}
|
||||
$range = Navigation::getViewRange(true);
|
||||
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
|
||||
|
||||
/** @var array $dates */
|
||||
$dates = Navigation::blockPeriods($start, $end, $range);
|
||||
$entries = [];
|
||||
$dates = Navigation::blockPeriods($start, $end, $range);
|
||||
$entries = [];
|
||||
[$start, $end] = $this->getPeriodFromBlocks($dates, $start, $end);
|
||||
$this->statistics = $this->periodStatisticRepo->allInRangeForModel($category, $start, $end);
|
||||
|
||||
// collect all expenses in this period:
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setCategory($category);
|
||||
$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->setCategory($category);
|
||||
$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->setCategory($category);
|
||||
$collector->setRange($start, $end);
|
||||
$collector->setTypes([TransactionTypeEnum::TRANSFER->value]);
|
||||
$transferSet = $collector->getExtractedJournals();
|
||||
Log::debug(sprintf('Count of loops: %d', count($dates)));
|
||||
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[]
|
||||
= [
|
||||
'transactions' => 0,
|
||||
'title' => $title,
|
||||
'route' => route(
|
||||
'categories.show',
|
||||
[$category->id, $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),
|
||||
];
|
||||
$entries[] = $this->getSingleModelPeriod($category, $currentDate['period'], $currentDate['start'], $currentDate['end']);
|
||||
}
|
||||
$cache->store($entries);
|
||||
|
||||
return $entries;
|
||||
}
|
||||
@@ -211,131 +169,151 @@ 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);
|
||||
|
||||
[$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();
|
||||
}
|
||||
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];
|
||||
|
||||
/** @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')));
|
||||
|
||||
// properties for cache
|
||||
$dates = Navigation::blockPeriods($start, $end, $range);
|
||||
$entries = [];
|
||||
switch ($model) {
|
||||
default:
|
||||
throw new FireflyException(sprintf('Cannot deal with model of type "%s"', $model));
|
||||
|
||||
// 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();
|
||||
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 = [];
|
||||
|
||||
// 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();
|
||||
break;
|
||||
|
||||
// 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();
|
||||
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();
|
||||
|
||||
/** @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[]
|
||||
= [
|
||||
'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),
|
||||
];
|
||||
// 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 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(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 getSingleAccountPeriod(Account $account, string $period, Carbon $start, Carbon $end): array
|
||||
protected function getSingleModelPeriod(Model $model, string $period, 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')));
|
||||
Log::debug(sprintf('Now in getSingleModelPeriod(%s #%d, %s %s)', $model::class, $model->id, $start->format('Y-m-d'), $end->format('Y-m-d')));
|
||||
$types = ['spent', 'earned', 'transferred_in', 'transferred_away'];
|
||||
$return = [
|
||||
'title' => Navigation::periodShow($start, $period),
|
||||
'route' => route('accounts.show', [$account->id, $start->format('Y-m-d'), $end->format('Y-m-d')]),
|
||||
'route' => route(sprintf('%s.show', strtolower(Str::plural(class_basename($model)))), [$model->id, $start->format('Y-m-d'), $end->format('Y-m-d')]),
|
||||
'total_transactions' => 0,
|
||||
];
|
||||
$this->transactions = [];
|
||||
foreach ($types as $type) {
|
||||
$set = $this->getSingleAccountPeriodByType($account, $start, $end, $type);
|
||||
$set = $this->getSingleModelPeriodByType($model, $start, $end, $type);
|
||||
$return['total_transactions'] += $set['count'];
|
||||
unset($set['count']);
|
||||
$return[$type] = $set;
|
||||
@@ -344,44 +322,72 @@ trait PeriodOverview
|
||||
return $return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
protected function getSingleAccountPeriodByType(Account $account, Carbon $start, Carbon $end, string $type): array
|
||||
private function filterPrefixedStatistics(Carbon $start, Carbon $end, string $prefix): Collection
|
||||
{
|
||||
Log::debug(sprintf('Now in getSingleAccountPeriodByType(#%d, %s %s, %s)', $account->id, $start->format('Y-m-d'), $end->format('Y-m-d'), $type));
|
||||
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);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
// nothing found, regenerate them.
|
||||
if (0 === $statistics->count()) {
|
||||
Log::debug(sprintf('Found nothing in this period for type "%s"', $type));
|
||||
if (0 === count($this->transactions)) {
|
||||
$this->transactions = $this->accountRepository->periodCollection($account, $start, $end);
|
||||
switch ($model::class) {
|
||||
default:
|
||||
throw new FireflyException(sprintf('Cannot deal with model of type "%s"', $model::class));
|
||||
|
||||
case Category::class:
|
||||
$this->transactions = $this->categoryRepository->periodCollection($model, $start, $end);
|
||||
|
||||
break;
|
||||
|
||||
case Account::class:
|
||||
$this->transactions = $this->accountRepository->periodCollection($model, $start, $end);
|
||||
|
||||
break;
|
||||
|
||||
case Tag::class:
|
||||
$this->transactions = $this->tagRepository->periodCollection($model, $start, $end);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
default:
|
||||
throw new FireflyException(sprintf('Cannot deal with account period type %s', $type));
|
||||
throw new FireflyException(sprintf('Cannot deal with category period type %s', $type));
|
||||
|
||||
case 'spent':
|
||||
|
||||
$result = $this->filterTransactionsByType(TransactionTypeEnum::WITHDRAWAL, $start, $end);
|
||||
|
||||
break;
|
||||
@@ -405,7 +411,7 @@ trait PeriodOverview
|
||||
Log::debug(sprintf('Going to group %d found journal(s)', count($result)));
|
||||
$grouped = $this->groupByCurrency($result);
|
||||
|
||||
$this->saveGroupedAsStatistics($account, $start, $end, $type, $grouped);
|
||||
$this->saveGroupedAsStatistics($model, $start, $end, $type, $grouped);
|
||||
|
||||
return $grouped;
|
||||
}
|
||||
@@ -439,70 +445,23 @@ trait PeriodOverview
|
||||
*/
|
||||
protected function getTagPeriodOverview(Tag $tag, Carbon $start, Carbon $end): array // period overview for tags.
|
||||
{
|
||||
$range = Navigation::getViewRange(true);
|
||||
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
|
||||
$this->tagRepository = app(TagRepositoryInterface::class);
|
||||
$this->tagRepository->setUser($tag->user);
|
||||
$this->periodStatisticRepo = app(PeriodStatisticRepositoryInterface::class);
|
||||
|
||||
// properties for cache
|
||||
$cache = new CacheProperties();
|
||||
$cache->addProperty($start);
|
||||
$cache->addProperty($end);
|
||||
$cache->addProperty('tag-period-entries');
|
||||
$cache->addProperty($tag->id);
|
||||
if ($cache->has()) {
|
||||
return $cache->get();
|
||||
}
|
||||
$range = Navigation::getViewRange(true);
|
||||
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
|
||||
|
||||
/** @var array $dates */
|
||||
$dates = Navigation::blockPeriods($start, $end, $range);
|
||||
$entries = [];
|
||||
$dates = Navigation::blockPeriods($start, $end, $range);
|
||||
$entries = [];
|
||||
[$start, $end] = $this->getPeriodFromBlocks($dates, $start, $end);
|
||||
$this->statistics = $this->periodStatisticRepo->allInRangeForModel($tag, $start, $end);
|
||||
|
||||
// collect all expenses in this period:
|
||||
/** @var GroupCollectorInterface $collector */
|
||||
$collector = app(GroupCollectorInterface::class);
|
||||
$collector->setTag($tag);
|
||||
$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->setTag($tag);
|
||||
$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->setTag($tag);
|
||||
$collector->setRange($start, $end);
|
||||
$collector->setTypes([TransactionTypeEnum::TRANSFER->value]);
|
||||
$transferSet = $collector->getExtractedJournals();
|
||||
|
||||
// filer all of them:
|
||||
$earnedSet = $this->filterJournalsByTag($earnedSet, $tag);
|
||||
$spentSet = $this->filterJournalsByTag($spentSet, $tag);
|
||||
$transferSet = $this->filterJournalsByTag($transferSet, $tag);
|
||||
|
||||
Log::debug(sprintf('Count of loops: %d', count($dates)));
|
||||
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[]
|
||||
= [
|
||||
'transactions' => 0,
|
||||
'title' => $title,
|
||||
'route' => route(
|
||||
'tags.show',
|
||||
[$tag->id, $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),
|
||||
];
|
||||
$entries[] = $this->getSingleModelPeriod($tag, $currentDate['period'], $currentDate['start'], $currentDate['end']);
|
||||
}
|
||||
|
||||
return $entries;
|
||||
@@ -556,29 +515,42 @@ trait PeriodOverview
|
||||
}
|
||||
$entries[]
|
||||
= [
|
||||
'title' => $title,
|
||||
'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),
|
||||
'spent' => $this->groupByCurrency($spent),
|
||||
'earned' => $this->groupByCurrency($earned),
|
||||
'transferred' => $this->groupByCurrency($transferred),
|
||||
];
|
||||
'title' => $title,
|
||||
'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),
|
||||
'spent' => $this->groupByCurrency($spent),
|
||||
'earned' => $this->groupByCurrency($earned),
|
||||
'transferred' => $this->groupByCurrency($transferred),
|
||||
];
|
||||
++$loops;
|
||||
}
|
||||
|
||||
return $entries;
|
||||
}
|
||||
|
||||
protected function saveGroupedAsStatistics(Account $account, 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(#%d, %s, %s, "%s", array(%d))', $account->id, $start->format('Y-m-d'), $end->format('Y-m-d'), $type, count($array)));
|
||||
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)));
|
||||
foreach ($array as $entry) {
|
||||
$this->periodStatisticRepo->saveStatistic($account, $entry['currency_id'], $start, $end, $type, $entry['count'], $entry['amount']);
|
||||
$this->periodStatisticRepo->saveStatistic($model, $entry['currency_id'], $start, $end, $type, $entry['count'], $entry['amount']);
|
||||
}
|
||||
if (0 === count($array)) {
|
||||
Log::debug('Save empty statistic.');
|
||||
$this->periodStatisticRepo->saveStatistic($account, $this->primaryCurrency->id, $start, $end, $type, 0, '0');
|
||||
$this->periodStatisticRepo->saveStatistic($model, $this->primaryCurrency->id, $start, $end, $type, 0, '0');
|
||||
}
|
||||
}
|
||||
|
||||
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');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -599,27 +571,6 @@ trait PeriodOverview
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function filterJournalsByTag(array $set, Tag $tag): array
|
||||
{
|
||||
$return = [];
|
||||
foreach ($set as $entry) {
|
||||
$found = false;
|
||||
|
||||
/** @var array $localTag */
|
||||
foreach ($entry['tags'] as $localTag) {
|
||||
if ($localTag['id'] === $tag->id) {
|
||||
$found = true;
|
||||
}
|
||||
}
|
||||
if (false === $found) {
|
||||
continue;
|
||||
}
|
||||
$return[] = $entry;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
private function filterTransactionsByType(TransactionTypeEnum $type, Carbon $start, Carbon $end): array
|
||||
{
|
||||
$result = [];
|
||||
@@ -632,6 +583,11 @@ trait PeriodOverview
|
||||
$date = Carbon::parse($item['date']);
|
||||
$fits = $item['type'] === $type->value && $date >= $start && $date <= $end;
|
||||
if ($fits) {
|
||||
|
||||
// if type is withdrawal, negative amount:
|
||||
if (TransactionTypeEnum::WITHDRAWAL === $type && 1 === bccomp((string)$item['amount'], '0')) {
|
||||
$item['amount'] = Steam::negative($item['amount']);
|
||||
}
|
||||
$result[] = $item;
|
||||
}
|
||||
}
|
||||
@@ -639,40 +595,6 @@ trait PeriodOverview
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return only transactions where $account is the source.
|
||||
*/
|
||||
private function filterTransferredAway(Account $account, array $journals): array
|
||||
{
|
||||
$return = [];
|
||||
|
||||
/** @var array $journal */
|
||||
foreach ($journals as $journal) {
|
||||
if ($account->id === (int)$journal['source_account_id']) {
|
||||
$return[] = $journal;
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return only transactions where $account is the source.
|
||||
*/
|
||||
private function filterTransferredIn(Account $account, array $journals): array
|
||||
{
|
||||
$return = [];
|
||||
|
||||
/** @var array $journal */
|
||||
foreach ($journals as $journal) {
|
||||
if ($account->id === (int)$journal['destination_account_id']) {
|
||||
$return[] = $journal;
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
private function filterTransfers(string $direction, Carbon $start, Carbon $end): array
|
||||
{
|
||||
$result = [];
|
||||
@@ -704,17 +626,12 @@ trait PeriodOverview
|
||||
$return = [
|
||||
'count' => 0,
|
||||
];
|
||||
if (0 === count($journals)) {
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** @var array $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'];
|
||||
$currencyCode = $journal['currency_code'];
|
||||
$currencyName = $journal['currency_name'];
|
||||
@@ -750,7 +667,7 @@ trait PeriodOverview
|
||||
];
|
||||
|
||||
|
||||
$return[$currencyId]['amount'] = bcadd($return[$currencyId]['amount'], $amount);
|
||||
$return[$currencyId]['amount'] = bcadd((string)$return[$currencyId]['amount'], $amount);
|
||||
++$return[$currencyId]['count'];
|
||||
++$return['count'];
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ class CategoryEnrichment implements EnrichmentInterface
|
||||
|
||||
private function collectTransactions(): void
|
||||
{
|
||||
if (null !== $this->start && null !== $this->end) {
|
||||
if ($this->start instanceof Carbon && $this->end instanceof Carbon) {
|
||||
/** @var OperationsRepositoryInterface $opsRepository */
|
||||
$opsRepository = app(OperationsRepositoryInterface::class);
|
||||
$opsRepository->setUser($this->user);
|
||||
|
||||
@@ -142,9 +142,9 @@ class PiggyBankEnrichment implements EnrichmentInterface
|
||||
'current_amount' => Steam::bcround($row['current_amount'], $currency->decimal_places),
|
||||
'pc_current_amount' => Steam::bcround($row['pc_current_amount'], $this->primaryCurrency->decimal_places),
|
||||
];
|
||||
$meta['current_amount'] = bcadd($meta['current_amount'], $row['current_amount']);
|
||||
$meta['current_amount'] = bcadd($meta['current_amount'], (string) $row['current_amount']);
|
||||
// only add pc_current_amount when the pc_current_amount is set
|
||||
$meta['pc_current_amount'] = null === $row['pc_current_amount'] ? null : bcadd($meta['pc_current_amount'], $row['pc_current_amount']);
|
||||
$meta['pc_current_amount'] = null === $row['pc_current_amount'] ? null : bcadd((string) $meta['pc_current_amount'], (string) $row['pc_current_amount']);
|
||||
}
|
||||
$meta['current_amount'] = Steam::bcround($meta['current_amount'], $currency->decimal_places);
|
||||
// only round this number when pc_current_amount is set.
|
||||
@@ -152,8 +152,8 @@ class PiggyBankEnrichment implements EnrichmentInterface
|
||||
|
||||
// calculate left to save, only when there is a target amount.
|
||||
if (null !== $targetAmount) {
|
||||
$meta['left_to_save'] = bcsub($meta['target_amount'], $meta['current_amount']);
|
||||
$meta['pc_left_to_save'] = null === $meta['pc_target_amount'] ? null : bcsub($meta['pc_target_amount'], $meta['pc_current_amount']);
|
||||
$meta['left_to_save'] = bcsub((string) $meta['target_amount'], (string) $meta['current_amount']);
|
||||
$meta['pc_left_to_save'] = null === $meta['pc_target_amount'] ? null : bcsub((string) $meta['pc_target_amount'], (string) $meta['pc_current_amount']);
|
||||
}
|
||||
|
||||
// get suggested per month.
|
||||
@@ -199,7 +199,7 @@ class PiggyBankEnrichment implements EnrichmentInterface
|
||||
'pc_current_amount' => '0',
|
||||
];
|
||||
}
|
||||
$this->amounts[$id][$accountId]['current_amount'] = bcadd($this->amounts[$id][$accountId]['current_amount'], (string)$item->current_amount);
|
||||
$this->amounts[$id][$accountId]['current_amount'] = bcadd((string) $this->amounts[$id][$accountId]['current_amount'], (string)$item->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'], (string)$item->native_current_amount);
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ trait RecalculatesAvailableBudgetsTrait
|
||||
// if not exists:
|
||||
$currentPeriod = Period::make($current, $currentEnd, precision: Precision::DAY(), boundaries: Boundaries::EXCLUDE_NONE());
|
||||
$daily = $this->getDailyAmount($budgetLimit);
|
||||
$amount = bcmul($daily, (string)$currentPeriod->length(), 12);
|
||||
$amount = bcmul((string) $daily, (string)$currentPeriod->length(), 12);
|
||||
|
||||
// no need to calculate if period is equal.
|
||||
if ($currentPeriod->equals($limitPeriod)) {
|
||||
|
||||
@@ -193,7 +193,7 @@ class TransactionSummarizer
|
||||
];
|
||||
|
||||
// add the data from the $field to the array.
|
||||
$array[$key]['sum'] = bcadd($array[$key]['sum'], Steam::{$method}((string)($journal[$field] ?? '0'))); // @phpstan-ignore-line
|
||||
$array[$key]['sum'] = bcadd($array[$key]['sum'], (string) Steam::{$method}((string)($journal[$field] ?? '0'))); // @phpstan-ignore-line
|
||||
Log::debug(sprintf('Field for transaction #%d is "%s" (%s). Sum: %s', $journal['transaction_group_id'], $currencyCode, $field, $array[$key]['sum']));
|
||||
|
||||
// also do foreign amount, but only when convertToPrimary is false (otherwise we have it already)
|
||||
@@ -211,7 +211,7 @@ class TransactionSummarizer
|
||||
'currency_code' => $journal['foreign_currency_code'],
|
||||
'currency_decimal_places' => $journal['foreign_currency_decimal_places'],
|
||||
];
|
||||
$array[$key]['sum'] = bcadd($array[$key]['sum'], Steam::{$method}((string)$journal['foreign_amount'])); // @phpstan-ignore-line
|
||||
$array[$key]['sum'] = bcadd($array[$key]['sum'], (string) Steam::{$method}((string)$journal['foreign_amount'])); // @phpstan-ignore-line
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ class PreferencesSingleton
|
||||
|
||||
public static function getInstance(): self
|
||||
{
|
||||
if (null === self::$instance) {
|
||||
if (!self::$instance instanceof self) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
|
||||
@@ -756,7 +756,7 @@ class Steam
|
||||
$current = $converter->convert($currency, $primary, $date, $amount);
|
||||
Log::debug(sprintf('Convert %s %s to %s %s', $currency->code, $amount, $primary->code, $current));
|
||||
}
|
||||
$total = bcadd($current, $total);
|
||||
$total = bcadd((string) $current, $total);
|
||||
}
|
||||
|
||||
return $total;
|
||||
|
||||
99
app/Support/System/IsOldVersion.php
Normal file
99
app/Support/System/IsOldVersion.php
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/*
|
||||
* IsOldVersion.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\Support\System;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Support\Facades\FireflyConfig;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
trait IsOldVersion
|
||||
{
|
||||
/**
|
||||
* By default, version_compare() returns -1 if the first version is lower than the second, 0 if they are equal, and
|
||||
* 1 if the second is lower.
|
||||
*/
|
||||
protected function compareDevelopVersions(string $current, string $latest): int
|
||||
{
|
||||
$currentParts = explode('/', $current);
|
||||
$latestParts = explode('/', $latest);
|
||||
if (2 !== count($currentParts) || 2 !== count($latestParts)) {
|
||||
Log::error(sprintf('Version "%s" or "%s" is not a valid develop-version.', $current, $latest));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
$currentDate = Carbon::createFromFormat('!Y-m-d', $currentParts[1]);
|
||||
$latestDate = Carbon::createFromFormat('!Y-m-d', $latestParts[1]);
|
||||
|
||||
if ($currentDate->lt($latestDate)) {
|
||||
Log::debug(sprintf('This current version is older, current = %s, latest version %s.', $current, $latest));
|
||||
|
||||
return -1;
|
||||
}
|
||||
if ($currentDate->gt($latestDate)) {
|
||||
Log::debug(sprintf('This current version is newer, current = %s, latest version %s.', $current, $latest));
|
||||
|
||||
return 1;
|
||||
}
|
||||
Log::debug(sprintf('This current version is of the same age, current = %s, latest version %s.', $current, $latest));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the "firefly_version" variable is correct.
|
||||
*/
|
||||
protected function isOldVersionInstalled(): bool
|
||||
{
|
||||
// version compare thing.
|
||||
$configVersion = (string)config('firefly.version');
|
||||
$dbVersion = (string)FireflyConfig::getFresh('ff3_version', '1.0')->data;
|
||||
$compare = 0;
|
||||
// compare develop to develop
|
||||
if (str_starts_with($configVersion, 'develop') && str_starts_with($dbVersion, 'develop')) {
|
||||
$compare = $this->compareDevelopVersions($configVersion, $dbVersion);
|
||||
}
|
||||
// user has develop installed, goes to normal version.
|
||||
if (!str_starts_with($configVersion, 'develop') && str_starts_with($dbVersion, 'develop')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// user has normal, goes to develop version.
|
||||
if (str_starts_with($configVersion, 'develop') && !str_starts_with($dbVersion, 'develop')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// compare normal with normal.
|
||||
if (!str_starts_with($configVersion, 'develop') && !str_starts_with($dbVersion, 'develop')) {
|
||||
$compare = version_compare($configVersion, $dbVersion);
|
||||
}
|
||||
if (-1 === $compare) {
|
||||
Log::warning(sprintf('The current configured Firefly III version (%s) is older than the required version (%s). Redirect to migrate routine.', $dbVersion, $configVersion));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -35,7 +35,7 @@ use FireflyIII\Support\Facades\Steam;
|
||||
*/
|
||||
class PiggyBankEventTransformer extends AbstractTransformer
|
||||
{
|
||||
private TransactionCurrency $primaryCurrency;
|
||||
private readonly TransactionCurrency $primaryCurrency;
|
||||
private bool $convertToPrimary = false;
|
||||
|
||||
/**
|
||||
|
||||
17
changelog.md
17
changelog.md
@@ -5,16 +5,31 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## 6.4.1 - 2025-09-15
|
||||
|
||||
### Added
|
||||
|
||||
- #10979
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed a missing filter from [issue 10803](https://github.com/firefly-iii/firefly-iii/issues/10803).
|
||||
- #10833
|
||||
- #10854
|
||||
- #10891
|
||||
- #10916
|
||||
- #10920
|
||||
- #10921
|
||||
- #10833
|
||||
- #10924
|
||||
- #10938
|
||||
- #10940
|
||||
- #10954
|
||||
- #10956
|
||||
- #10960
|
||||
- #10974
|
||||
- #10990
|
||||
|
||||
### API
|
||||
|
||||
- #10803
|
||||
- #10908
|
||||
|
||||
|
||||
|
||||
275
composer.lock
generated
275
composer.lock
generated
@@ -1878,16 +1878,16 @@
|
||||
},
|
||||
{
|
||||
"name": "laravel/framework",
|
||||
"version": "v12.31.1",
|
||||
"version": "v12.32.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/framework.git",
|
||||
"reference": "281b711710c245dd8275d73132e92635be3094df"
|
||||
"reference": "77b2740391cd2a825ba59d6fada45e9b8b9bcc5a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/framework/zipball/281b711710c245dd8275d73132e92635be3094df",
|
||||
"reference": "281b711710c245dd8275d73132e92635be3094df",
|
||||
"url": "https://api.github.com/repos/laravel/framework/zipball/77b2740391cd2a825ba59d6fada45e9b8b9bcc5a",
|
||||
"reference": "77b2740391cd2a825ba59d6fada45e9b8b9bcc5a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1915,7 +1915,6 @@
|
||||
"monolog/monolog": "^3.0",
|
||||
"nesbot/carbon": "^3.8.4",
|
||||
"nunomaduro/termwind": "^2.0",
|
||||
"phiki/phiki": "^2.0.0",
|
||||
"php": "^8.2",
|
||||
"psr/container": "^1.1.1|^2.0.1",
|
||||
"psr/log": "^1.0|^2.0|^3.0",
|
||||
@@ -2094,7 +2093,7 @@
|
||||
"issues": "https://github.com/laravel/framework/issues",
|
||||
"source": "https://github.com/laravel/framework"
|
||||
},
|
||||
"time": "2025-09-23T15:33:04+00:00"
|
||||
"time": "2025-09-30T17:39:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/passport",
|
||||
@@ -2812,16 +2811,16 @@
|
||||
},
|
||||
{
|
||||
"name": "league/csv",
|
||||
"version": "9.25.0",
|
||||
"version": "9.26.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/csv.git",
|
||||
"reference": "f856f532866369fb1debe4e7c5a1db185f40ef86"
|
||||
"reference": "7fce732754d043f3938899e5183e2d0f3d31b571"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/csv/zipball/f856f532866369fb1debe4e7c5a1db185f40ef86",
|
||||
"reference": "f856f532866369fb1debe4e7c5a1db185f40ef86",
|
||||
"url": "https://api.github.com/repos/thephpleague/csv/zipball/7fce732754d043f3938899e5183e2d0f3d31b571",
|
||||
"reference": "7fce732754d043f3938899e5183e2d0f3d31b571",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2899,7 +2898,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-09-11T08:29:08+00:00"
|
||||
"time": "2025-10-01T11:24:54+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/event",
|
||||
@@ -4352,77 +4351,6 @@
|
||||
},
|
||||
"time": "2020-10-15T08:29:30+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phiki/phiki",
|
||||
"version": "v2.0.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phikiphp/phiki.git",
|
||||
"reference": "160785c50c01077780ab217e5808f00ab8f05a13"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phikiphp/phiki/zipball/160785c50c01077780ab217e5808f00ab8f05a13",
|
||||
"reference": "160785c50c01077780ab217e5808f00ab8f05a13",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"league/commonmark": "^2.5.3",
|
||||
"php": "^8.2",
|
||||
"psr/simple-cache": "^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"illuminate/support": "^11.45",
|
||||
"laravel/pint": "^1.18.1",
|
||||
"orchestra/testbench": "^9.15",
|
||||
"pestphp/pest": "^3.5.1",
|
||||
"phpstan/extension-installer": "^1.4.3",
|
||||
"phpstan/phpstan": "^2.0",
|
||||
"symfony/var-dumper": "^7.1.6"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Phiki\\Adapters\\Laravel\\PhikiServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Phiki\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ryan Chandler",
|
||||
"email": "support@ryangjchandler.co.uk",
|
||||
"homepage": "https://ryangjchandler.co.uk",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Syntax highlighting using TextMate grammars in PHP.",
|
||||
"support": {
|
||||
"issues": "https://github.com/phikiphp/phiki/issues",
|
||||
"source": "https://github.com/phikiphp/phiki/tree/v2.0.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/sponsors/ryangjchandler",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://buymeacoffee.com/ryangjchandler",
|
||||
"type": "other"
|
||||
}
|
||||
],
|
||||
"time": "2025-09-20T17:21:02+00:00"
|
||||
},
|
||||
{
|
||||
"name": "php-http/client-common",
|
||||
"version": "2.7.2",
|
||||
@@ -6488,16 +6416,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/cache",
|
||||
"version": "v7.3.2",
|
||||
"version": "v7.3.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/cache.git",
|
||||
"reference": "6621a2bee5373e3e972b2ae5dbedd5ac899d8cb6"
|
||||
"reference": "bf8afc8ffd4bfd3d9c373e417f041d9f1e5b863f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/cache/zipball/6621a2bee5373e3e972b2ae5dbedd5ac899d8cb6",
|
||||
"reference": "6621a2bee5373e3e972b2ae5dbedd5ac899d8cb6",
|
||||
"url": "https://api.github.com/repos/symfony/cache/zipball/bf8afc8ffd4bfd3d9c373e417f041d9f1e5b863f",
|
||||
"reference": "bf8afc8ffd4bfd3d9c373e417f041d9f1e5b863f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -6566,7 +6494,7 @@
|
||||
"psr6"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/cache/tree/v7.3.2"
|
||||
"source": "https://github.com/symfony/cache/tree/v7.3.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -6586,7 +6514,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-07-30T17:13:41+00:00"
|
||||
"time": "2025-09-11T10:12:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/cache-contracts",
|
||||
@@ -6740,16 +6668,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v7.3.3",
|
||||
"version": "v7.3.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "cb0102a1c5ac3807cf3fdf8bea96007df7fdbea7"
|
||||
"reference": "2b9c5fafbac0399a20a2e82429e2bd735dcfb7db"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/cb0102a1c5ac3807cf3fdf8bea96007df7fdbea7",
|
||||
"reference": "cb0102a1c5ac3807cf3fdf8bea96007df7fdbea7",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/2b9c5fafbac0399a20a2e82429e2bd735dcfb7db",
|
||||
"reference": "2b9c5fafbac0399a20a2e82429e2bd735dcfb7db",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -6814,7 +6742,7 @@
|
||||
"terminal"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/console/tree/v7.3.3"
|
||||
"source": "https://github.com/symfony/console/tree/v7.3.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -6834,7 +6762,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-08-25T06:35:40+00:00"
|
||||
"time": "2025-09-22T15:31:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/css-selector",
|
||||
@@ -6970,16 +6898,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/error-handler",
|
||||
"version": "v7.3.2",
|
||||
"version": "v7.3.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/error-handler.git",
|
||||
"reference": "0b31a944fcd8759ae294da4d2808cbc53aebd0c3"
|
||||
"reference": "99f81bc944ab8e5dae4f21b4ca9972698bbad0e4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/error-handler/zipball/0b31a944fcd8759ae294da4d2808cbc53aebd0c3",
|
||||
"reference": "0b31a944fcd8759ae294da4d2808cbc53aebd0c3",
|
||||
"url": "https://api.github.com/repos/symfony/error-handler/zipball/99f81bc944ab8e5dae4f21b4ca9972698bbad0e4",
|
||||
"reference": "99f81bc944ab8e5dae4f21b4ca9972698bbad0e4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -7027,7 +6955,7 @@
|
||||
"description": "Provides tools to manage errors and ease debugging PHP code",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/error-handler/tree/v7.3.2"
|
||||
"source": "https://github.com/symfony/error-handler/tree/v7.3.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -7047,7 +6975,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-07-07T08:17:57+00:00"
|
||||
"time": "2025-09-11T10:12:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
@@ -7347,16 +7275,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-client",
|
||||
"version": "v7.3.3",
|
||||
"version": "v7.3.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/http-client.git",
|
||||
"reference": "333b9bd7639cbdaecd25a3a48a9d2dcfaa86e019"
|
||||
"reference": "4b62871a01c49457cf2a8e560af7ee8a94b87a62"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/http-client/zipball/333b9bd7639cbdaecd25a3a48a9d2dcfaa86e019",
|
||||
"reference": "333b9bd7639cbdaecd25a3a48a9d2dcfaa86e019",
|
||||
"url": "https://api.github.com/repos/symfony/http-client/zipball/4b62871a01c49457cf2a8e560af7ee8a94b87a62",
|
||||
"reference": "4b62871a01c49457cf2a8e560af7ee8a94b87a62",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -7423,7 +7351,7 @@
|
||||
"http"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/http-client/tree/v7.3.3"
|
||||
"source": "https://github.com/symfony/http-client/tree/v7.3.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -7443,7 +7371,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-08-27T07:45:05+00:00"
|
||||
"time": "2025-09-11T10:12:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-client-contracts",
|
||||
@@ -7525,16 +7453,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-foundation",
|
||||
"version": "v7.3.3",
|
||||
"version": "v7.3.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/http-foundation.git",
|
||||
"reference": "7475561ec27020196c49bb7c4f178d33d7d3dc00"
|
||||
"reference": "c061c7c18918b1b64268771aad04b40be41dd2e6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/7475561ec27020196c49bb7c4f178d33d7d3dc00",
|
||||
"reference": "7475561ec27020196c49bb7c4f178d33d7d3dc00",
|
||||
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/c061c7c18918b1b64268771aad04b40be41dd2e6",
|
||||
"reference": "c061c7c18918b1b64268771aad04b40be41dd2e6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -7584,7 +7512,7 @@
|
||||
"description": "Defines an object-oriented layer for the HTTP specification",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/http-foundation/tree/v7.3.3"
|
||||
"source": "https://github.com/symfony/http-foundation/tree/v7.3.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -7604,20 +7532,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-08-20T08:04:18+00:00"
|
||||
"time": "2025-09-16T08:38:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-kernel",
|
||||
"version": "v7.3.3",
|
||||
"version": "v7.3.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/http-kernel.git",
|
||||
"reference": "72c304de37e1a1cec6d5d12b81187ebd4850a17b"
|
||||
"reference": "b796dffea7821f035047235e076b60ca2446e3cf"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/72c304de37e1a1cec6d5d12b81187ebd4850a17b",
|
||||
"reference": "72c304de37e1a1cec6d5d12b81187ebd4850a17b",
|
||||
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/b796dffea7821f035047235e076b60ca2446e3cf",
|
||||
"reference": "b796dffea7821f035047235e076b60ca2446e3cf",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -7702,7 +7630,7 @@
|
||||
"description": "Provides a structured process for converting a Request into a Response",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/http-kernel/tree/v7.3.3"
|
||||
"source": "https://github.com/symfony/http-kernel/tree/v7.3.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -7722,20 +7650,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-08-29T08:23:45+00:00"
|
||||
"time": "2025-09-27T12:32:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/mailer",
|
||||
"version": "v7.3.3",
|
||||
"version": "v7.3.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/mailer.git",
|
||||
"reference": "a32f3f45f1990db8c4341d5122a7d3a381c7e575"
|
||||
"reference": "ab97ef2f7acf0216955f5845484235113047a31d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/mailer/zipball/a32f3f45f1990db8c4341d5122a7d3a381c7e575",
|
||||
"reference": "a32f3f45f1990db8c4341d5122a7d3a381c7e575",
|
||||
"url": "https://api.github.com/repos/symfony/mailer/zipball/ab97ef2f7acf0216955f5845484235113047a31d",
|
||||
"reference": "ab97ef2f7acf0216955f5845484235113047a31d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -7786,7 +7714,7 @@
|
||||
"description": "Helps sending emails",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/mailer/tree/v7.3.3"
|
||||
"source": "https://github.com/symfony/mailer/tree/v7.3.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -7806,7 +7734,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-08-13T11:49:31+00:00"
|
||||
"time": "2025-09-17T05:51:54+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/mailgun-mailer",
|
||||
@@ -7879,16 +7807,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/mime",
|
||||
"version": "v7.3.2",
|
||||
"version": "v7.3.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/mime.git",
|
||||
"reference": "e0a0f859148daf1edf6c60b398eb40bfc96697d1"
|
||||
"reference": "b1b828f69cbaf887fa835a091869e55df91d0e35"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/mime/zipball/e0a0f859148daf1edf6c60b398eb40bfc96697d1",
|
||||
"reference": "e0a0f859148daf1edf6c60b398eb40bfc96697d1",
|
||||
"url": "https://api.github.com/repos/symfony/mime/zipball/b1b828f69cbaf887fa835a091869e55df91d0e35",
|
||||
"reference": "b1b828f69cbaf887fa835a091869e55df91d0e35",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -7943,7 +7871,7 @@
|
||||
"mime-type"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/mime/tree/v7.3.2"
|
||||
"source": "https://github.com/symfony/mime/tree/v7.3.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -7963,7 +7891,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-07-15T13:41:35+00:00"
|
||||
"time": "2025-09-16T08:38:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/options-resolver",
|
||||
@@ -8867,16 +8795,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v7.3.3",
|
||||
"version": "v7.3.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/process.git",
|
||||
"reference": "32241012d521e2e8a9d713adb0812bb773b907f1"
|
||||
"reference": "f24f8f316367b30810810d4eb30c543d7003ff3b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/32241012d521e2e8a9d713adb0812bb773b907f1",
|
||||
"reference": "32241012d521e2e8a9d713adb0812bb773b907f1",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/f24f8f316367b30810810d4eb30c543d7003ff3b",
|
||||
"reference": "f24f8f316367b30810810d4eb30c543d7003ff3b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -8908,7 +8836,7 @@
|
||||
"description": "Executes commands in sub-processes",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/process/tree/v7.3.3"
|
||||
"source": "https://github.com/symfony/process/tree/v7.3.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -8928,7 +8856,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-08-18T09:42:54+00:00"
|
||||
"time": "2025-09-11T10:12:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/psr-http-message-bridge",
|
||||
@@ -9015,16 +8943,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/routing",
|
||||
"version": "v7.3.2",
|
||||
"version": "v7.3.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/routing.git",
|
||||
"reference": "7614b8ca5fa89b9cd233e21b627bfc5774f586e4"
|
||||
"reference": "8dc648e159e9bac02b703b9fbd937f19ba13d07c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/routing/zipball/7614b8ca5fa89b9cd233e21b627bfc5774f586e4",
|
||||
"reference": "7614b8ca5fa89b9cd233e21b627bfc5774f586e4",
|
||||
"url": "https://api.github.com/repos/symfony/routing/zipball/8dc648e159e9bac02b703b9fbd937f19ba13d07c",
|
||||
"reference": "8dc648e159e9bac02b703b9fbd937f19ba13d07c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -9076,7 +9004,7 @@
|
||||
"url"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/routing/tree/v7.3.2"
|
||||
"source": "https://github.com/symfony/routing/tree/v7.3.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -9096,7 +9024,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-07-15T11:36:08+00:00"
|
||||
"time": "2025-09-11T10:12:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/service-contracts",
|
||||
@@ -9183,16 +9111,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/string",
|
||||
"version": "v7.3.3",
|
||||
"version": "v7.3.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/string.git",
|
||||
"reference": "17a426cce5fd1f0901fefa9b2a490d0038fd3c9c"
|
||||
"reference": "f96476035142921000338bad71e5247fbc138872"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/17a426cce5fd1f0901fefa9b2a490d0038fd3c9c",
|
||||
"reference": "17a426cce5fd1f0901fefa9b2a490d0038fd3c9c",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/f96476035142921000338bad71e5247fbc138872",
|
||||
"reference": "f96476035142921000338bad71e5247fbc138872",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -9207,7 +9135,6 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/emoji": "^7.1",
|
||||
"symfony/error-handler": "^6.4|^7.0",
|
||||
"symfony/http-client": "^6.4|^7.0",
|
||||
"symfony/intl": "^6.4|^7.0",
|
||||
"symfony/translation-contracts": "^2.5|^3.0",
|
||||
@@ -9250,7 +9177,7 @@
|
||||
"utf8"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/string/tree/v7.3.3"
|
||||
"source": "https://github.com/symfony/string/tree/v7.3.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -9270,20 +9197,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-08-25T06:35:40+00:00"
|
||||
"time": "2025-09-11T14:36:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/translation",
|
||||
"version": "v7.3.3",
|
||||
"version": "v7.3.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/translation.git",
|
||||
"reference": "e0837b4cbcef63c754d89a4806575cada743a38d"
|
||||
"reference": "ec25870502d0c7072d086e8ffba1420c85965174"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/translation/zipball/e0837b4cbcef63c754d89a4806575cada743a38d",
|
||||
"reference": "e0837b4cbcef63c754d89a4806575cada743a38d",
|
||||
"url": "https://api.github.com/repos/symfony/translation/zipball/ec25870502d0c7072d086e8ffba1420c85965174",
|
||||
"reference": "ec25870502d0c7072d086e8ffba1420c85965174",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -9350,7 +9277,7 @@
|
||||
"description": "Provides tools to internationalize your application",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/translation/tree/v7.3.3"
|
||||
"source": "https://github.com/symfony/translation/tree/v7.3.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -9370,7 +9297,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-08-01T21:02:37+00:00"
|
||||
"time": "2025-09-07T11:39:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/translation-contracts",
|
||||
@@ -9526,16 +9453,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/var-dumper",
|
||||
"version": "v7.3.3",
|
||||
"version": "v7.3.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/var-dumper.git",
|
||||
"reference": "34d8d4c4b9597347306d1ec8eb4e1319b1e6986f"
|
||||
"reference": "b8abe7daf2730d07dfd4b2ee1cecbf0dd2fbdabb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/34d8d4c4b9597347306d1ec8eb4e1319b1e6986f",
|
||||
"reference": "34d8d4c4b9597347306d1ec8eb4e1319b1e6986f",
|
||||
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/b8abe7daf2730d07dfd4b2ee1cecbf0dd2fbdabb",
|
||||
"reference": "b8abe7daf2730d07dfd4b2ee1cecbf0dd2fbdabb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -9589,7 +9516,7 @@
|
||||
"dump"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/var-dumper/tree/v7.3.3"
|
||||
"source": "https://github.com/symfony/var-dumper/tree/v7.3.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -9609,20 +9536,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-08-13T11:49:31+00:00"
|
||||
"time": "2025-09-11T10:12:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/var-exporter",
|
||||
"version": "v7.3.3",
|
||||
"version": "v7.3.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/var-exporter.git",
|
||||
"reference": "d4dfcd2a822cbedd7612eb6fbd260e46f87b7137"
|
||||
"reference": "0f020b544a30a7fe8ba972e53ee48a74c0bc87f4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/var-exporter/zipball/d4dfcd2a822cbedd7612eb6fbd260e46f87b7137",
|
||||
"reference": "d4dfcd2a822cbedd7612eb6fbd260e46f87b7137",
|
||||
"url": "https://api.github.com/repos/symfony/var-exporter/zipball/0f020b544a30a7fe8ba972e53ee48a74c0bc87f4",
|
||||
"reference": "0f020b544a30a7fe8ba972e53ee48a74c0bc87f4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -9670,7 +9597,7 @@
|
||||
"serialize"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/var-exporter/tree/v7.3.3"
|
||||
"source": "https://github.com/symfony/var-exporter/tree/v7.3.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -9690,7 +9617,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-08-18T13:10:53+00:00"
|
||||
"time": "2025-09-11T10:12:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "thecodingmachine/safe",
|
||||
@@ -11893,16 +11820,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "12.3.14",
|
||||
"version": "12.3.15",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "13e9b2bea9327b094176147250d2c10319a10f5b"
|
||||
"reference": "b035ee2cd8ecad4091885b61017ebb1d80eb0e57"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/13e9b2bea9327b094176147250d2c10319a10f5b",
|
||||
"reference": "13e9b2bea9327b094176147250d2c10319a10f5b",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b035ee2cd8ecad4091885b61017ebb1d80eb0e57",
|
||||
"reference": "b035ee2cd8ecad4091885b61017ebb1d80eb0e57",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -11916,7 +11843,7 @@
|
||||
"phar-io/manifest": "^2.0.4",
|
||||
"phar-io/version": "^3.2.1",
|
||||
"php": ">=8.3",
|
||||
"phpunit/php-code-coverage": "^12.3.8",
|
||||
"phpunit/php-code-coverage": "^12.4.0",
|
||||
"phpunit/php-file-iterator": "^6.0.0",
|
||||
"phpunit/php-invoker": "^6.0.0",
|
||||
"phpunit/php-text-template": "^5.0.0",
|
||||
@@ -11970,7 +11897,7 @@
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
||||
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/12.3.14"
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/12.3.15"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -11994,7 +11921,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-09-24T06:34:27+00:00"
|
||||
"time": "2025-09-28T12:10:54+00:00"
|
||||
},
|
||||
{
|
||||
"name": "rector/rector",
|
||||
|
||||
@@ -78,10 +78,10 @@ return [
|
||||
'running_balance_column' => env('USE_RUNNING_BALANCE', false),
|
||||
// see cer.php for exchange rates feature flag.
|
||||
],
|
||||
'version' => 'develop/2025-09-26',
|
||||
'build_time' => 1758914637,
|
||||
'version' => 'develop/2025-10-02',
|
||||
'build_time' => 1759381368,
|
||||
'api_version' => '2.1.0', // field is no longer used.
|
||||
'db_version' => 27,
|
||||
'db_version' => 28, // field is no longer used.
|
||||
|
||||
// generic settings
|
||||
'maxUploadSize' => 1073741824, // 1 GB
|
||||
|
||||
@@ -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');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +80,7 @@ class TransactionCurrencySeeder extends Seeder
|
||||
$currencies[] = ['code' => 'CHF', 'name' => 'Swiss franc', 'symbol' => 'CHF', 'decimal_places' => 2];
|
||||
$currencies[] = ['code' => 'NOK', 'name' => 'Norwegian krone', 'symbol' => 'kr.', 'decimal_places' => 2];
|
||||
$currencies[] = ['code' => 'CZK', 'name' => 'Czech koruna', 'symbol' => 'Kč', 'decimal_places' => 2];
|
||||
$currencies[] = ['code' => 'KZT', 'name' => 'Kazakhstani tenge', 'symbol' => '₸', 'decimal_places' => 2];
|
||||
|
||||
foreach ($currencies as $currency) {
|
||||
if (null === TransactionCurrency::where('code', $currency['code'])->first()) {
|
||||
|
||||
346
package-lock.json
generated
346
package-lock.json
generated
@@ -2135,9 +2135,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@fortawesome/fontawesome-free": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-7.0.1.tgz",
|
||||
"integrity": "sha512-RLmb9U6H2rJDnGxEqXxzy7ANPrQz7WK2/eTjdZqyU9uRU5W+FkAec9uU5gTYzFBH7aoXIw2WTJSCJR4KPlReQw==",
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-7.1.0.tgz",
|
||||
"integrity": "sha512-+WxNld5ZCJHvPQCr/GnzCTVREyStrAJjisUPtUxG5ngDA8TMlPnKp6dddlTpai4+1GNmltAeuk1hJEkBohwZYA==",
|
||||
"license": "(CC-BY-4.0 AND OFL-1.1 AND MIT)",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
@@ -2589,9 +2589,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||
"version": "4.52.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.2.tgz",
|
||||
"integrity": "sha512-o3pcKzJgSGt4d74lSZ+OCnHwkKBeAbFDmbEm5gg70eA8VkyCuC/zV9TwBnmw6VjDlRdF4Pshfb+WE9E6XY1PoQ==",
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.3.tgz",
|
||||
"integrity": "sha512-h6cqHGZ6VdnwliFG1NXvMPTy/9PS3h8oLh7ImwR+kl+oYnQizgjxsONmmPSb2C66RksfkfIxEVtDSEcJiO0tqw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -2603,9 +2603,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm64": {
|
||||
"version": "4.52.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.2.tgz",
|
||||
"integrity": "sha512-cqFSWO5tX2vhC9hJTK8WAiPIm4Q8q/cU8j2HQA0L3E1uXvBYbOZMhE2oFL8n2pKB5sOCHY6bBuHaRwG7TkfJyw==",
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.3.tgz",
|
||||
"integrity": "sha512-wd+u7SLT/u6knklV/ifG7gr5Qy4GUbH2hMWcDauPFJzmCZUAJ8L2bTkVXC2niOIxp8lk3iH/QX8kSrUxVZrOVw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -2617,9 +2617,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||
"version": "4.52.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.2.tgz",
|
||||
"integrity": "sha512-vngduywkkv8Fkh3wIZf5nFPXzWsNsVu1kvtLETWxTFf/5opZmflgVSeLgdHR56RQh71xhPhWoOkEBvbehwTlVA==",
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.3.tgz",
|
||||
"integrity": "sha512-lj9ViATR1SsqycwFkJCtYfQTheBdvlWJqzqxwc9f2qrcVrQaF/gCuBRTiTolkRWS6KvNxSk4KHZWG7tDktLgjg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -2631,9 +2631,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-x64": {
|
||||
"version": "4.52.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.2.tgz",
|
||||
"integrity": "sha512-h11KikYrUCYTrDj6h939hhMNlqU2fo/X4NB0OZcys3fya49o1hmFaczAiJWVAFgrM1NCP6RrO7lQKeVYSKBPSQ==",
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.3.tgz",
|
||||
"integrity": "sha512-+Dyo7O1KUmIsbzx1l+4V4tvEVnVQqMOIYtrxK7ncLSknl1xnMHLgn7gddJVrYPNZfEB8CIi3hK8gq8bDhb3h5A==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -2645,9 +2645,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-freebsd-arm64": {
|
||||
"version": "4.52.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.2.tgz",
|
||||
"integrity": "sha512-/eg4CI61ZUkLXxMHyVlmlGrSQZ34xqWlZNW43IAU4RmdzWEx0mQJ2mN/Cx4IHLVZFL6UBGAh+/GXhgvGb+nVxw==",
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.3.tgz",
|
||||
"integrity": "sha512-u9Xg2FavYbD30g3DSfNhxgNrxhi6xVG4Y6i9Ur1C7xUuGDW3banRbXj+qgnIrwRN4KeJ396jchwy9bCIzbyBEQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -2659,9 +2659,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-freebsd-x64": {
|
||||
"version": "4.52.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.2.tgz",
|
||||
"integrity": "sha512-QOWgFH5X9+p+S1NAfOqc0z8qEpJIoUHf7OWjNUGOeW18Mx22lAUOiA9b6r2/vpzLdfxi/f+VWsYjUOMCcYh0Ng==",
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.3.tgz",
|
||||
"integrity": "sha512-5M8kyi/OX96wtD5qJR89a/3x5x8x5inXBZO04JWhkQb2JWavOWfjgkdvUqibGJeNNaz1/Z1PPza5/tAPXICI6A==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -2673,9 +2673,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
||||
"version": "4.52.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.2.tgz",
|
||||
"integrity": "sha512-kDWSPafToDd8LcBYd1t5jw7bD5Ojcu12S3uT372e5HKPzQt532vW+rGFFOaiR0opxePyUkHrwz8iWYEyH1IIQA==",
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.3.tgz",
|
||||
"integrity": "sha512-IoerZJ4l1wRMopEHRKOO16e04iXRDyZFZnNZKrWeNquh5d6bucjezgd+OxG03mOMTnS1x7hilzb3uURPkJ0OfA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -2687,9 +2687,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
||||
"version": "4.52.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.2.tgz",
|
||||
"integrity": "sha512-gKm7Mk9wCv6/rkzwCiUC4KnevYhlf8ztBrDRT9g/u//1fZLapSRc+eDZj2Eu2wpJ+0RzUKgtNijnVIB4ZxyL+w==",
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.3.tgz",
|
||||
"integrity": "sha512-ZYdtqgHTDfvrJHSh3W22TvjWxwOgc3ThK/XjgcNGP2DIwFIPeAPNsQxrJO5XqleSlgDux2VAoWQ5iJrtaC1TbA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -2701,9 +2701,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
||||
"version": "4.52.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.2.tgz",
|
||||
"integrity": "sha512-66lA8vnj5mB/rtDNwPgrrKUOtCLVQypkyDa2gMfOefXK6rcZAxKLO9Fy3GkW8VkPnENv9hBkNOFfGLf6rNKGUg==",
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.3.tgz",
|
||||
"integrity": "sha512-NcViG7A0YtuFDA6xWSgmFb6iPFzHlf5vcqb2p0lGEbT+gjrEEz8nC/EeDHvx6mnGXnGCC1SeVV+8u+smj0CeGQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -2715,9 +2715,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
||||
"version": "4.52.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.2.tgz",
|
||||
"integrity": "sha512-s+OPucLNdJHvuZHuIz2WwncJ+SfWHFEmlC5nKMUgAelUeBUnlB4wt7rXWiyG4Zn07uY2Dd+SGyVa9oyLkVGOjA==",
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.3.tgz",
|
||||
"integrity": "sha512-d3pY7LWno6SYNXRm6Ebsq0DJGoiLXTb83AIPCXl9fmtIQs/rXoS8SJxxUNtFbJ5MiOvs+7y34np77+9l4nfFMw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -2729,9 +2729,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-loong64-gnu": {
|
||||
"version": "4.52.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.2.tgz",
|
||||
"integrity": "sha512-8wTRM3+gVMDLLDdaT6tKmOE3lJyRy9NpJUS/ZRWmLCmOPIJhVyXwjBo+XbrrwtV33Em1/eCTd5TuGJm4+DmYjw==",
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.3.tgz",
|
||||
"integrity": "sha512-3y5GA0JkBuirLqmjwAKwB0keDlI6JfGYduMlJD/Rl7fvb4Ni8iKdQs1eiunMZJhwDWdCvrcqXRY++VEBbvk6Eg==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
@@ -2743,9 +2743,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
|
||||
"version": "4.52.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.2.tgz",
|
||||
"integrity": "sha512-6yqEfgJ1anIeuP2P/zhtfBlDpXUb80t8DpbYwXQ3bQd95JMvUaqiX+fKqYqUwZXqdJDd8xdilNtsHM2N0cFm6A==",
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.3.tgz",
|
||||
"integrity": "sha512-AUUH65a0p3Q0Yfm5oD2KVgzTKgwPyp9DSXc3UA7DtxhEb/WSPfbG4wqXeSN62OG5gSo18em4xv6dbfcUGXcagw==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
@@ -2757,9 +2757,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
||||
"version": "4.52.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.2.tgz",
|
||||
"integrity": "sha512-sshYUiYVSEI2B6dp4jMncwxbrUqRdNApF2c3bhtLAU0qA8Lrri0p0NauOsTWh3yCCCDyBOjESHMExonp7Nzc0w==",
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.3.tgz",
|
||||
"integrity": "sha512-1makPhFFVBqZE+XFg3Dkq+IkQ7JvmUrwwqaYBL2CE+ZpxPaqkGaiWFEWVGyvTwZace6WLJHwjVh/+CXbKDGPmg==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
@@ -2771,9 +2771,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-riscv64-musl": {
|
||||
"version": "4.52.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.2.tgz",
|
||||
"integrity": "sha512-duBLgd+3pqC4MMwBrKkFxaZerUxZcYApQVC5SdbF5/e/589GwVvlRUnyqMFbM8iUSb1BaoX/3fRL7hB9m2Pj8Q==",
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.3.tgz",
|
||||
"integrity": "sha512-OOFJa28dxfl8kLOPMUOQBCO6z3X2SAfzIE276fwT52uXDWUS178KWq0pL7d6p1kz7pkzA0yQwtqL0dEPoVcRWg==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
@@ -2785,9 +2785,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
||||
"version": "4.52.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.2.tgz",
|
||||
"integrity": "sha512-tzhYJJidDUVGMgVyE+PmxENPHlvvqm1KILjjZhB8/xHYqAGeizh3GBGf9u6WdJpZrz1aCpIIHG0LgJgH9rVjHQ==",
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.3.tgz",
|
||||
"integrity": "sha512-jMdsML2VI5l+V7cKfZx3ak+SLlJ8fKvLJ0Eoa4b9/vCUrzXKgoKxvHqvJ/mkWhFiyp88nCkM5S2v6nIwRtPcgg==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
@@ -2799,9 +2799,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||
"version": "4.52.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.2.tgz",
|
||||
"integrity": "sha512-opH8GSUuVcCSSyHHcl5hELrmnk4waZoVpgn/4FDao9iyE4WpQhyWJ5ryl5M3ocp4qkRuHfyXnGqg8M9oKCEKRA==",
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.3.tgz",
|
||||
"integrity": "sha512-tPgGd6bY2M2LJTA1uGq8fkSPK8ZLYjDjY+ZLK9WHncCnfIz29LIXIqUgzCR0hIefzy6Hpbe8Th5WOSwTM8E7LA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -2813,9 +2813,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-musl": {
|
||||
"version": "4.52.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.2.tgz",
|
||||
"integrity": "sha512-LSeBHnGli1pPKVJ79ZVJgeZWWZXkEe/5o8kcn23M8eMKCUANejchJbF/JqzM4RRjOJfNRhKJk8FuqL1GKjF5oQ==",
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.3.tgz",
|
||||
"integrity": "sha512-BCFkJjgk+WFzP+tcSMXq77ymAPIxsX9lFJWs+2JzuZTLtksJ2o5hvgTdIcZ5+oKzUDMwI0PfWzRBYAydAHF2Mw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -2827,9 +2827,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-openharmony-arm64": {
|
||||
"version": "4.52.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.2.tgz",
|
||||
"integrity": "sha512-uPj7MQ6/s+/GOpolavm6BPo+6CbhbKYyZHUDvZ/SmJM7pfDBgdGisFX3bY/CBDMg2ZO4utfhlApkSfZ92yXw7Q==",
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.3.tgz",
|
||||
"integrity": "sha512-KTD/EqjZF3yvRaWUJdD1cW+IQBk4fbQaHYJUmP8N4XoKFZilVL8cobFSTDnjTtxWJQ3JYaMgF4nObY/+nYkumA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -2841,9 +2841,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
||||
"version": "4.52.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.2.tgz",
|
||||
"integrity": "sha512-Z9MUCrSgIaUeeHAiNkm3cQyst2UhzjPraR3gYYfOjAuZI7tcFRTOD+4cHLPoS/3qinchth+V56vtqz1Tv+6KPA==",
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.3.tgz",
|
||||
"integrity": "sha512-+zteHZdoUYLkyYKObGHieibUFLbttX2r+58l27XZauq0tcWYYuKUwY2wjeCN9oK1Um2YgH2ibd6cnX/wFD7DuA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -2855,9 +2855,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
||||
"version": "4.52.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.2.tgz",
|
||||
"integrity": "sha512-+GnYBmpjldD3XQd+HMejo+0gJGwYIOfFeoBQv32xF/RUIvccUz20/V6Otdv+57NE70D5pa8W/jVGDoGq0oON4A==",
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.3.tgz",
|
||||
"integrity": "sha512-of1iHkTQSo3kr6dTIRX6t81uj/c/b15HXVsPcEElN5sS859qHrOepM5p9G41Hah+CTqSh2r8Bm56dL2z9UQQ7g==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
@@ -2869,9 +2869,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-x64-gnu": {
|
||||
"version": "4.52.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.2.tgz",
|
||||
"integrity": "sha512-ApXFKluSB6kDQkAqZOKXBjiaqdF1BlKi+/eqnYe9Ee7U2K3pUDKsIyr8EYm/QDHTJIM+4X+lI0gJc3TTRhd+dA==",
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.3.tgz",
|
||||
"integrity": "sha512-s0hybmlHb56mWVZQj8ra9048/WZTPLILKxcvcq+8awSZmyiSUZjjem1AhU3Tf4ZKpYhK4mg36HtHDOe8QJS5PQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -2883,9 +2883,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
||||
"version": "4.52.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.2.tgz",
|
||||
"integrity": "sha512-ARz+Bs8kY6FtitYM96PqPEVvPXqEZmPZsSkXvyX19YzDqkCaIlhCieLLMI5hxO9SRZ2XtCtm8wxhy0iJ2jxNfw==",
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.3.tgz",
|
||||
"integrity": "sha512-zGIbEVVXVtauFgl3MRwGWEN36P5ZGenHRMgNw88X5wEhEBpq0XrMEZwOn07+ICrwM17XO5xfMZqh0OldCH5VTA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -3173,13 +3173,13 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "24.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.5.2.tgz",
|
||||
"integrity": "sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==",
|
||||
"version": "24.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.6.2.tgz",
|
||||
"integrity": "sha512-d2L25Y4j+W3ZlNAeMKcy7yDsK425ibcAOO2t7aPTz6gNMH0z2GThtwENCDc0d/Pw9wgyRqE5Px1wkV7naz8ang==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~7.12.0"
|
||||
"undici-types": "~7.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node-forge": {
|
||||
@@ -3898,16 +3898,6 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/at-least-node": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
|
||||
"integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">= 4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/autoprefixer": {
|
||||
"version": "10.4.21",
|
||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz",
|
||||
@@ -4075,9 +4065,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/baseline-browser-mapping": {
|
||||
"version": "2.8.7",
|
||||
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.7.tgz",
|
||||
"integrity": "sha512-bxxN2M3a4d1CRoQC//IqsR5XrLh0IJ8TCv2x6Y9N0nckNz/rTjZB3//GGscZziZOxmjP55rzxg/ze7usFI9FqQ==",
|
||||
"version": "2.8.10",
|
||||
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.10.tgz",
|
||||
"integrity": "sha512-uLfgBi+7IBNay8ECBO2mVMGZAc1VgZWEChxm4lv+TobGdG82LnXMjuNGo/BSSZZL4UmkWhxEHP2f5ziLNwGWMA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
@@ -4360,9 +4350,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/browserslist": {
|
||||
"version": "4.26.2",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.26.2.tgz",
|
||||
"integrity": "sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A==",
|
||||
"version": "4.26.3",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.26.3.tgz",
|
||||
"integrity": "sha512-lAUU+02RFBuCKQPj/P6NgjlbCnLBMp4UtgTx7vNHd3XSIJF87s9a5rA3aH2yw3GS9DqZAUbOtZdCCiZeVRqt0w==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@@ -4380,9 +4370,9 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"baseline-browser-mapping": "^2.8.3",
|
||||
"caniuse-lite": "^1.0.30001741",
|
||||
"electron-to-chromium": "^1.5.218",
|
||||
"baseline-browser-mapping": "^2.8.9",
|
||||
"caniuse-lite": "^1.0.30001746",
|
||||
"electron-to-chromium": "^1.5.227",
|
||||
"node-releases": "^2.0.21",
|
||||
"update-browserslist-db": "^1.1.3"
|
||||
},
|
||||
@@ -4521,9 +4511,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001745",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001745.tgz",
|
||||
"integrity": "sha512-ywt6i8FzvdgrrrGbr1jZVObnVv6adj+0if2/omv9cmR2oiZs30zL4DIyaptKcbOrBdOIc74QTMoJvSE2QHh5UQ==",
|
||||
"version": "1.0.30001746",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001746.tgz",
|
||||
"integrity": "sha512-eA7Ys/DGw+pnkWWSE/id29f2IcPHVoE8wxtvE5JdvD2V28VTDPy1yEeo11Guz0sJ4ZeGRcm3uaTcAqK1LXaphA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@@ -5061,9 +5051,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/cross-env": {
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-10.0.0.tgz",
|
||||
"integrity": "sha512-aU8qlEK/nHYtVuN4p7UQgAwVljzMg8hB4YK5ThRqD2l/ziSnryncPNn7bMLt5cFYsKVKBh8HqLqyCoTupEUu7Q==",
|
||||
"version": "10.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-10.1.0.tgz",
|
||||
"integrity": "sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -5736,9 +5726,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.5.224",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.224.tgz",
|
||||
"integrity": "sha512-kWAoUu/bwzvnhpdZSIc6KUyvkI1rbRXMT0Eq8pKReyOyaPZcctMli+EgvcN1PAvwVc7Tdo4Fxi2PsLNDU05mdg==",
|
||||
"version": "1.5.228",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.228.tgz",
|
||||
"integrity": "sha512-nxkiyuqAn4MJ1QbobwqJILiDtu/jk14hEAWaMiJmNPh1Z+jqoFlBFZjdXwLWGeVSeu9hGLg6+2G9yJaW8rBIFA==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
@@ -5820,9 +5810,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/envinfo": {
|
||||
"version": "7.14.0",
|
||||
"resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.14.0.tgz",
|
||||
"integrity": "sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==",
|
||||
"version": "7.15.0",
|
||||
"resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.15.0.tgz",
|
||||
"integrity": "sha512-chR+t7exF6y59kelhXw5I3849nTy7KIRO+ePdLMhCD+JRP/JvmkenDWP7QSFGlsHX+kxGxdDutOPrmj5j1HR6g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
@@ -7088,9 +7078,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/i18next": {
|
||||
"version": "25.5.2",
|
||||
"resolved": "https://registry.npmjs.org/i18next/-/i18next-25.5.2.tgz",
|
||||
"integrity": "sha512-lW8Zeh37i/o0zVr+NoCHfNnfvVw+M6FQbRp36ZZ/NyHDJ3NJVpp2HhAUyU9WafL5AssymNoOjMRB48mmx2P6Hw==",
|
||||
"version": "25.5.3",
|
||||
"resolved": "https://registry.npmjs.org/i18next/-/i18next-25.5.3.tgz",
|
||||
"integrity": "sha512-joFqorDeQ6YpIXni944upwnuHBf5IoPMuqAchGVeQLdWC2JOjxgM9V8UGLhNIIH/Q8QleRxIi0BSRQehSrDLcg==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
@@ -8653,16 +8643,6 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/os-tmpdir": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
|
||||
"integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/p-limit": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
|
||||
@@ -8818,9 +8798,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/patch-package": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/patch-package/-/patch-package-8.0.0.tgz",
|
||||
"integrity": "sha512-da8BVIhzjtgScwDJ2TtKsfT5JFWz1hYoBl9rUQ1f38MC2HwnEIkK8VN3dKMKcP7P7bvvgzNDbfNHtx3MsQb5vA==",
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/patch-package/-/patch-package-8.0.1.tgz",
|
||||
"integrity": "sha512-VsKRIA8f5uqHQ7NGhwIna6Bx6D9s/1iXlA1hthBVBEbkq+t4kXD0HHt+rJhf/Z+Ci0F/HCB2hvn0qLdLG+Qxlw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -8829,15 +8809,14 @@
|
||||
"ci-info": "^3.7.0",
|
||||
"cross-spawn": "^7.0.3",
|
||||
"find-yarn-workspace-root": "^2.0.0",
|
||||
"fs-extra": "^9.0.0",
|
||||
"fs-extra": "^10.0.0",
|
||||
"json-stable-stringify": "^1.0.2",
|
||||
"klaw-sync": "^6.0.0",
|
||||
"minimist": "^1.2.6",
|
||||
"open": "^7.4.2",
|
||||
"rimraf": "^2.6.3",
|
||||
"semver": "^7.5.3",
|
||||
"slash": "^2.0.0",
|
||||
"tmp": "^0.0.33",
|
||||
"tmp": "^0.2.4",
|
||||
"yaml": "^2.2.2"
|
||||
},
|
||||
"bin": {
|
||||
@@ -8848,22 +8827,6 @@
|
||||
"npm": ">5"
|
||||
}
|
||||
},
|
||||
"node_modules/patch-package/node_modules/fs-extra": {
|
||||
"version": "9.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
|
||||
"integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"at-least-node": "^1.0.0",
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/patch-package/node_modules/slash": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
|
||||
@@ -10086,9 +10049,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/rimraf": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
||||
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
||||
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
|
||||
"deprecated": "Rimraf versions prior to v4 are no longer supported",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
@@ -10097,6 +10060,9 @@
|
||||
},
|
||||
"bin": {
|
||||
"rimraf": "bin.js"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/ripemd160": {
|
||||
@@ -10130,9 +10096,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/rollup": {
|
||||
"version": "4.52.2",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.2.tgz",
|
||||
"integrity": "sha512-I25/2QgoROE1vYV+NQ1En9T9UFB9Cmfm2CJ83zZOlaDpvz29wGQSZXWKw7MiNXau7wYgB/T9fVIdIuEQ+KbiiA==",
|
||||
"version": "4.52.3",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.3.tgz",
|
||||
"integrity": "sha512-RIDh866U8agLgiIcdpB+COKnlCreHJLfIhWC3LVflku5YHfpnsIKigRZeFfMfCc4dVcqNVfQQ5gO/afOck064A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -10146,28 +10112,28 @@
|
||||
"npm": ">=8.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rollup/rollup-android-arm-eabi": "4.52.2",
|
||||
"@rollup/rollup-android-arm64": "4.52.2",
|
||||
"@rollup/rollup-darwin-arm64": "4.52.2",
|
||||
"@rollup/rollup-darwin-x64": "4.52.2",
|
||||
"@rollup/rollup-freebsd-arm64": "4.52.2",
|
||||
"@rollup/rollup-freebsd-x64": "4.52.2",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.52.2",
|
||||
"@rollup/rollup-linux-arm-musleabihf": "4.52.2",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.52.2",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.52.2",
|
||||
"@rollup/rollup-linux-loong64-gnu": "4.52.2",
|
||||
"@rollup/rollup-linux-ppc64-gnu": "4.52.2",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.52.2",
|
||||
"@rollup/rollup-linux-riscv64-musl": "4.52.2",
|
||||
"@rollup/rollup-linux-s390x-gnu": "4.52.2",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.52.2",
|
||||
"@rollup/rollup-linux-x64-musl": "4.52.2",
|
||||
"@rollup/rollup-openharmony-arm64": "4.52.2",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.52.2",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.52.2",
|
||||
"@rollup/rollup-win32-x64-gnu": "4.52.2",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.52.2",
|
||||
"@rollup/rollup-android-arm-eabi": "4.52.3",
|
||||
"@rollup/rollup-android-arm64": "4.52.3",
|
||||
"@rollup/rollup-darwin-arm64": "4.52.3",
|
||||
"@rollup/rollup-darwin-x64": "4.52.3",
|
||||
"@rollup/rollup-freebsd-arm64": "4.52.3",
|
||||
"@rollup/rollup-freebsd-x64": "4.52.3",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.52.3",
|
||||
"@rollup/rollup-linux-arm-musleabihf": "4.52.3",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.52.3",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.52.3",
|
||||
"@rollup/rollup-linux-loong64-gnu": "4.52.3",
|
||||
"@rollup/rollup-linux-ppc64-gnu": "4.52.3",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.52.3",
|
||||
"@rollup/rollup-linux-riscv64-musl": "4.52.3",
|
||||
"@rollup/rollup-linux-s390x-gnu": "4.52.3",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.52.3",
|
||||
"@rollup/rollup-linux-x64-musl": "4.52.3",
|
||||
"@rollup/rollup-openharmony-arm64": "4.52.3",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.52.3",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.52.3",
|
||||
"@rollup/rollup-win32-x64-gnu": "4.52.3",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.52.3",
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
@@ -11214,16 +11180,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/tmp": {
|
||||
"version": "0.0.33",
|
||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
|
||||
"integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz",
|
||||
"integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"os-tmpdir": "~1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.6.0"
|
||||
"node": ">=14.14"
|
||||
}
|
||||
},
|
||||
"node_modules/to-arraybuffer": {
|
||||
@@ -11343,9 +11306,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "7.12.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.12.0.tgz",
|
||||
"integrity": "sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ==",
|
||||
"version": "7.13.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.13.0.tgz",
|
||||
"integrity": "sha512-Ov2Rr9Sx+fRgagJ5AX0qvItZG/JKKoBRAVITs1zk7IqZGTJUwgUr7qoYBpWwakpWilTZFM98rG/AFRocu10iIQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
@@ -11863,9 +11826,9 @@
|
||||
"license": "BSD-2-Clause"
|
||||
},
|
||||
"node_modules/webpack": {
|
||||
"version": "5.101.3",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.101.3.tgz",
|
||||
"integrity": "sha512-7b0dTKR3Ed//AD/6kkx/o7duS8H3f1a4w3BYpIriX4BzIhjkn4teo05cptsxvLesHFKK5KObnadmCHBwGc+51A==",
|
||||
"version": "5.102.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.102.0.tgz",
|
||||
"integrity": "sha512-hUtqAR3ZLVEYDEABdBioQCIqSoguHbFn1K7WlPPWSuXmx0031BD73PSE35jKyftdSh4YLDoQNgK4pqBt5Q82MA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -11877,7 +11840,7 @@
|
||||
"@webassemblyjs/wasm-parser": "^1.14.1",
|
||||
"acorn": "^8.15.0",
|
||||
"acorn-import-phases": "^1.0.3",
|
||||
"browserslist": "^4.24.0",
|
||||
"browserslist": "^4.24.5",
|
||||
"chrome-trace-event": "^1.0.2",
|
||||
"enhanced-resolve": "^5.17.3",
|
||||
"es-module-lexer": "^1.2.1",
|
||||
@@ -11890,9 +11853,9 @@
|
||||
"mime-types": "^2.1.27",
|
||||
"neo-async": "^2.6.2",
|
||||
"schema-utils": "^4.3.2",
|
||||
"tapable": "^2.1.1",
|
||||
"tapable": "^2.2.3",
|
||||
"terser-webpack-plugin": "^5.3.11",
|
||||
"watchpack": "^2.4.1",
|
||||
"watchpack": "^2.4.4",
|
||||
"webpack-sources": "^3.3.3"
|
||||
},
|
||||
"bin": {
|
||||
@@ -12155,23 +12118,6 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/webpack-dev-server/node_modules/rimraf": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
||||
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
|
||||
"deprecated": "Rimraf versions prior to v4 are no longer supported",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"glob": "^7.1.3"
|
||||
},
|
||||
"bin": {
|
||||
"rimraf": "bin.js"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/webpack-dev-server/node_modules/schema-utils": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz",
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
"title": "Titel",
|
||||
"date": "Datum",
|
||||
"book_date": "Buchungsdatum",
|
||||
"process_date": "Bearbeitungsdatum",
|
||||
"process_date": "Wertstellungsdatum",
|
||||
"due_date": "F\u00e4lligkeitstermin",
|
||||
"foreign_amount": "Ausl\u00e4ndischer Betrag",
|
||||
"payment_date": "Zahlungsdatum",
|
||||
|
||||
@@ -12,8 +12,7 @@
|
||||
{# Firefly III version #}
|
||||
<tr>
|
||||
<td>Firefly III</td>
|
||||
<td>{% if FF_IS_DEVELOP %}<!-- .Z9JBCmw64Zkx1pQw -->{% endif %}{% if not FF_IS_DEVELOP %}v{% endif %}{{ FF_VERSION }} / <span>#</span>{{ system.db_version }} (expects <span>#</span>{{ config('firefly.db_version') }})
|
||||
</td>
|
||||
<td>{% if FF_IS_DEVELOP %}<!-- .Z9JBCmw64Zkx1pQw -->{% endif %}{% if not FF_IS_DEVELOP %}v{% endif %}{{ FF_VERSION }}</td>
|
||||
</tr>
|
||||
{# PHP version + settings #}
|
||||
<tr>
|
||||
|
||||
Reference in New Issue
Block a user