Compare commits

..

14 Commits

Author SHA1 Message Date
github-actions[bot]
a00e8b976c Merge pull request #11458 from firefly-iii/release-1767598313
🤖 Automatically merge the PR into the develop branch.
2026-01-05 08:32:02 +01:00
JC5
e5b3c3e6bd 🤖 Auto commit for release 'develop' on 2026-01-05 2026-01-05 08:31:53 +01:00
James Cole
4d7f63273e Fix #11449 2026-01-04 20:21:41 +01:00
James Cole
04553f6fc5 Fix #11443 2026-01-03 14:46:39 +01:00
James Cole
54676715c0 Create new request for search. 2026-01-02 16:38:46 +01:00
github-actions[bot]
23246e8f5a Merge pull request #11434 from firefly-iii/release-1767337981
🤖 Automatically merge the PR into the develop branch.
2026-01-02 08:13:10 +01:00
JC5
4ccd65b4d7 🤖 Auto commit for release 'develop' on 2026-01-02 2026-01-02 08:13:01 +01:00
James Cole
2209087b94 Previous year, fixes #11433 2026-01-02 07:59:29 +01:00
github-actions[bot]
f655dcbcf8 Merge pull request #11429 from firefly-iii/release-1767278452
🤖 Automatically merge the PR into the develop branch.
2026-01-01 15:40:59 +01:00
JC5
13bb064734 🤖 Auto commit for release 'develop' on 2026-01-01 2026-01-01 15:40:52 +01:00
James Cole
5a3edbe68f Be less strict about bills. 2026-01-01 15:37:09 +01:00
github-actions[bot]
76657b5519 Merge pull request #11428 from firefly-iii/release-1767271388
🤖 Automatically merge the PR into the develop branch.
2026-01-01 13:43:16 +01:00
JC5
775deb2142 🤖 Auto commit for release 'develop' on 2026-01-01 2026-01-01 13:43:08 +01:00
James Cole
8220d491f9 Fix popup in report helper 2026-01-01 13:39:16 +01:00
17 changed files with 253 additions and 131 deletions

View File

@@ -402,16 +402,16 @@
},
{
"name": "friendsofphp/php-cs-fixer",
"version": "v3.92.3",
"version": "v3.92.4",
"source": {
"type": "git",
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
"reference": "2ba8f5a60f6f42fb65758cfb3768434fa2d1c7e8"
"reference": "9e7488b19403423e02e8403cc1eb596baf4673b0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/2ba8f5a60f6f42fb65758cfb3768434fa2d1c7e8",
"reference": "2ba8f5a60f6f42fb65758cfb3768434fa2d1c7e8",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/9e7488b19403423e02e8403cc1eb596baf4673b0",
"reference": "9e7488b19403423e02e8403cc1eb596baf4673b0",
"shasum": ""
},
"require": {
@@ -443,17 +443,17 @@
},
"require-dev": {
"facile-it/paraunit": "^1.3.1 || ^2.7",
"infection/infection": "^0.31.0",
"justinrainbow/json-schema": "^6.5",
"keradus/cli-executor": "^2.2",
"infection/infection": "^0.31",
"justinrainbow/json-schema": "^6.6",
"keradus/cli-executor": "^2.3",
"mikey179/vfsstream": "^1.6.12",
"php-coveralls/php-coveralls": "^2.9",
"php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.6",
"php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.6",
"phpunit/phpunit": "^9.6.25 || ^10.5.53 || ^11.5.34",
"phpunit/phpunit": "^9.6.31 || ^10.5.60 || ^11.5.46",
"symfony/polyfill-php85": "^1.33",
"symfony/var-dumper": "^5.4.48 || ^6.4.24 || ^7.3.2 || ^8.0",
"symfony/yaml": "^5.4.45 || ^6.4.24 || ^7.3.2 || ^8.0"
"symfony/var-dumper": "^5.4.48 || ^6.4.26 || ^7.4.0 || ^8.0",
"symfony/yaml": "^5.4.45 || ^6.4.30 || ^7.4.1 || ^8.0"
},
"suggest": {
"ext-dom": "For handling output formats in XML",
@@ -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.92.3"
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.92.4"
},
"funding": [
{
@@ -502,7 +502,7 @@
"type": "github"
}
],
"time": "2025-12-18T10:45:02+00:00"
"time": "2026-01-04T00:38:52+00:00"
},
{
"name": "psr/container",
@@ -1252,16 +1252,16 @@
},
{
"name": "symfony/console",
"version": "v8.0.1",
"version": "v8.0.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "fcb73f69d655b48fcb894a262f074218df08bd58"
"reference": "6145b304a5c1ea0bdbd0b04d297a5864f9a7d587"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/fcb73f69d655b48fcb894a262f074218df08bd58",
"reference": "fcb73f69d655b48fcb894a262f074218df08bd58",
"url": "https://api.github.com/repos/symfony/console/zipball/6145b304a5c1ea0bdbd0b04d297a5864f9a7d587",
"reference": "6145b304a5c1ea0bdbd0b04d297a5864f9a7d587",
"shasum": ""
},
"require": {
@@ -1318,7 +1318,7 @@
"terminal"
],
"support": {
"source": "https://github.com/symfony/console/tree/v8.0.1"
"source": "https://github.com/symfony/console/tree/v8.0.3"
},
"funding": [
{
@@ -1338,7 +1338,7 @@
"type": "tidelift"
}
],
"time": "2025-12-05T15:25:33+00:00"
"time": "2025-12-23T14:52:06+00:00"
},
{
"name": "symfony/deprecation-contracts",
@@ -1640,16 +1640,16 @@
},
{
"name": "symfony/finder",
"version": "v8.0.0",
"version": "v8.0.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
"reference": "7598dd5770580fa3517ec83e8da0c9b9e01f4291"
"reference": "dd3a2953570a283a2ba4e17063bb98c734cf5b12"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/7598dd5770580fa3517ec83e8da0c9b9e01f4291",
"reference": "7598dd5770580fa3517ec83e8da0c9b9e01f4291",
"url": "https://api.github.com/repos/symfony/finder/zipball/dd3a2953570a283a2ba4e17063bb98c734cf5b12",
"reference": "dd3a2953570a283a2ba4e17063bb98c734cf5b12",
"shasum": ""
},
"require": {
@@ -1684,7 +1684,7 @@
"description": "Finds files and directories via an intuitive fluent interface",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/finder/tree/v8.0.0"
"source": "https://github.com/symfony/finder/tree/v8.0.3"
},
"funding": [
{
@@ -1704,7 +1704,7 @@
"type": "tidelift"
}
],
"time": "2025-11-05T14:36:47+00:00"
"time": "2025-12-23T14:52:06+00:00"
},
{
"name": "symfony/options-resolver",
@@ -2358,16 +2358,16 @@
},
{
"name": "symfony/process",
"version": "v8.0.0",
"version": "v8.0.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
"reference": "a0a750500c4ce900d69ba4e9faf16f82c10ee149"
"reference": "0cbbd88ec836f8757641c651bb995335846abb78"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/a0a750500c4ce900d69ba4e9faf16f82c10ee149",
"reference": "a0a750500c4ce900d69ba4e9faf16f82c10ee149",
"url": "https://api.github.com/repos/symfony/process/zipball/0cbbd88ec836f8757641c651bb995335846abb78",
"reference": "0cbbd88ec836f8757641c651bb995335846abb78",
"shasum": ""
},
"require": {
@@ -2399,7 +2399,7 @@
"description": "Executes commands in sub-processes",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/process/tree/v8.0.0"
"source": "https://github.com/symfony/process/tree/v8.0.3"
},
"funding": [
{
@@ -2419,7 +2419,7 @@
"type": "tidelift"
}
],
"time": "2025-10-16T16:25:44+00:00"
"time": "2025-12-19T10:01:18+00:00"
},
{
"name": "symfony/service-contracts",

View File

@@ -25,11 +25,11 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers\Search;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Search\TransactionSearchRequest;
use FireflyIII\Support\JsonApi\Enrichments\TransactionGroupEnrichment;
use FireflyIII\Support\Search\SearchInterface;
use FireflyIII\Transformers\TransactionGroupTransformer;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection;
@@ -42,12 +42,12 @@ class TransactionController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/search/searchTransactions
*/
public function search(Request $request, SearchInterface $searcher): JsonResponse
public function search(TransactionSearchRequest $request, SearchInterface $searcher): JsonResponse
{
$manager = $this->getManager();
$fullQuery = (string) $request->get('query');
$page = 0 === (int) $request->get('page') ? 1 : (int) $request->get('page');
$pageSize = $this->parameters->get('limit');
$fullQuery = (string) $request->attributes->get('query');
$page = $request->attributes->get('page');
$pageSize = $request->attributes->get('limit');
$searcher->parseQuery($fullQuery);
$searcher->setPage($page);
$searcher->setLimit($pageSize);

View File

@@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
/*
* SearchQueryRequest.php
* Copyright (c) 2026 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\Api\V1\Requests\Search;
use FireflyIII\Api\V1\Requests\ApiRequest;
use Illuminate\Contracts\Validation\Validator;
class SearchQueryRequest extends ApiRequest
{
public function rules(): array
{
return [
'query' => sprintf('min:0|max:500|%s', $this->required),
];
}
public function withValidator(Validator $validator): void
{
$validator->after(
function (Validator $validator): void {
if ($validator->failed()) {
return;
}
$query = $this->convertString('query');
$this->attributes->set('query', $query);
}
);
}
}

View File

@@ -0,0 +1,42 @@
<?php
declare(strict_types=1);
/*
* SearchRequest.php
* Copyright (c) 2026 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\Api\V1\Requests\Search;
use FireflyIII\Api\V1\Requests\AggregateFormRequest;
use FireflyIII\Api\V1\Requests\PaginationRequest;
use FireflyIII\Models\TransactionJournal;
use Override;
class TransactionSearchRequest extends AggregateFormRequest
{
#[Override]
protected function getRequests(): array
{
return [
[PaginationRequest::class, 'sort_class' => TransactionJournal::class],
SearchQueryRequest::class,
// [ObjectTypeApiRequest::class, 'object_type' => Account::class],
];
}
}

View File

@@ -24,15 +24,20 @@ declare(strict_types=1);
namespace FireflyIII\Events\Model\TransactionGroup;
use FireflyIII\Events\Event;
use FireflyIII\Models\RuleGroup;
use FireflyIII\Models\TransactionGroup;
use Illuminate\Queue\SerializesModels;
class TriggeredStoredTransactionGroup extends Event
{
use SerializesModels;
public ?RuleGroup $ruleGroup = null;
/**
* Create a new event instance.
*/
public function __construct(public TransactionGroup $transactionGroup) {}
public function __construct(public TransactionGroup $transactionGroup, ?RuleGroup $ruleGroup = null)
{
$this->ruleGroup = $ruleGroup;
}
}

View File

@@ -28,6 +28,7 @@ use FireflyIII\Events\Model\TransactionGroup\TriggeredStoredTransactionGroup;
use FireflyIII\Events\RequestedSendWebhookMessages;
use FireflyIII\Events\StoredTransactionGroup;
use FireflyIII\Generator\Webhook\MessageGeneratorInterface;
use FireflyIII\Models\RuleGroup;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\PeriodStatistic\PeriodStatisticRepositoryInterface;
@@ -46,7 +47,7 @@ class StoredGroupEventHandler
{
public function runAllHandlers(StoredTransactionGroup $event): void
{
$this->processRules($event);
$this->processRules($event, null);
$this->recalculateCredit($event);
$this->triggerWebhooks($event);
$this->removePeriodStatistics($event);
@@ -55,13 +56,13 @@ class StoredGroupEventHandler
public function triggerRulesManually(TriggeredStoredTransactionGroup $event): void
{
$newEvent = new StoredTransactionGroup($event->transactionGroup, true, false);
$this->processRules($newEvent);
$this->processRules($newEvent, $event->ruleGroup);
}
/**
* This method grabs all the users rules and processes them.
*/
private function processRules(StoredTransactionGroup $storedGroupEvent): void
private function processRules(StoredTransactionGroup $storedGroupEvent, ?RuleGroup $ruleGroup): void
{
if (false === $storedGroupEvent->applyRules) {
Log::info(sprintf('Will not run rules on group #%d', $storedGroupEvent->transactionGroup->id));
@@ -86,7 +87,14 @@ class StoredGroupEventHandler
// add the groups to the rule engine.
// it should run the rules in the group and cancel the group if necessary.
$groups = $ruleGroupRepository->getRuleGroupsWithRules('store-journal');
if (null === $ruleGroup) {
Log::debug('Fire processRules with ALL store-journal rule groups.');
$groups = $ruleGroupRepository->getRuleGroupsWithRules('store-journal');
}
if (null !== $ruleGroup) {
Log::debug(sprintf('Fire processRules with rule group #%d.', $ruleGroup->id));
$groups = new Collection([$ruleGroup]);
}
// create and fire rule engine.
$newRuleEngine = app(RuleEngineInterface::class);

View File

@@ -66,7 +66,7 @@ class PopupReport implements PopupReportInterface
if (null !== $currencyId) {
/** @var CurrencyRepositoryInterface $repos */
$repos = app(CurrencyRepositoryInterface::class);
$currency = $repos->find((int) $currencyId);
$currency = $repos->find((int)$currencyId);
}
/** @var GroupCollectorInterface $collector */
@@ -98,7 +98,7 @@ class PopupReport implements PopupReportInterface
if (null !== $currencyId) {
/** @var CurrencyRepositoryInterface $repos */
$repos = app(CurrencyRepositoryInterface::class);
$currency = $repos->find((int) $currencyId);
$currency = $repos->find((int)$currencyId);
}
/** @var GroupCollectorInterface $collector */
@@ -135,7 +135,7 @@ class PopupReport implements PopupReportInterface
if (null !== $currencyId) {
/** @var CurrencyRepositoryInterface $repos */
$repos = app(CurrencyRepositoryInterface::class);
$currency = $repos->find((int) $currencyId);
$currency = $repos->find((int)$currencyId);
}
/** @var GroupCollectorInterface $collector */
@@ -174,9 +174,10 @@ class PopupReport implements PopupReportInterface
if (null !== $currencyId) {
/** @var CurrencyRepositoryInterface $repos */
$repos = app(CurrencyRepositoryInterface::class);
$currency = $repos->find((int) $currencyId);
$currency = $repos->find((int)$currencyId);
}
/** @var JournalRepositoryInterface $repository */
$repository = app(JournalRepositoryInterface::class);
$repository->setUser($account->user);
@@ -187,11 +188,11 @@ class PopupReport implements PopupReportInterface
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
// set report accounts + the request accounts:
// $set = $attributes['accounts'] ?? new Collection;
// $set->push($account);
// the source account must be in the set.
$set = $attributes['accounts'] ?? new Collection();
$collector->setDestinationAccounts(new Collection()->push($account))
->setSourceAccounts($set)
->setRange($attributes['startDate'], $attributes['endDate'])
->withAccountInformation()
->withBudgetInformation()

View File

@@ -35,6 +35,7 @@ use FireflyIII\Models\TransactionGroup;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
@@ -70,13 +71,20 @@ class ExecutionController extends Controller
*/
public function execute(SelectTransactionsRequest $request, RuleGroup $ruleGroup): RedirectResponse
{
Log::debug(sprintf('You have selected rule group #%d', $ruleGroup->id));
// Get parameters specified by the user
$accounts = $request->get('accounts');
$set = $this->repository->getAccountsById($accounts);
$set = new Collection();
if (is_array($accounts)) {
$set = $this->repository->getAccountsById($accounts);
}
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setAccounts($set);
if (count($set) > 0) {
$collector->setAccounts($set);
}
// add date operators.
if (null !== $request->get('start')) {
$startDate = new Carbon($request->get('start'));
@@ -96,7 +104,7 @@ class ExecutionController extends Controller
/** @var TransactionGroup $group */
foreach ($groups as $group) {
Log::debug(sprintf('Processing group #%d.', $group->id));
event(new TriggeredStoredTransactionGroup($group));
event(new TriggeredStoredTransactionGroup($group, $ruleGroup));
}
}

View File

@@ -191,7 +191,7 @@ class WarnAboutBills implements ShouldQueue
$diff = $earliest->diffInDays($this->date);
Log::debug(sprintf('Difference in days is %s', $diff));
return $diff >= 2;
return $diff >= 6; // FIXME hard coded value.
}
private function sendOverdueAlerts(User $user, array $overdue): void

View File

@@ -157,6 +157,11 @@ trait GetConfigurationData
$index = (string)trans('firefly.year_to_date');
$ranges[$index] = [$yearBegin, new Carbon()];
// previous year:
$yearBegin = today(config('app.timezone'))->subYear()->startOfYear();
$index = (string)trans('firefly.previous_year', ['year' => $yearBegin->year]);
$ranges[$index] = [$yearBegin, $yearBegin->clone()->endOfYear()];
// everything
$index = (string)trans('firefly.everything');
$ranges[$index] = [$first, new Carbon()];

View File

@@ -245,7 +245,6 @@ trait RenderPartialViews
if (null === $account) {
return 'This is an unknown account. Apologies.';
}
$journals = $popupHelper->byExpenses($account, $attributes);
try {

View File

@@ -321,7 +321,7 @@ class SubscriptionEnrichment implements EnrichmentInterface
$array['foreign_currency_code'] = $entry->foreign_currency_code;
$array['foreign_currency_symbol'] = $entry->foreign_currency_symbol;
$array['foreign_currency_decimal_places'] = $entry->foreign_currency_decimal_places;
$array['foreign_amount'] = Steam::bcround($entry->foreign_amount, $entry->foreign_currency_decimal_places);
$array['foreign_amount'] = Steam::bcround((string) $entry->foreign_amount, $entry->foreign_currency_decimal_places);
}
// convert to primary, but is already primary.
if ($this->convertToPrimary && (int)$entry->transaction_currency_id === $this->primaryCurrency->id) {
@@ -329,7 +329,7 @@ class SubscriptionEnrichment implements EnrichmentInterface
}
// convert to primary, but is NOT already primary.
if ($this->convertToPrimary && (int)$entry->transaction_currency_id !== $this->primaryCurrency->id) {
$array['pc_amount'] = $converter->convert($entry->transactionCurrency, $this->primaryCurrency, $entry->date, $entry->amount);
$array['pc_amount'] = $converter->convert($entry->transactionCurrency, $this->primaryCurrency, $entry->date, (string) $entry->amount);
}
// convert to primary, but foreign is already primary.
if ($this->convertToPrimary && (int)$entry->foreign_currency_id === $this->primaryCurrency->id) {
@@ -340,7 +340,7 @@ class SubscriptionEnrichment implements EnrichmentInterface
// TODO this is very database intensive.
/** @var TransactionCurrency $foreignCurrency */
$foreignCurrency = Amount::getTransactionCurrencyById($entry->foreign_currency_id);
$array['pc_foreign_amount'] = $converter->convert($foreignCurrency, $this->primaryCurrency, $entry->date, $entry->amount);
$array['pc_foreign_amount'] = $converter->convert($foreignCurrency, $this->primaryCurrency, $entry->date, (string) $entry->amount);
}
$result[] = $array;
}

View File

@@ -34,6 +34,9 @@
"transfers",
"management"
],
"platform": {
"php": "8.4"
},
"license": "AGPL-3.0-or-later",
"homepage": "https://github.com/firefly-iii/firefly-iii",
"type": "project",

146
composer.lock generated
View File

@@ -3621,16 +3621,16 @@
},
{
"name": "monolog/monolog",
"version": "3.9.0",
"version": "3.10.0",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
"reference": "10d85740180ecba7896c87e06a166e0c95a0e3b6"
"reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/10d85740180ecba7896c87e06a166e0c95a0e3b6",
"reference": "10d85740180ecba7896c87e06a166e0c95a0e3b6",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/b321dd6749f0bf7189444158a3ce785cc16d69b0",
"reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0",
"shasum": ""
},
"require": {
@@ -3648,7 +3648,7 @@
"graylog2/gelf-php": "^1.4.2 || ^2.0",
"guzzlehttp/guzzle": "^7.4.5",
"guzzlehttp/psr7": "^2.2",
"mongodb/mongodb": "^1.8",
"mongodb/mongodb": "^1.8 || ^2.0",
"php-amqplib/php-amqplib": "~2.4 || ^3",
"php-console/php-console": "^3.1.8",
"phpstan/phpstan": "^2",
@@ -3708,7 +3708,7 @@
],
"support": {
"issues": "https://github.com/Seldaek/monolog/issues",
"source": "https://github.com/Seldaek/monolog/tree/3.9.0"
"source": "https://github.com/Seldaek/monolog/tree/3.10.0"
},
"funding": [
{
@@ -3720,7 +3720,7 @@
"type": "tidelift"
}
],
"time": "2025-03-24T10:02:05+00:00"
"time": "2026-01-02T08:56:05+00:00"
},
{
"name": "nesbot/carbon",
@@ -6427,16 +6427,16 @@
},
{
"name": "symfony/cache",
"version": "v8.0.1",
"version": "v8.0.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/cache.git",
"reference": "0e67dc8145810d4e1c0d13c0e1d29ceb930b1c8e"
"reference": "ef8c7dbfe613d2773d0b5e68b2ef2db72c8b025f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/cache/zipball/0e67dc8145810d4e1c0d13c0e1d29ceb930b1c8e",
"reference": "0e67dc8145810d4e1c0d13c0e1d29ceb930b1c8e",
"url": "https://api.github.com/repos/symfony/cache/zipball/ef8c7dbfe613d2773d0b5e68b2ef2db72c8b025f",
"reference": "ef8c7dbfe613d2773d0b5e68b2ef2db72c8b025f",
"shasum": ""
},
"require": {
@@ -6503,7 +6503,7 @@
"psr6"
],
"support": {
"source": "https://github.com/symfony/cache/tree/v8.0.1"
"source": "https://github.com/symfony/cache/tree/v8.0.3"
},
"funding": [
{
@@ -6523,7 +6523,7 @@
"type": "tidelift"
}
],
"time": "2025-12-04T18:17:06+00:00"
"time": "2025-12-28T10:45:32+00:00"
},
{
"name": "symfony/cache-contracts",
@@ -6680,16 +6680,16 @@
},
{
"name": "symfony/console",
"version": "v7.4.1",
"version": "v7.4.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "6d9f0fbf2ec2e9785880096e3abd0ca0c88b506e"
"reference": "732a9ca6cd9dfd940c639062d5edbde2f6727fb6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/6d9f0fbf2ec2e9785880096e3abd0ca0c88b506e",
"reference": "6d9f0fbf2ec2e9785880096e3abd0ca0c88b506e",
"url": "https://api.github.com/repos/symfony/console/zipball/732a9ca6cd9dfd940c639062d5edbde2f6727fb6",
"reference": "732a9ca6cd9dfd940c639062d5edbde2f6727fb6",
"shasum": ""
},
"require": {
@@ -6754,7 +6754,7 @@
"terminal"
],
"support": {
"source": "https://github.com/symfony/console/tree/v7.4.1"
"source": "https://github.com/symfony/console/tree/v7.4.3"
},
"funding": [
{
@@ -6774,7 +6774,7 @@
"type": "tidelift"
}
],
"time": "2025-12-05T15:23:39+00:00"
"time": "2025-12-23T14:50:43+00:00"
},
{
"name": "symfony/css-selector",
@@ -7224,16 +7224,16 @@
},
{
"name": "symfony/finder",
"version": "v7.4.0",
"version": "v7.4.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
"reference": "340b9ed7320570f319028a2cbec46d40535e94bd"
"reference": "fffe05569336549b20a1be64250b40516d6e8d06"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/340b9ed7320570f319028a2cbec46d40535e94bd",
"reference": "340b9ed7320570f319028a2cbec46d40535e94bd",
"url": "https://api.github.com/repos/symfony/finder/zipball/fffe05569336549b20a1be64250b40516d6e8d06",
"reference": "fffe05569336549b20a1be64250b40516d6e8d06",
"shasum": ""
},
"require": {
@@ -7268,7 +7268,7 @@
"description": "Finds files and directories via an intuitive fluent interface",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/finder/tree/v7.4.0"
"source": "https://github.com/symfony/finder/tree/v7.4.3"
},
"funding": [
{
@@ -7288,20 +7288,20 @@
"type": "tidelift"
}
],
"time": "2025-11-05T05:42:40+00:00"
"time": "2025-12-23T14:50:43+00:00"
},
{
"name": "symfony/http-client",
"version": "v8.0.1",
"version": "v8.0.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-client.git",
"reference": "727fda60d0aebfdfcc4c8bc4661f0cb8f44153c0"
"reference": "ea062691009cc2b7bb87734fef20e02671cbd50b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-client/zipball/727fda60d0aebfdfcc4c8bc4661f0cb8f44153c0",
"reference": "727fda60d0aebfdfcc4c8bc4661f0cb8f44153c0",
"url": "https://api.github.com/repos/symfony/http-client/zipball/ea062691009cc2b7bb87734fef20e02671cbd50b",
"reference": "ea062691009cc2b7bb87734fef20e02671cbd50b",
"shasum": ""
},
"require": {
@@ -7364,7 +7364,7 @@
"http"
],
"support": {
"source": "https://github.com/symfony/http-client/tree/v8.0.1"
"source": "https://github.com/symfony/http-client/tree/v8.0.3"
},
"funding": [
{
@@ -7384,7 +7384,7 @@
"type": "tidelift"
}
],
"time": "2025-12-05T14:08:45+00:00"
"time": "2025-12-23T14:52:06+00:00"
},
{
"name": "symfony/http-client-contracts",
@@ -7466,16 +7466,16 @@
},
{
"name": "symfony/http-foundation",
"version": "v7.4.1",
"version": "v7.4.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
"reference": "bd1af1e425811d6f077db240c3a588bdb405cd27"
"reference": "a70c745d4cea48dbd609f4075e5f5cbce453bd52"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/bd1af1e425811d6f077db240c3a588bdb405cd27",
"reference": "bd1af1e425811d6f077db240c3a588bdb405cd27",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/a70c745d4cea48dbd609f4075e5f5cbce453bd52",
"reference": "a70c745d4cea48dbd609f4075e5f5cbce453bd52",
"shasum": ""
},
"require": {
@@ -7524,7 +7524,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.4.1"
"source": "https://github.com/symfony/http-foundation/tree/v7.4.3"
},
"funding": [
{
@@ -7544,20 +7544,20 @@
"type": "tidelift"
}
],
"time": "2025-12-07T11:13:10+00:00"
"time": "2025-12-23T14:23:49+00:00"
},
{
"name": "symfony/http-kernel",
"version": "v7.4.2",
"version": "v7.4.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-kernel.git",
"reference": "f6e6f0a5fa8763f75a504b930163785fb6dd055f"
"reference": "885211d4bed3f857b8c964011923528a55702aa5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/f6e6f0a5fa8763f75a504b930163785fb6dd055f",
"reference": "f6e6f0a5fa8763f75a504b930163785fb6dd055f",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/885211d4bed3f857b8c964011923528a55702aa5",
"reference": "885211d4bed3f857b8c964011923528a55702aa5",
"shasum": ""
},
"require": {
@@ -7643,7 +7643,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.4.2"
"source": "https://github.com/symfony/http-kernel/tree/v7.4.3"
},
"funding": [
{
@@ -7663,20 +7663,20 @@
"type": "tidelift"
}
],
"time": "2025-12-08T07:43:37+00:00"
"time": "2025-12-31T08:43:57+00:00"
},
{
"name": "symfony/mailer",
"version": "v7.4.0",
"version": "v7.4.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/mailer.git",
"reference": "a3d9eea8cfa467ece41f0f54ba28185d74bd53fd"
"reference": "e472d35e230108231ccb7f51eb6b2100cac02ee4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/mailer/zipball/a3d9eea8cfa467ece41f0f54ba28185d74bd53fd",
"reference": "a3d9eea8cfa467ece41f0f54ba28185d74bd53fd",
"url": "https://api.github.com/repos/symfony/mailer/zipball/e472d35e230108231ccb7f51eb6b2100cac02ee4",
"reference": "e472d35e230108231ccb7f51eb6b2100cac02ee4",
"shasum": ""
},
"require": {
@@ -7727,7 +7727,7 @@
"description": "Helps sending emails",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/mailer/tree/v7.4.0"
"source": "https://github.com/symfony/mailer/tree/v7.4.3"
},
"funding": [
{
@@ -7747,7 +7747,7 @@
"type": "tidelift"
}
],
"time": "2025-11-21T15:26:00+00:00"
"time": "2025-12-16T08:02:06+00:00"
},
{
"name": "symfony/mailgun-mailer",
@@ -8810,16 +8810,16 @@
},
{
"name": "symfony/process",
"version": "v7.4.0",
"version": "v7.4.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
"reference": "7ca8dc2d0dcf4882658313aba8be5d9fd01026c8"
"reference": "2f8e1a6cdf590ca63715da4d3a7a3327404a523f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/7ca8dc2d0dcf4882658313aba8be5d9fd01026c8",
"reference": "7ca8dc2d0dcf4882658313aba8be5d9fd01026c8",
"url": "https://api.github.com/repos/symfony/process/zipball/2f8e1a6cdf590ca63715da4d3a7a3327404a523f",
"reference": "2f8e1a6cdf590ca63715da4d3a7a3327404a523f",
"shasum": ""
},
"require": {
@@ -8851,7 +8851,7 @@
"description": "Executes commands in sub-processes",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/process/tree/v7.4.0"
"source": "https://github.com/symfony/process/tree/v7.4.3"
},
"funding": [
{
@@ -8871,7 +8871,7 @@
"type": "tidelift"
}
],
"time": "2025-10-16T11:21:06+00:00"
"time": "2025-12-19T10:00:43+00:00"
},
{
"name": "symfony/psr-http-message-bridge",
@@ -8963,16 +8963,16 @@
},
{
"name": "symfony/routing",
"version": "v7.4.0",
"version": "v7.4.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/routing.git",
"reference": "4720254cb2644a0b876233d258a32bf017330db7"
"reference": "5d3fd7adf8896c2fdb54e2f0f35b1bcbd9e45090"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/routing/zipball/4720254cb2644a0b876233d258a32bf017330db7",
"reference": "4720254cb2644a0b876233d258a32bf017330db7",
"url": "https://api.github.com/repos/symfony/routing/zipball/5d3fd7adf8896c2fdb54e2f0f35b1bcbd9e45090",
"reference": "5d3fd7adf8896c2fdb54e2f0f35b1bcbd9e45090",
"shasum": ""
},
"require": {
@@ -9024,7 +9024,7 @@
"url"
],
"support": {
"source": "https://github.com/symfony/routing/tree/v7.4.0"
"source": "https://github.com/symfony/routing/tree/v7.4.3"
},
"funding": [
{
@@ -9044,7 +9044,7 @@
"type": "tidelift"
}
],
"time": "2025-11-27T13:27:24+00:00"
"time": "2025-12-19T10:00:43+00:00"
},
{
"name": "symfony/service-contracts",
@@ -9225,16 +9225,16 @@
},
{
"name": "symfony/translation",
"version": "v8.0.1",
"version": "v8.0.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/translation.git",
"reference": "770e3b8b0ba8360958abedcabacd4203467333ca"
"reference": "60a8f11f0e15c48f2cc47c4da53873bb5b62135d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/translation/zipball/770e3b8b0ba8360958abedcabacd4203467333ca",
"reference": "770e3b8b0ba8360958abedcabacd4203467333ca",
"url": "https://api.github.com/repos/symfony/translation/zipball/60a8f11f0e15c48f2cc47c4da53873bb5b62135d",
"reference": "60a8f11f0e15c48f2cc47c4da53873bb5b62135d",
"shasum": ""
},
"require": {
@@ -9294,7 +9294,7 @@
"description": "Provides tools to internationalize your application",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/translation/tree/v8.0.1"
"source": "https://github.com/symfony/translation/tree/v8.0.3"
},
"funding": [
{
@@ -9314,7 +9314,7 @@
"type": "tidelift"
}
],
"time": "2025-12-01T09:13:36+00:00"
"time": "2025-12-21T10:59:45+00:00"
},
{
"name": "symfony/translation-contracts",
@@ -9478,16 +9478,16 @@
},
{
"name": "symfony/var-dumper",
"version": "v7.4.0",
"version": "v7.4.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
"reference": "41fd6c4ae28c38b294b42af6db61446594a0dece"
"reference": "7e99bebcb3f90d8721890f2963463280848cba92"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/41fd6c4ae28c38b294b42af6db61446594a0dece",
"reference": "41fd6c4ae28c38b294b42af6db61446594a0dece",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/7e99bebcb3f90d8721890f2963463280848cba92",
"reference": "7e99bebcb3f90d8721890f2963463280848cba92",
"shasum": ""
},
"require": {
@@ -9541,7 +9541,7 @@
"dump"
],
"support": {
"source": "https://github.com/symfony/var-dumper/tree/v7.4.0"
"source": "https://github.com/symfony/var-dumper/tree/v7.4.3"
},
"funding": [
{
@@ -9561,7 +9561,7 @@
"type": "tidelift"
}
],
"time": "2025-10-27T20:36:44+00:00"
"time": "2025-12-18T07:04:31+00:00"
},
{
"name": "symfony/var-exporter",

View File

@@ -78,8 +78,8 @@ return [
'running_balance_column' => (bool)envNonEmpty('USE_RUNNING_BALANCE', true), // this is only the default value, is not used.
// see cer.php for exchange rates feature flag.
],
'version' => 'develop/2025-12-30',
'build_time' => 1767125279,
'version' => 'develop/2026-01-05',
'build_time' => 1767598210,
'api_version' => '2.1.0', // field is no longer used.
'db_version' => 28, // field is no longer used.

2
package-lock.json generated
View File

@@ -11577,7 +11577,7 @@
"version": "8.28.2",
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.28.2.tgz",
"integrity": "sha512-C5GZjs1tYlAqjwymaaCPDjCyGo10ajUphiwA922jKt9n7KPpqR7oM1PCwYzhB/E7+nT3wfdG3oRre5raIT1rKA==",
"deprecated": "Vue I18n v8.x has reached EOL and is no longer actively maintained. About maintenance status, see https://vue-i18n.intlify.dev/guide/maintenance.html",
"deprecated": "v9 and v10 no longer supported. please migrate to v11. about maintenance status, see https://vue-i18n.intlify.dev/guide/maintenance.html",
"dev": true,
"license": "MIT"
},

View File

@@ -43,6 +43,7 @@ return [
'last_180_days' => 'Last 180 days',
'month_to_date' => 'Month to date',
'year_to_date' => 'Year to date',
'previous_year' => 'Previous year (:year)',
'YTD' => 'YTD',
'welcome_back' => 'What\'s playing?',
'main_dashboard_page_title' => 'Home',