Compare commits

...

66 Commits

Author SHA1 Message Date
github-actions[bot]
067112904e Merge pull request #11467 from firefly-iii/develop
🤖 Automatically merge the PR into the main branch.
2026-01-06 21:05:43 +01:00
github-actions[bot]
fc371e27b7 Merge pull request #11466 from firefly-iii/release-1767729927
🤖 Automatically merge the PR into the develop branch.
2026-01-06 21:05:36 +01:00
JC5
52b14b46a2 🤖 Auto commit for release 'v6.4.15' on 2026-01-06 2026-01-06 21:05:27 +01:00
James Cole
5260b770bb Clean up changelog. 2026-01-06 21:01:07 +01:00
github-actions[bot]
226c4c8f8e Merge pull request #11464 from firefly-iii/release-1767729551
🤖 Automatically merge the PR into the develop branch.
2026-01-06 20:59:17 +01:00
JC5
9ebafe64f1 🤖 Auto commit for release 'develop' on 2026-01-06 2026-01-06 20:59:11 +01:00
James Cole
ffa618101d Update changelog. 2026-01-06 20:55:08 +01:00
James Cole
280e531a76 Fix #11396 2026-01-06 20:43:11 +01:00
James Cole
f542a3fd88 Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop 2026-01-06 20:38:46 +01:00
James Cole
581d67a92c Fix #11399 2026-01-06 20:38:41 +01:00
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
github-actions[bot]
6dd2627a6a Merge pull request #11424 from firefly-iii/release-1767125383
🤖 Automatically merge the PR into the develop branch.
2025-12-30 21:09:52 +01:00
JC5
22074568ae 🤖 Auto commit for release 'develop' on 2025-12-30 2025-12-30 21:09:43 +01:00
James Cole
df03899588 Fix whoopsie. 2025-12-30 21:05:50 +01:00
github-actions[bot]
7f4f95097b Merge pull request #11423 from firefly-iii/release-1767124577
🤖 Automatically merge the PR into the develop branch.
2025-12-30 20:56:26 +01:00
JC5
c96ada053f 🤖 Auto commit for release 'develop' on 2025-12-30 2025-12-30 20:56:17 +01:00
James Cole
523ec7c0a1 Expand settings, make accounts not mandatory. 2025-12-30 20:51:56 +01:00
James Cole
61444e9660 New variables for updates. 2025-12-30 16:39:46 +01:00
github-actions[bot]
8235c24c13 Merge pull request #11421 from firefly-iii/release-1767107945
🤖 Automatically merge the PR into the develop branch.
2025-12-30 16:19:14 +01:00
JC5
7ca96a766f 🤖 Auto commit for release 'develop' on 2025-12-30 2025-12-30 16:19:05 +01:00
James Cole
27586a7ec2 Allow transactions to be moved to the future and still have the running balance calculated correctly. 2025-12-30 16:13:28 +01:00
James Cole
dc3c3bb092 Add setting for anonymous amounts in preferences. 2025-12-30 07:24:14 +01:00
github-actions[bot]
7287c29778 Merge pull request #11419 from firefly-iii/release-1767020049
🤖 Automatically merge the PR into the develop branch.
2025-12-29 15:54:17 +01:00
JC5
7d374b22f9 🤖 Auto commit for release 'develop' on 2025-12-29 2025-12-29 15:54:09 +01:00
James Cole
e0542f1270 Fix end of quarter issue. 2025-12-29 11:10:28 +01:00
James Cole
73a9be0605 Fix #11410 2025-12-29 11:05:48 +01:00
github-actions[bot]
1f343bda1a Merge pull request #11416 from firefly-iii/release-1766995950
🤖 Automatically merge the PR into the develop branch.
2025-12-29 09:12:40 +01:00
JC5
1c8eaf93a6 🤖 Auto commit for release 'develop' on 2025-12-29 2025-12-29 09:12:30 +01:00
James Cole
ccfee25000 Merge pull request #11414 from oboxodo/develop
Add Uruguayan Peso to currency seeder
2025-12-29 09:11:25 +01:00
Diego Algorta
07c6dac766 Add Uruguayan Peso to currency seeder 2025-12-28 12:06:08 -03:00
github-actions[bot]
b0b2e5b752 Merge pull request #11411 from firefly-iii/release-1766901579
🤖 Automatically merge the PR into the develop branch.
2025-12-28 06:59:46 +01:00
JC5
ff3a935e9d 🤖 Auto commit for release 'develop' on 2025-12-28 2025-12-28 06:59:39 +01:00
James Cole
f0e2f09da7 Fix some end of period stuff. 2025-12-28 06:54:03 +01:00
github-actions[bot]
f3fbebb9a4 Merge pull request #11409 from firefly-iii/release-1766836192
🤖 Automatically merge the PR into the develop branch.
2025-12-27 12:49:59 +01:00
JC5
6e6e42dab6 🤖 Auto commit for release 'develop' on 2025-12-27 2025-12-27 12:49:53 +01:00
James Cole
d9efd63fad Add debug details. 2025-12-27 12:45:46 +01:00
github-actions[bot]
bc273ada39 Merge pull request #11406 from firefly-iii/release-1766776026
🤖 Automatically merge the PR into the develop branch.
2025-12-26 20:07:14 +01:00
JC5
75c76bb6dd 🤖 Auto commit for release 'develop' on 2025-12-26 2025-12-26 20:07:06 +01:00
James Cole
4d2dd1d8f7 Fix view of running balance column 2025-12-26 20:02:09 +01:00
James Cole
456e73ac16 Fix #11403 2025-12-26 07:09:04 +01:00
James Cole
86f1d8a1bc Fix ALE amount logging. 2025-12-24 07:45:03 +01:00
James Cole
7dac164556 Remove maxlength 2025-12-22 15:39:41 +01:00
James Cole
532df54f10 Merge pull request #11394 from firefly-iii/dependabot/composer/develop/mailersend/laravel-driver-2.12.0 2025-12-22 05:20:33 +01:00
mergify[bot]
daa76d01ca Merge branch 'develop' into dependabot/composer/develop/mailersend/laravel-driver-2.12.0 2025-12-22 03:37:04 +00:00
github-actions[bot]
aa3a435022 Merge pull request #11395 from firefly-iii/release-1766374574
🤖 Automatically merge the PR into the develop branch.
2025-12-22 04:36:21 +01:00
JC5
bc4018481f 🤖 Auto commit for release 'develop' on 2025-12-22 2025-12-22 04:36:14 +01:00
dependabot[bot]
6b7aed7658 Bump mailersend/laravel-driver from 2.9.1 to 2.12.0
Bumps [mailersend/laravel-driver](https://github.com/mailersend/mailersend-laravel-driver) from 2.9.1 to 2.12.0.
- [Release notes](https://github.com/mailersend/mailersend-laravel-driver/releases)
- [Commits](https://github.com/mailersend/mailersend-laravel-driver/compare/v2.9.1...v2.12.0)

---
updated-dependencies:
- dependency-name: mailersend/laravel-driver
  dependency-version: 2.12.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-22 03:01:04 +00:00
James Cole
92a535c644 Only update amount when it's actually changed. 2025-12-20 20:12:07 +01:00
James Cole
340540bd5a Replace calls to Amount facade. 2025-12-20 08:21:05 +01:00
James Cole
c63f4a941b Expand debug info for currency search. 2025-12-20 08:08:57 +01:00
James Cole
7491cb5f58 Merge branches 'develop' and 'develop' of github.com:firefly-iii/firefly-iii into develop 2025-12-20 08:08:30 +01:00
James Cole
31c1e28c76 Add message. 2025-12-20 08:08:20 +01:00
github-actions[bot]
637d8e050a Merge pull request #11376 from firefly-iii/develop
🤖 Automatically merge the PR into the main branch.
2025-12-16 06:42:25 +01:00
83 changed files with 940 additions and 565 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",
@@ -731,16 +731,16 @@
},
{
"name": "react/child-process",
"version": "v0.6.6",
"version": "v0.6.7",
"source": {
"type": "git",
"url": "https://github.com/reactphp/child-process.git",
"reference": "1721e2b93d89b745664353b9cfc8f155ba8a6159"
"reference": "970f0e71945556422ee4570ccbabaedc3cf04ad3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/child-process/zipball/1721e2b93d89b745664353b9cfc8f155ba8a6159",
"reference": "1721e2b93d89b745664353b9cfc8f155ba8a6159",
"url": "https://api.github.com/repos/reactphp/child-process/zipball/970f0e71945556422ee4570ccbabaedc3cf04ad3",
"reference": "970f0e71945556422ee4570ccbabaedc3cf04ad3",
"shasum": ""
},
"require": {
@@ -794,7 +794,7 @@
],
"support": {
"issues": "https://github.com/reactphp/child-process/issues",
"source": "https://github.com/reactphp/child-process/tree/v0.6.6"
"source": "https://github.com/reactphp/child-process/tree/v0.6.7"
},
"funding": [
{
@@ -802,7 +802,7 @@
"type": "open_collective"
}
],
"time": "2025-01-01T16:37:48+00:00"
"time": "2025-12-23T15:25:20+00:00"
},
{
"name": "react/dns",
@@ -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

@@ -4,6 +4,7 @@ Over time, many people have contributed to Firefly III. Their efforts are not al
Please find below all the people who contributed to the Firefly III code. Their names are mentioned in the year of their first contribution.
## 2025
- Diego Algorta
- Jihad
- jreyesr
- codearena-bot

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

@@ -28,10 +28,10 @@ use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Jobs\SendWebhookMessage;
use FireflyIII\Models\Webhook;
use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface;
use FireflyIII\Support\Facades\FireflyConfig;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class SubmitController

View File

@@ -79,8 +79,8 @@ class UpdateRequest extends FormRequest
'start_date' => 'date|nullable',
'target_date' => 'date|nullable|after:start_date',
'notes' => 'max:65000',
'accounts' => 'required',
'accounts.*' => 'array|required',
'accounts' => 'array',
'accounts.*' => 'array',
'accounts.*.account_id' => ['required', 'numeric', 'belongsToUser:accounts,id'],
'accounts.*.current_amount' => ['numeric', 'nullable', new IsValidZeroOrMoreAmount(true)],
'object_group_id' => 'numeric|belongsToUser:object_groups,id',

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

@@ -37,17 +37,19 @@ class UpdateRequest extends FormRequest
use ChecksLogin;
use ConvertsDataTypes;
private array $booleans = ['configuration.is_demo_site', 'configuration.single_user_mode', 'configuration.enable_exchange_rates', 'configuration.use_running_balance', 'configuration.enable_external_map', 'configuration.enable_external_rates', 'configuration.allow_webhooks'];
private array $integers = ['configuration.permission_update_check', 'configuration.last_update_check'];
/**
* Get all data from the request.
*/
public function getAll(): array
{
$name = $this->route()->parameter('dynamicConfigKey');
if ('configuration.is_demo_site' === $name || 'configuration.single_user_mode' === $name) {
if (in_array($name, $this->booleans, true)) {
return ['value' => $this->boolean('value')];
}
if ('configuration.permission_update_check' === $name || 'configuration.last_update_check' === $name) {
if (in_array($name, $this->integers, true)) {
return ['value' => $this->convertInteger('value')];
}
@@ -61,13 +63,13 @@ class UpdateRequest extends FormRequest
{
$name = $this->route()->parameter('configName');
if ('configuration.is_demo_site' === $name || 'configuration.single_user_mode' === $name) {
if (in_array($name, $this->booleans, true)) {
return ['value' => ['required', new IsBoolean()]];
}
if ('configuration.permission_update_check' === $name) {
return ['value' => 'required|numeric|min:-1|max:1'];
}
if ('configuration.last_update_check' === $name) {
if (in_array($name, $this->integers, true)) {
return ['value' => 'required|numeric|min:464272080'];
}

View File

@@ -84,7 +84,7 @@ class CorrectsAmounts extends Command
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
$type = TransactionType::where('type', TransactionTypeEnum::TRANSFER->value)->first();
$journals = TransactionJournal::where('transaction_type_id', $type->id)->get();
$journals = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')->whereNotNull('transactions.foreign_amount')->where('transaction_journals.transaction_type_id', $type->id)->distinct()->get(['transaction_journals.*']);
/** @var TransactionJournal $journal */
foreach ($journals as $journal) {
@@ -93,7 +93,7 @@ class CorrectsAmounts extends Command
$valid = $this->validateJournal($journal);
if (false === $valid) {
Log::debug(sprintf('Journal #%d does not need to be fixed or is invalid (see previous messages)', $journal->id));
// Log::debug(sprintf('Journal #%d does not need to be fixed or is invalid (see previous messages)', $journal->id));
continue;
}
@@ -298,7 +298,7 @@ class CorrectsAmounts extends Command
return false;
}
if (null === $source->foreign_currency_id || null === $destination->foreign_currency_id) {
Log::debug('No foreign currency information is present, can safely continue with other transactions.');
// Log::debug('No foreign currency information is present, can safely continue with other transactions.');
return false;
}

View File

@@ -36,6 +36,7 @@ use Illuminate\Console\Command;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Symfony\Component\Console\Command\Command as CommandAlias;
use FireflyIII\Support\Facades\Amount;
class CorrectsCurrencies extends Command
{
@@ -63,7 +64,7 @@ class CorrectsCurrencies extends Command
$repos = app(CurrencyRepositoryInterface::class);
// first check if the user has any default currency (not necessarily the case, so can be forced).
$primaryCurrency = app('amount')->getPrimaryCurrencyByUserGroup($userGroup);
$primaryCurrency = Amount::getPrimaryCurrencyByUserGroup($userGroup);
Log::debug(sprintf('Now correcting currencies for user group #%d', $userGroup->id));
$found = [$primaryCurrency->id];

View File

@@ -35,6 +35,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use Illuminate\Console\Command;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use FireflyIII\Support\Facades\Amount;
class CorrectsOpeningBalanceCurrencies extends Command
{
@@ -133,6 +134,6 @@ class CorrectsOpeningBalanceCurrencies extends Command
$repos = app(AccountRepositoryInterface::class);
$repos->setUser($account->user);
return $repos->getAccountCurrency($account) ?? app('amount')->getPrimaryCurrencyByUserGroup($account->userGroup);
return $repos->getAccountCurrency($account) ?? Amount::getPrimaryCurrencyByUserGroup($account->userGroup);
}
}

View File

@@ -36,6 +36,7 @@ use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\User;
use Illuminate\Console\Command;
use FireflyIII\Support\Facades\FireflyConfig;
use FireflyIII\Support\Facades\Amount;
class UpgradesAccountCurrencies extends Command
{
@@ -105,7 +106,7 @@ class UpgradesAccountCurrencies extends Command
$accounts = $this->accountRepos->getAccountsByType([AccountTypeEnum::DEFAULT->value, AccountTypeEnum::ASSET->value]);
// get user's currency preference:
$primaryCurrency = app('amount')->getPrimaryCurrencyByUserGroup($user->userGroup);
$primaryCurrency = Amount::getPrimaryCurrencyByUserGroup($user->userGroup);
/** @var Account $account */
foreach ($accounts as $account) {

View File

@@ -31,6 +31,7 @@ use FireflyIII\Models\BudgetLimit;
use FireflyIII\User;
use Illuminate\Console\Command;
use FireflyIII\Support\Facades\FireflyConfig;
use FireflyIII\Support\Facades\Amount;
class UpgradesBudgetLimits extends Command
{
@@ -67,7 +68,7 @@ class UpgradesBudgetLimits extends Command
/** @var null|User $user */
$user = $budget->user;
if (null !== $user) {
$currency = app('amount')->getPrimaryCurrencyByUserGroup($user->userGroup);
$currency = Amount::getPrimaryCurrencyByUserGroup($user->userGroup);
$budgetLimit->transaction_currency_id = $currency->id;
$budgetLimit->save();
$this->friendlyInfo(

View File

@@ -32,6 +32,7 @@ use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use FireflyIII\Support\Facades\FireflyConfig;
use FireflyIII\Support\Facades\Amount;
class UpgradesMultiPiggyBanks extends Command
{
@@ -95,7 +96,7 @@ class UpgradesMultiPiggyBanks extends Command
$this->repository->setUser($piggyBank->account->user);
$this->accountRepository->setUser($piggyBank->account->user);
$repetition = $this->repository->getRepetition($piggyBank, true);
$currency = $this->accountRepository->getAccountCurrency($piggyBank->account) ?? app('amount')->getPrimaryCurrencyByUserGroup($piggyBank->account->user->userGroup);
$currency = $this->accountRepository->getAccountCurrency($piggyBank->account) ?? Amount::getPrimaryCurrencyByUserGroup($piggyBank->account->user->userGroup);
// update piggy bank to have a currency.
$piggyBank->transaction_currency_id = $currency->id;

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

@@ -32,6 +32,7 @@ use FireflyIII\Services\Internal\Support\BillServiceTrait;
use FireflyIII\User;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Log;
use FireflyIII\Support\Facades\Amount;
/**
* Class BillFactory
@@ -51,7 +52,7 @@ class BillFactory
Log::debug(sprintf('Now in %s', __METHOD__), $data);
$factory = app(TransactionCurrencyFactory::class);
$currency = $factory->find((int) ($data['currency_id'] ?? null), (string) ($data['currency_code'] ?? null))
?? app('amount')->getPrimaryCurrencyByUserGroup($this->user->userGroup);
?? Amount::getPrimaryCurrencyByUserGroup($this->user->userGroup);
try {
$skip = array_key_exists('skip', $data) ? $data['skip'] : 0;

View File

@@ -36,6 +36,7 @@ use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
use FireflyIII\User;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Log;
use FireflyIII\Support\Facades\Amount;
use function Safe\json_encode;
@@ -126,7 +127,7 @@ class PiggyBankFactory
private function getCurrency(array $data): TransactionCurrency
{
// currency:
$primaryCurrency = app('amount')->getPrimaryCurrency();
$primaryCurrency = Amount::getPrimaryCurrency();
$currency = null;
if (array_key_exists('transaction_currency_code', $data)) {
$currency = $this->currencyRepository->findByCode((string)($data['transaction_currency_code'] ?? ''));

View File

@@ -55,6 +55,7 @@ use FireflyIII\Validation\AccountValidator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use JsonException;
use FireflyIII\Support\Facades\Amount;
use function Safe\json_encode;
@@ -251,7 +252,7 @@ class TransactionJournalFactory
$foreignCurrency = $this->getForeignByAccount($type->type, $foreignCurrency, $destinationAccount);
$description = $this->getDescription($description);
Log::debug(sprintf('Currency is #%d "%s", foreign currency is #%d "%s"', $currency->id, $currency->code, $foreignCurrency?->id, $foreignCurrency));
Log::debug(sprintf('Currency is #%d "%s", foreign currency is #%d "%s"', $currency->id, $currency->code, $foreignCurrency?->id, $foreignCurrency?->code));
Log::debug(sprintf('Date: %s (%s)', $carbon->toW3cString(), $carbon->getTimezone()->getName()));
/** Create a basic journal. */
@@ -502,7 +503,7 @@ class TransactionJournalFactory
$preference = $this->accountRepository->getAccountCurrency($account);
if (null === $preference && !$currency instanceof TransactionCurrency) {
// return user's default:
return app('amount')->getPrimaryCurrencyByUserGroup($this->user->userGroup);
return Amount::getPrimaryCurrencyByUserGroup($this->user->userGroup);
}
$result = $preference ?? $currency;
Log::debug(sprintf('Currency is now #%d (%s) because of account #%d (%s)', $result->id, $result->code, $account->id, $account->name));

View File

@@ -51,7 +51,7 @@ class TransactionJournalMetaFactory
Log::debug('Is a carbon object.');
$value = $data['data']->toW3cString();
}
if ('' === (string) $value) {
if ('' === (string)$value) {
// Log::debug('Is an empty string.');
// don't store blank strings.
if (null !== $entry) {

View File

@@ -35,6 +35,7 @@ use FireflyIII\Support\Facades\Steam;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Throwable;
use FireflyIII\Support\Facades\Amount;
/**
* Class MonthReportGenerator.
@@ -144,7 +145,7 @@ class MonthReportGenerator implements ReportGeneratorInterface
$dayBeforeBalance = Steam::accountsBalancesOptimized(new Collection()->push($account), $date)[$account->id];
$startBalance = $dayBeforeBalance['balance'];
$primaryCurrency = app('amount')->getPrimaryCurrencyByUserGroup($account->user->userGroup);
$primaryCurrency = Amount::getPrimaryCurrencyByUserGroup($account->user->userGroup);
$currency = $accountRepository->getAccountCurrency($account) ?? $primaryCurrency;
foreach ($journals as $index => $journal) {

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

@@ -52,7 +52,7 @@ class AccountObserver
if (!Amount::convertToPrimary($account->user)) {
return;
}
$userCurrency = app('amount')->getPrimaryCurrencyByUserGroup($account->user->userGroup);
$userCurrency = Amount::getPrimaryCurrencyByUserGroup($account->user->userGroup);
$repository = app(AccountRepositoryInterface::class);
$currency = $repository->getAccountCurrency($account);
if (null !== $currency && $currency->id !== $userCurrency->id && '' !== (string) $account->virtual_balance && 0 !== bccomp($account->virtual_balance, '0')) {

View File

@@ -42,7 +42,7 @@ class AutoBudgetObserver
if (!Amount::convertToPrimary($autoBudget->budget->user)) {
return;
}
$userCurrency = app('amount')->getPrimaryCurrencyByUserGroup($autoBudget->budget->user->userGroup);
$userCurrency = Amount::getPrimaryCurrencyByUserGroup($autoBudget->budget->user->userGroup);
$autoBudget->native_amount = null;
if ($autoBudget->transactionCurrency->id !== $userCurrency->id) {
$converter = new ExchangeRateConverter();

View File

@@ -44,7 +44,7 @@ class AvailableBudgetObserver
return;
}
$userCurrency = app('amount')->getPrimaryCurrencyByUserGroup($availableBudget->user->userGroup);
$userCurrency = Amount::getPrimaryCurrencyByUserGroup($availableBudget->user->userGroup);
$availableBudget->native_amount = null;
if ($availableBudget->transactionCurrency->id !== $userCurrency->id) {
$converter = new ExchangeRateConverter();

View File

@@ -46,7 +46,7 @@ class BillObserver
if (!Amount::convertToPrimary($bill->user)) {
return;
}
$userCurrency = app('amount')->getPrimaryCurrencyByUserGroup($bill->user->userGroup);
$userCurrency = Amount::getPrimaryCurrencyByUserGroup($bill->user->userGroup);
$bill->native_amount_min = null;
$bill->native_amount_max = null;
if ($bill->transactionCurrency->id !== $userCurrency->id) {

View File

@@ -72,7 +72,7 @@ class BudgetLimitObserver
return;
}
$userCurrency = app('amount')->getPrimaryCurrencyByUserGroup($budgetLimit->budget->user->userGroup);
$userCurrency = Amount::getPrimaryCurrencyByUserGroup($budgetLimit->budget->user->userGroup);
$budgetLimit->native_amount = null;
if ($budgetLimit->transactionCurrency->id !== $userCurrency->id) {
$converter = new ExchangeRateConverter();

View File

@@ -48,7 +48,7 @@ class PiggyBankEventObserver
if (!Amount::convertToPrimary($user)) {
return;
}
$userCurrency = app('amount')->getPrimaryCurrencyByUserGroup($event->piggyBank->accounts()->first()->user->userGroup);
$userCurrency = Amount::getPrimaryCurrencyByUserGroup($event->piggyBank->accounts()->first()->user->userGroup);
$event->native_amount = null;
if ($event->piggyBank->transactionCurrency->id !== $userCurrency->id) {
$converter = new ExchangeRateConverter();

View File

@@ -29,6 +29,7 @@ use FireflyIII\Models\PiggyBank;
use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
use Illuminate\Support\Facades\Log;
use FireflyIII\Support\Facades\Amount;
/**
* Class PiggyBankObserver
@@ -49,7 +50,7 @@ class PiggyBankObserver
return;
}
$userCurrency = app('amount')->getPrimaryCurrencyByUserGroup($group);
$userCurrency = Amount::getPrimaryCurrencyByUserGroup($group);
$piggyBank->native_target_amount = null;
if ($piggyBank->transactionCurrency->id !== $userCurrency->id) {
$converter = new ExchangeRateConverter();

View File

@@ -24,11 +24,12 @@ declare(strict_types=1);
namespace FireflyIII\Handlers\Observer;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Facades\FireflyConfig;
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
use FireflyIII\Support\Models\AccountBalanceCalculator;
use Illuminate\Support\Facades\Log;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class TransactionObserver
@@ -42,7 +43,10 @@ class TransactionObserver
Log::debug('Observe "created" of a transaction.');
if (true === FireflyConfig::get('use_running_balance', config('firefly.feature_flags.running_balance_column'))->data && (1 === bccomp($transaction->amount, '0') && self::$recalculate)) {
Log::debug('Trigger recalculateForJournal');
AccountBalanceCalculator::recalculateForJournal($transaction->transactionJournal);
$journal = $transaction->transactionJournal;
if ($journal instanceof TransactionJournal) {
AccountBalanceCalculator::recalculateForJournal($journal);
}
}
$this->updatePrimaryCurrencyAmount($transaction);
}
@@ -52,11 +56,14 @@ class TransactionObserver
if (!Amount::convertToPrimary($transaction->transactionJournal->user)) {
return;
}
$userCurrency = app('amount')->getPrimaryCurrencyByUserGroup($transaction->transactionJournal->user->userGroup);
$userCurrency = Amount::getPrimaryCurrencyByUserGroup($transaction->transactionJournal->user->userGroup);
$transaction->native_amount = null;
$transaction->native_foreign_amount = null;
// first normal amount
if ($transaction->transactionCurrency->id !== $userCurrency->id && (null === $transaction->foreign_currency_id || (null !== $transaction->foreign_currency_id && $transaction->foreign_currency_id !== $userCurrency->id))) {
if ($transaction->transactionCurrency->id !== $userCurrency->id
&& (null === $transaction->foreign_currency_id
|| (null !== $transaction->foreign_currency_id
&& $transaction->foreign_currency_id !== $userCurrency->id))) {
$converter = new ExchangeRateConverter();
$converter->setUserGroup($transaction->transactionJournal->user->userGroup);
$converter->setIgnoreSettings(true);

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

@@ -45,6 +45,7 @@ use Illuminate\Routing\Redirector;
use Illuminate\Support\Collection;
use Illuminate\View\View;
use FireflyIII\Support\Facades\Steam;
use FireflyIII\Support\Facades\Amount;
/**
* Class BudgetLimitController
@@ -205,14 +206,14 @@ class BudgetLimitController extends Controller
// add some extra metadata:
$spentArr = $this->opsRepository->sumExpenses($limit->start_date, $limit->end_date, null, new Collection()->push($budget), $currency);
$array['spent'] = $spentArr[$currency->id]['sum'] ?? '0';
$array['left_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, bcadd($array['spent'], (string) $array['amount']));
$array['amount_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, $limit['amount']);
$array['left_formatted'] = Amount::formatAnything($limit->transactionCurrency, bcadd($array['spent'], (string) $array['amount']));
$array['amount_formatted'] = Amount::formatAnything($limit->transactionCurrency, $limit['amount']);
$array['days_left'] = (string) $this->activeDaysLeft($start, $end);
// left per day:
$array['left_per_day'] = 0 === bccomp('0', $array['days_left']) ? bcadd((string) $array['spent'], (string) $array['amount']) : bcdiv(bcadd((string) $array['spent'], (string) $array['amount']), $array['days_left']);
// left per day formatted.
$array['left_per_day_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, $array['left_per_day']);
$array['left_per_day_formatted'] = Amount::formatAnything($limit->transactionCurrency, $array['left_per_day']);
// notes:
$array['notes'] = $this->blRepository->getNoteText($limit);
@@ -239,8 +240,8 @@ class BudgetLimitController extends Controller
$this->blRepository->destroyBudgetLimit($budgetLimit);
$array = [
'budget_id' => $budgetId,
'left_formatted' => app('amount')->formatAnything($currency, '0'),
'left_per_day_formatted' => app('amount')->formatAnything($currency, '0'),
'left_formatted' => Amount::formatAnything($currency, '0'),
'left_per_day_formatted' => Amount::formatAnything($currency, '0'),
'transaction_currency_id' => $currency->id,
];
@@ -269,14 +270,14 @@ class BudgetLimitController extends Controller
);
$daysLeft = $this->activeDaysLeft($limit->start_date, $limit->end_date);
$array['spent'] = $spentArr[$budgetLimit->transactionCurrency->id]['sum'] ?? '0';
$array['left_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, bcadd($array['spent'], (string) $array['amount']));
$array['amount_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, $limit['amount']);
$array['left_formatted'] = Amount::formatAnything($limit->transactionCurrency, bcadd($array['spent'], (string) $array['amount']));
$array['amount_formatted'] = Amount::formatAnything($limit->transactionCurrency, $limit['amount']);
$array['days_left'] = (string) $daysLeft;
$array['left_per_day'] = 0 === $daysLeft ? bcadd((string) $array['spent'], (string) $array['amount']) : bcdiv(bcadd((string) $array['spent'], (string) $array['amount']), $array['days_left']);
// left per day formatted.
$array['amount'] = Steam::bcround($limit['amount'], $limit->transactionCurrency->decimal_places);
$array['left_per_day_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, $array['left_per_day']);
$array['left_per_day_formatted'] = Amount::formatAnything($limit->transactionCurrency, $array['left_per_day']);
if ('true' === $request->get('redirect')) {
return redirect(route('budgets.index'));
}

View File

@@ -37,6 +37,7 @@ use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use FireflyIII\Support\Facades\Amount;
/**
* Class JavascriptController.
@@ -106,7 +107,7 @@ class JavascriptController extends Controller
$currency = $repository->getAccountCurrency($account) ?? $this->primaryCurrency;
}
$locale = Steam::getLocale();
$accounting = app('amount')->getJsConfig();
$accounting = Amount::getJsConfig();
$accounting['frac_digits'] = $currency->decimal_places;
$pref = Preferences::get('language', config('firefly.default_language', 'en_US'));
$lang = $pref->data;

View File

@@ -121,15 +121,15 @@ class BoxController extends Controller
$keys = array_keys($sums);
foreach ($keys as $currencyId) {
$currency = $repository->find($currencyId);
$sums[$currencyId] = app('amount')->formatAnything($currency, $sums[$currencyId], false);
$incomes[$currencyId] = app('amount')->formatAnything($currency, $incomes[$currencyId] ?? '0', false);
$expenses[$currencyId] = app('amount')->formatAnything($currency, $expenses[$currencyId] ?? '0', false);
$sums[$currencyId] = Amount::formatAnything($currency, $sums[$currencyId], false);
$incomes[$currencyId] = Amount::formatAnything($currency, $incomes[$currencyId] ?? '0', false);
$expenses[$currencyId] = Amount::formatAnything($currency, $expenses[$currencyId] ?? '0', false);
}
if (0 === count($sums)) {
$currency = $this->primaryCurrency;
$sums[$this->primaryCurrency->id] = app('amount')->formatAnything($this->primaryCurrency, '0', false);
$incomes[$this->primaryCurrency->id] = app('amount')->formatAnything($this->primaryCurrency, '0', false);
$expenses[$this->primaryCurrency->id] = app('amount')->formatAnything($this->primaryCurrency, '0', false);
$sums[$this->primaryCurrency->id] = Amount::formatAnything($this->primaryCurrency, '0', false);
$incomes[$this->primaryCurrency->id] = Amount::formatAnything($this->primaryCurrency, '0', false);
$expenses[$this->primaryCurrency->id] = Amount::formatAnything($this->primaryCurrency, '0', false);
}
$response = [
@@ -187,7 +187,7 @@ class BoxController extends Controller
if ('primary' === $key) {
continue;
}
$return[$data['currency_id']] = app('amount')->formatFlat($data['currency_symbol'], $data['currency_decimal_places'], $data['balance'], false);
$return[$data['currency_id']] = Amount::formatFlat($data['currency_symbol'], $data['currency_decimal_places'], $data['balance'], false);
}
$return = [
'net_worths' => array_values($return),

View File

@@ -33,6 +33,7 @@ use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Support\Http\Controllers\DateCalculation;
use Illuminate\Http\JsonResponse;
use FireflyIII\Support\Facades\Amount;
/**
* Class BudgetController
@@ -84,9 +85,9 @@ class BudgetController extends Controller
return response()->json(
[
'budgeted' => $budgeted,
'budgeted_formatted' => app('amount')->formatAnything($currency, $budgeted, true),
'budgeted_formatted' => Amount::formatAnything($currency, $budgeted, true),
'available' => $available,
'available_formatted' => app('amount')->formatAnything($currency, $available, true),
'available_formatted' => Amount::formatAnything($currency, $available, true),
'percentage' => $percentage,
'currency_id' => $currency->id,
'currency_code' => $currency->code,

View File

@@ -212,6 +212,13 @@ class ReconcileController extends Controller
$startBalance = Steam::accountsBalancesOptimized(new Collection()->push($account), $startDate)[$account->id];
$endBalance = Steam::accountsBalancesOptimized(new Collection()->push($account), $end)[$account->id];
// round balances.
foreach ($startBalance as $key => $value) {
$startBalance[$key] = Steam::bcround($value, $currency->decimal_places);
}
foreach ($endBalance as $key => $value) {
$endBalance[$key] = Steam::bcround($value, $currency->decimal_places);
}
// get the transactions

View File

@@ -35,6 +35,7 @@ use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
use FireflyIII\Support\Facades\Amount;
/**
* Class AmountController
@@ -167,7 +168,7 @@ class AmountController extends Controller
$piggyBank->refresh();
}
if (0 !== bccomp($total, '0')) {
session()->flash('success', (string) trans('firefly.added_amount_to_piggy', ['amount' => app('amount')->formatAnything($piggyBank->transactionCurrency, $total, false), 'name' => $piggyBank->name]));
session()->flash('success', (string) trans('firefly.added_amount_to_piggy', ['amount' => Amount::formatAnything($piggyBank->transactionCurrency, $total, false), 'name' => $piggyBank->name]));
Preferences::mark();
return redirect(route('piggy-banks.index'));
@@ -177,7 +178,7 @@ class AmountController extends Controller
'error',
(string) trans(
'firefly.cannot_add_amount_piggy',
['amount' => app('amount')->formatAnything($piggyBank->transactionCurrency, $total, false), 'name' => e($piggyBank->name)]
['amount' => Amount::formatAnything($piggyBank->transactionCurrency, $total, false), 'name' => e($piggyBank->name)]
)
);
@@ -214,7 +215,7 @@ class AmountController extends Controller
'success',
(string) trans(
'firefly.removed_amount_from_piggy',
['amount' => app('amount')->formatAnything($piggyBank->transactionCurrency, $total, false), 'name' => $piggyBank->name]
['amount' => Amount::formatAnything($piggyBank->transactionCurrency, $total, false), 'name' => $piggyBank->name]
)
);
Preferences::mark();
@@ -226,7 +227,7 @@ class AmountController extends Controller
'error',
(string) trans(
'firefly.cannot_remove_from_piggy',
['amount' => app('amount')->formatAnything($piggyBank->transactionCurrency, $total, false), 'name' => e($piggyBank->name)]
['amount' => Amount::formatAnything($piggyBank->transactionCurrency, $total, false), 'name' => e($piggyBank->name)]
)
);

View File

@@ -23,7 +23,6 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers;
use FireflyIII\Support\Facades\Navigation;
use Carbon\Carbon;
use FireflyIII\Enums\AccountTypeEnum;
use FireflyIII\Events\Preferences\UserGroupChangedPrimaryCurrency;
@@ -33,7 +32,9 @@ use FireflyIII\Http\Requests\PreferencesRequest;
use FireflyIII\Models\Account;
use FireflyIII\Models\Preference;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Support\Facades\Navigation;
use FireflyIII\Support\Facades\Preferences;
use FireflyIII\Support\Facades\Steam;
use FireflyIII\Support\Singleton\PreferencesSingleton;
use FireflyIII\User;
use Illuminate\Contracts\View\Factory;
@@ -44,7 +45,6 @@ use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
use JsonException;
use Safe\Exceptions\FilesystemException;
use FireflyIII\Support\Facades\Steam;
use function Safe\file_get_contents;
use function Safe\json_decode;
@@ -63,7 +63,7 @@ class PreferencesController extends Controller
$this->middleware(
static function ($request, $next) {
app('view')->share('title', (string) trans('firefly.preferences'));
app('view')->share('title', (string)trans('firefly.preferences'));
app('view')->share('mainTitleIcon', 'fa-gear');
return $next($request);
@@ -87,8 +87,8 @@ class PreferencesController extends Controller
/** @var Account $account */
foreach ($accounts as $account) {
$type = $account->accountType->type;
$role = sprintf('opt_group_%s', $repository->getMetaValue($account, 'account_role'));
$type = $account->accountType->type;
$role = sprintf('opt_group_%s', $repository->getMetaValue($account, 'account_role'));
if (in_array($type, [AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::LOAN->value], true)) {
$role = sprintf('opt_group_l_%s', $type);
@@ -97,7 +97,7 @@ class PreferencesController extends Controller
if ('opt_group_' === $role) {
$role = 'opt_group_defaultAsset';
}
$groupedAccounts[(string) trans(sprintf('firefly.%s', $role))][$account->id] = $account->name;
$groupedAccounts[(string)trans(sprintf('firefly.%s', $role))][$account->id] = $account->name;
}
ksort($groupedAccounts);
@@ -120,21 +120,22 @@ class PreferencesController extends Controller
if (is_array($fiscalYearStartStr)) {
$fiscalYearStartStr = '01-01';
}
$fiscalYearStart = sprintf('%s-%s', Carbon::now()->format('Y'), (string) $fiscalYearStartStr);
$fiscalYearStart = sprintf('%s-%s', Carbon::now()->format('Y'), (string)$fiscalYearStartStr);
$tjOptionalFields = Preferences::get('transaction_journal_optional_fields', [])->data;
$availableDarkModes = config('firefly.available_dark_modes');
// notifications settings
$slackUrl = Preferences::getEncrypted('slack_webhook_url', '')->data;
$pushoverAppToken = (string) Preferences::getEncrypted('pushover_app_token', '')->data;
$pushoverUserToken = (string) Preferences::getEncrypted('pushover_user_token', '')->data;
$pushoverAppToken = (string)Preferences::getEncrypted('pushover_app_token', '')->data;
$pushoverUserToken = (string)Preferences::getEncrypted('pushover_user_token', '')->data;
$ntfyServer = Preferences::getEncrypted('ntfy_server', 'https://ntfy.sh')->data;
$ntfyTopic = (string) Preferences::getEncrypted('ntfy_topic', '')->data;
$ntfyTopic = (string)Preferences::getEncrypted('ntfy_topic', '')->data;
$ntfyAuth = '1' === Preferences::get('ntfy_auth', false)->data;
$ntfyUser = Preferences::getEncrypted('ntfy_user', '')->data;
$ntfyPass = (string) Preferences::getEncrypted('ntfy_pass', '')->data;
$ntfyPass = (string)Preferences::getEncrypted('ntfy_pass', '')->data;
$channels = config('notifications.channels');
$forcedAvailability = [];
$anonymous = Steam::anonymous();
// notification preferences
$notifications = [];
@@ -164,7 +165,7 @@ class PreferencesController extends Controller
Log::error($e->getMessage());
$locales = [];
}
$locales = ['equal' => (string) trans('firefly.equal_to_language')] + $locales;
$locales = ['equal' => (string)trans('firefly.equal_to_language')] + $locales;
// an important fallback is that the frontPageAccount array gets refilled automatically
// when it turns up empty.
if (0 === count($frontpageAccounts)) {
@@ -184,7 +185,7 @@ class PreferencesController extends Controller
$ntfyPass = '';
}
return view('preferences.index', ['language' => $language, 'pushoverAppToken' => $pushoverAppToken, 'pushoverUserToken' => $pushoverUserToken, 'ntfyServer' => $ntfyServer, 'ntfyTopic' => $ntfyTopic, 'ntfyAuth' => $ntfyAuth, 'channels' => $channels, 'ntfyUser' => $ntfyUser, 'forcedAvailability' => $forcedAvailability, 'ntfyPass' => $ntfyPass, 'groupedAccounts' => $groupedAccounts, 'isDocker' => $isDocker, 'frontpageAccounts' => $frontpageAccounts, 'languages' => $languages, 'darkMode' => $darkMode, 'availableDarkModes' => $availableDarkModes, 'notifications' => $notifications, 'convertToPrimary' => $convertToPrimary, 'slackUrl' => $slackUrl, 'locales' => $locales, 'locale' => $locale, 'tjOptionalFields' => $tjOptionalFields, 'viewRange' => $viewRange, 'customFiscalYear' => $customFiscalYear, 'listPageSize' => $listPageSize, 'fiscalYearStart' => $fiscalYearStart]);
return view('preferences.index', ['anonymous' => $anonymous, 'language' => $language, 'pushoverAppToken' => $pushoverAppToken, 'pushoverUserToken' => $pushoverUserToken, 'ntfyServer' => $ntfyServer, 'ntfyTopic' => $ntfyTopic, 'ntfyAuth' => $ntfyAuth, 'channels' => $channels, 'ntfyUser' => $ntfyUser, 'forcedAvailability' => $forcedAvailability, 'ntfyPass' => $ntfyPass, 'groupedAccounts' => $groupedAccounts, 'isDocker' => $isDocker, 'frontpageAccounts' => $frontpageAccounts, 'languages' => $languages, 'darkMode' => $darkMode, 'availableDarkModes' => $availableDarkModes, 'notifications' => $notifications, 'convertToPrimary' => $convertToPrimary, 'slackUrl' => $slackUrl, 'locales' => $locales, 'locale' => $locale, 'tjOptionalFields' => $tjOptionalFields, 'viewRange' => $viewRange, 'customFiscalYear' => $customFiscalYear, 'listPageSize' => $listPageSize, 'fiscalYearStart' => $fiscalYearStart]);
}
/**
@@ -201,7 +202,7 @@ class PreferencesController extends Controller
$frontpageAccounts = [];
if (is_array($request->get('frontpageAccounts')) && count($request->get('frontpageAccounts')) > 0) {
foreach ($request->get('frontpageAccounts') as $id) {
$frontpageAccounts[] = (int) $id;
$frontpageAccounts[] = (int)$id;
}
Preferences::set('frontpageAccounts', $frontpageAccounts);
}
@@ -241,7 +242,7 @@ class PreferencesController extends Controller
}
// convert primary
$convertToPrimary = 1 === (int) $request->get('convertToPrimary');
$convertToPrimary = 1 === (int)$request->get('convertToPrimary');
if ($convertToPrimary && !$this->convertToPrimary) {
// set to true!
Log::debug('User sets convertToPrimary to true.');
@@ -253,9 +254,9 @@ class PreferencesController extends Controller
Preferences::set('convert_to_primary', $convertToPrimary);
// custom fiscal year
$customFiscalYear = 1 === (int) $request->get('customFiscalYear');
$customFiscalYear = 1 === (int)$request->get('customFiscalYear');
Preferences::set('customFiscalYear', $customFiscalYear);
$fiscalYearString = (string) $request->get('fiscalYearStart');
$fiscalYearString = (string)$request->get('fiscalYearStart');
if ('' !== $fiscalYearString) {
$fiscalYearStart = Carbon::parse($fiscalYearString, config('app.timezone'))->format('m-d');
Preferences::set('fiscalYearStart', $fiscalYearStart);
@@ -263,7 +264,7 @@ class PreferencesController extends Controller
// save page size:
Preferences::set('listPageSize', 50);
$listPageSize = (int) $request->get('listPageSize');
$listPageSize = (int)$request->get('listPageSize');
if ($listPageSize > 0 && $listPageSize < 1337) {
Preferences::set('listPageSize', $listPageSize);
}
@@ -282,7 +283,7 @@ class PreferencesController extends Controller
// same for locale:
if (!auth()->user()->hasRole('demo')) {
$locale = (string) $request->get('locale');
$locale = (string)$request->get('locale');
$locale = '' === $locale ? null : $locale;
Preferences::set('locale', $locale);
}
@@ -311,7 +312,12 @@ class PreferencesController extends Controller
Preferences::set('darkMode', $darkMode);
}
session()->flash('success', (string) trans('firefly.saved_preferences'));
// anonymous amounts?
$anonymous = '1' === $request->get('anonymous');
Preferences::set('anonymous', $anonymous);
// save and continue
session()->flash('success', (string)trans('firefly.saved_preferences'));
Preferences::mark();
return redirect(route('preferences.index'));
@@ -325,7 +331,7 @@ class PreferencesController extends Controller
switch ($channel) {
default:
session()->flash('error', (string) trans('firefly.notification_test_failed', ['channel' => $channel]));
session()->flash('error', (string)trans('firefly.notification_test_failed', ['channel' => $channel]));
break;
@@ -337,7 +343,7 @@ class PreferencesController extends Controller
$user = auth()->user();
Log::debug(sprintf('Now in testNotification("%s") controller.', $channel));
event(new UserTestNotificationChannel($channel, $user));
session()->flash('success', (string) trans('firefly.notification_test_executed', ['channel' => $channel]));
session()->flash('success', (string)trans('firefly.notification_test_executed', ['channel' => $channel]));
}
return '';

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

@@ -31,6 +31,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use FireflyIII\Support\Facades\Amount;
class TransactionCurrency extends Model
{
@@ -65,7 +66,7 @@ class TransactionCurrency extends Model
public function refreshForUser(User $user): void
{
$current = $user->userGroup->currencies()->where('transaction_currencies.id', $this->id)->first();
$native = app('amount')->getPrimaryCurrencyByUserGroup($user->userGroup);
$native = Amount::getPrimaryCurrencyByUserGroup($user->userGroup);
$this->userGroupNative = $native->id === $this->id;
$this->userGroupEnabled = null !== $current;
}

View File

@@ -353,7 +353,7 @@ class AccountRepository implements AccountRepositoryInterface, UserGroupInterfac
if (AccountTypeEnum::ASSET->value !== $account->accountType->type) {
throw new FireflyException(sprintf('%s is not an asset account.', $account->name));
}
$currency = $this->getAccountCurrency($account) ?? app('amount')->getPrimaryCurrency();
$currency = $this->getAccountCurrency($account) ?? Amount::getPrimaryCurrency();
$name = trans('firefly.reconciliation_account_name', ['name' => $account->name, 'currency' => $currency->code]);
/** @var AccountType $type */

View File

@@ -34,6 +34,7 @@ use FireflyIII\Support\Repositories\UserGroup\UserGroupInterface;
use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use FireflyIII\Support\Facades\Amount;
/**
* Class AccountTasker.
@@ -59,7 +60,7 @@ class AccountTasker implements AccountTaskerInterface, UserGroupInterface
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
$primaryCurrency = app('amount')->getPrimaryCurrencyByUserGroup($this->user->userGroup);
$primaryCurrency = Amount::getPrimaryCurrencyByUserGroup($this->user->userGroup);
$return = [
'accounts' => [],
@@ -146,7 +147,7 @@ class AccountTasker implements AccountTaskerInterface, UserGroupInterface
private function groupExpenseByDestination(array $array): array
{
$primaryCurrency = app('amount')->getPrimaryCurrencyByUserGroup($this->user->userGroup);
$primaryCurrency = Amount::getPrimaryCurrencyByUserGroup($this->user->userGroup);
/** @var CurrencyRepositoryInterface $currencyRepos */
$currencyRepos = app(CurrencyRepositoryInterface::class);
@@ -231,7 +232,7 @@ class AccountTasker implements AccountTaskerInterface, UserGroupInterface
private function groupIncomeBySource(array $array): array
{
$primaryCurrency = app('amount')->getPrimaryCurrencyByUserGroup($this->user->userGroup);
$primaryCurrency = Amount::getPrimaryCurrencyByUserGroup($this->user->userGroup);
/** @var CurrencyRepositoryInterface $currencyRepos */
$currencyRepos = app(CurrencyRepositoryInterface::class);

View File

@@ -27,8 +27,6 @@ use FireflyIII\Enums\UserRoleEnum;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Attachment;
use FireflyIII\Models\UserGroup;
use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Collection;
/**
@@ -38,7 +36,6 @@ use Illuminate\Support\Collection;
* @method getUserGroup()
* @method getUser()
* @method checkUserGroupAccess(UserRoleEnum $role)
* @method setUser(null|Authenticatable|User $user)
* @method setUserGroupById(int $userGroupId)
*/
interface AttachmentRepositoryInterface

View File

@@ -536,7 +536,7 @@ class BillRepository implements BillRepositoryInterface, UserGroupInterface
$bills = $this->getActiveBills();
$return = [];
$convertToPrimary = Amount::convertToPrimary($this->user);
$primary = app('amount')->getPrimaryCurrency();
$primary = Amount::getPrimaryCurrency();
/** @var Bill $bill */
foreach ($bills as $bill) {
@@ -602,7 +602,7 @@ class BillRepository implements BillRepositoryInterface, UserGroupInterface
$bills = $this->getActiveBills();
$return = [];
$convertToPrimary = Amount::convertToPrimary($this->user);
$primary = app('amount')->getPrimaryCurrency();
$primary = Amount::getPrimaryCurrency();
/** @var Bill $bill */
foreach ($bills as $bill) {

View File

@@ -51,6 +51,7 @@ use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use FireflyIII\Support\Facades\Amount;
/**
* Class BudgetRepository.
@@ -94,7 +95,7 @@ class BudgetRepository implements BudgetRepositoryInterface, UserGroupInterface
$limitRepository = app(BudgetLimitRepository::class);
$limitRepository->setUser($this->user);
$budgets = $this->getActiveBudgets();
$primaryCurrency = app('amount')->getPrimaryCurrency();
$primaryCurrency = Amount::getPrimaryCurrency();
$converter = new ExchangeRateConverter();
/** @var Budget $budget */
@@ -393,7 +394,7 @@ class BudgetRepository implements BudgetRepositoryInterface, UserGroupInterface
$autoBudget = $this->getAutoBudget($budget);
// grab default currency:
$currency = app('amount')->getPrimaryCurrencyByUserGroup($this->user->userGroup);
$currency = Amount::getPrimaryCurrencyByUserGroup($this->user->userGroup);
if (!$autoBudget instanceof AutoBudget) {
// at this point it's a blind assumption auto_budget_type is 1 or 2.
@@ -778,7 +779,7 @@ class BudgetRepository implements BudgetRepositoryInterface, UserGroupInterface
$currency = $repos->findByCode((string) $data['currency_code']);
}
if (null === $currency) {
$currency = app('amount')->getPrimaryCurrencyByUserGroup($this->user->userGroup);
$currency = Amount::getPrimaryCurrencyByUserGroup($this->user->userGroup);
}
$autoBudget = new AutoBudget();

View File

@@ -242,7 +242,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface, UserGroupInterf
Log::debug('Grabbing default currency for this user...');
/** @var null|TransactionCurrency $result */
$result = app('amount')->getPrimaryCurrencyByUserGroup($this->user->userGroup);
$result = Amount::getPrimaryCurrencyByUserGroup($this->user->userGroup);
}
Log::debug(sprintf('Final result: %s', $result->code));
@@ -260,22 +260,28 @@ class CurrencyRepository implements CurrencyRepositoryInterface, UserGroupInterf
public function findCurrencyNull(?int $currencyId, ?string $currencyCode): ?TransactionCurrency
{
Log::debug(sprintf('Now in findCurrencyNull(%s, "%s")', var_export($currencyId, true), $currencyCode));
$result = $this->find((int)$currencyId);
if ($result instanceof TransactionCurrency) {
Log::debug(sprintf('Found currency by ID: %s', $result->code));
if (null !== $currencyId && 0 !== $currencyId) {
$result = $this->find((int)$currencyId);
if ($result instanceof TransactionCurrency) {
Log::debug(sprintf('Found currency by ID: %s', $result->code));
return $result;
}
}
if (null !== $currencyCode && '' !== $currencyCode) {
Log::debug(sprintf('Searching for currency with code "%s"...', $currencyCode));
$result = $this->findByCode($currencyCode);
if ($result instanceof TransactionCurrency && false === $result->enabled) {
Log::debug(sprintf('Also enabled currency %s', $result->code));
$this->enable($result);
}
return $result;
}
Log::debug(sprintf('Searching for currency with code "%s"...', $currencyCode));
$result = $this->findByCode((string)$currencyCode);
if ($result instanceof TransactionCurrency && false === $result->enabled) {
Log::debug(sprintf('Also enabled currency %s', $result->code));
$this->enable($result);
}
Log::debug('Found no currency, returning NULL.');
return $result;
return null;
}
#[Override]
@@ -438,7 +444,7 @@ class CurrencyRepository implements CurrencyRepositoryInterface, UserGroupInterf
public function makePrimary(TransactionCurrency $currency): void
{
$current = app('amount')->getPrimaryCurrencyByUserGroup($this->userGroup);
$current = Amount::getPrimaryCurrencyByUserGroup($this->userGroup);
Log::debug(sprintf('Enabled + made default currency %s for user #%d', $currency->code, $this->userGroup->id));
$this->userGroup->currencies()->detach($currency->id);
foreach ($this->userGroup->currencies()->get() as $item) {

View File

@@ -72,7 +72,7 @@ trait ModifiesPiggyBanks
$pivot->native_current_amount = null;
// also update native_current_amount.
$userCurrency = app('amount')->getPrimaryCurrencyByUserGroup($this->user->userGroup);
$userCurrency = Amount::getPrimaryCurrencyByUserGroup($this->user->userGroup);
if ($userCurrency->id !== $piggyBank->transaction_currency_id) {
$converter = new ExchangeRateConverter();
$converter->setIgnoreSettings(true);
@@ -95,7 +95,7 @@ trait ModifiesPiggyBanks
$pivot->native_current_amount = null;
// also update native_current_amount.
$userCurrency = app('amount')->getPrimaryCurrencyByUserGroup($this->user->userGroup);
$userCurrency = Amount::getPrimaryCurrencyByUserGroup($this->user->userGroup);
if ($userCurrency->id !== $piggyBank->transaction_currency_id) {
$converter = new ExchangeRateConverter();
$converter->setIgnoreSettings(true);

View File

@@ -44,6 +44,7 @@ use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Override;
use FireflyIII\Support\Facades\Amount;
/**
* Class PiggyBankRepository.
@@ -171,7 +172,7 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface, UserGroupInte
$accountRepos = app(AccountRepositoryInterface::class);
$accountRepos->setUser($this->user);
$primaryCurrency = app('amount')->getPrimaryCurrencyByUserGroup($this->user->userGroup);
$primaryCurrency = Amount::getPrimaryCurrencyByUserGroup($this->user->userGroup);
Log::debug(sprintf('Piggy bank #%d currency is %s', $piggyBank->id, $piggyBank->transactionCurrency->code));
@@ -302,7 +303,7 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface, UserGroupInte
/** @var PiggyBank $piggy */
foreach ($set as $piggy) {
$currentAmount = $this->getCurrentAmount($piggy);
$piggy->name = sprintf('%s (%s)', $piggy->name, app('amount')->formatAnything($piggy->transactionCurrency, $currentAmount, false));
$piggy->name = sprintf('%s (%s)', $piggy->name, Amount::formatAnything($piggy->transactionCurrency, $currentAmount, false));
}
return $set;

View File

@@ -44,6 +44,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Services\Internal\Destroy\TransactionGroupDestroyService;
use Illuminate\Support\Facades\Validator;
use FireflyIII\Support\Facades\Steam;
use FireflyIII\Support\Facades\Amount;
/**
* Trait AccountServiceTrait
@@ -231,7 +232,7 @@ trait AccountServiceTrait
// get or grab currency:
$currency = $this->accountRepository->getAccountCurrency($account);
if (null === $currency) {
$currency = app('amount')->getPrimaryCurrencyByUserGroup($account->user->userGroup);
$currency = Amount::getPrimaryCurrencyByUserGroup($account->user->userGroup);
}
// submit to factory:
@@ -348,7 +349,7 @@ trait AccountServiceTrait
if (null === $currency) {
// use default currency:
$currency = app('amount')->getPrimaryCurrencyByUserGroup($this->user->userGroup);
$currency = Amount::getPrimaryCurrencyByUserGroup($this->user->userGroup);
}
$currency->enabled = true;
$currency->save();
@@ -388,7 +389,7 @@ trait AccountServiceTrait
// if exists, update:
$currency = $this->accountRepository->getAccountCurrency($account);
if (null === $currency) {
$currency = app('amount')->getPrimaryCurrencyByUserGroup($account->user->userGroup);
$currency = Amount::getPrimaryCurrencyByUserGroup($account->user->userGroup);
}
// simply grab the first journal and change it:
@@ -454,7 +455,7 @@ trait AccountServiceTrait
// get or grab currency:
$currency = $this->accountRepository->getAccountCurrency($account);
if (null === $currency) {
$currency = app('amount')->getPrimaryCurrencyByUserGroup($account->user->userGroup);
$currency = Amount::getPrimaryCurrencyByUserGroup($account->user->userGroup);
}
// submit to factory:
$submission = [
@@ -571,7 +572,7 @@ trait AccountServiceTrait
// if exists, update:
$currency = $this->accountRepository->getAccountCurrency($account);
if (null === $currency) {
$currency = app('amount')->getPrimaryCurrencyByUserGroup($account->user->userGroup);
$currency = Amount::getPrimaryCurrencyByUserGroup($account->user->userGroup);
}
// simply grab the first journal and change it:
@@ -652,7 +653,7 @@ trait AccountServiceTrait
// get or grab currency:
$currency = $this->accountRepository->getAccountCurrency($account);
if (null === $currency) {
$currency = app('amount')->getPrimaryCurrencyByUserGroup($account->user->userGroup);
$currency = Amount::getPrimaryCurrencyByUserGroup($account->user->userGroup);
}
// submit to factory:

View File

@@ -42,6 +42,7 @@ use FireflyIII\Models\RecurrenceTransactionMeta;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Validation\AccountValidator;
use Illuminate\Support\Facades\Log;
use FireflyIII\Support\Facades\Amount;
use function Safe\json_encode;
@@ -107,7 +108,7 @@ trait RecurringTransactionTrait
$currency = $factory->find($array['currency_id'] ?? null, $array['currency_code'] ?? null);
$foreignCurrency = $factory->find($array['foreign_currency_id'] ?? null, $array['foreign_currency_code'] ?? null);
if (null === $currency) {
$currency = app('amount')->getPrimaryCurrencyByUserGroup($recurrence->user->userGroup);
$currency = Amount::getPrimaryCurrencyByUserGroup($recurrence->user->userGroup);
}
Log::debug(

View File

@@ -35,6 +35,7 @@ use FireflyIII\Repositories\ObjectGroup\CreatesObjectGroups;
use FireflyIII\Services\Internal\Support\BillServiceTrait;
use FireflyIII\User;
use Illuminate\Support\Collection;
use FireflyIII\Support\Facades\Amount;
/**
* Class BillUpdateService
@@ -53,7 +54,7 @@ class BillUpdateService
if (array_key_exists('currency_id', $data) || array_key_exists('currency_code', $data)) {
$factory = app(TransactionCurrencyFactory::class);
$currency = $factory->find((int) ($data['currency_id'] ?? null), $data['currency_code'] ?? null)
?? app('amount')->getPrimaryCurrencyByUserGroup($bill->user->userGroup);
?? Amount::getPrimaryCurrencyByUserGroup($bill->user->userGroup);
// enable the currency if it isn't.
$currency->enabled = true;

View File

@@ -68,8 +68,7 @@ class JournalUpdateService
private ?Account $destinationAccount = null;
private ?Transaction $destinationTransaction = null;
private array $metaDate
= ['interest_date', 'book_date', 'process_date', 'due_date', 'payment_date',
'invoice_date', ];
= ['interest_date', 'book_date', 'process_date', 'due_date', 'payment_date', 'invoice_date', '_internal_previous_date'];
private array $metaString
= [
'sepa_cc',
@@ -205,11 +204,9 @@ class JournalUpdateService
$validator->setUser($this->transactionJournal->user);
$result = $validator->validateSource(['id' => $sourceId, 'name' => $sourceName]);
Log::debug(
sprintf('hasValidSourceAccount(%d, "%s") will return %s', $sourceId, $sourceName, var_export($result, true))
);
Log::debug(sprintf('hasValidSourceAccount(%d, "%s") will return %s', $sourceId, $sourceName, var_export($result, true)));
// TODO typeoverrule the account validator may have a different opinion on the transaction type.
// TODO type overrule the account validator may have a different opinion on the transaction type.
// validate submitted info:
return $result;
@@ -283,14 +280,7 @@ class JournalUpdateService
$validator->setUser($this->transactionJournal->user);
$validator->source = $this->getValidSourceAccount();
$result = $validator->validateDestination(['id' => $destId, 'name' => $destName]);
Log::debug(
sprintf(
'hasValidDestinationAccount(%d, "%s") will return %s',
$destId,
$destName,
var_export($result, true)
)
);
Log::debug(sprintf('hasValidDestinationAccount(%d, "%s") will return %s', $destId, $destName, var_export($result, true)));
// TODO typeOverrule: the account validator may have another opinion on the transaction type.
@@ -494,6 +484,24 @@ class JournalUpdateService
// do some parsing.
Log::debug(sprintf('Create date value from string "%s".', $value));
$this->transactionJournal->date_tz = $value->format('e');
$res = $value->gt($this->transactionJournal->date);
Log::debug(sprintf('Old date: %s, new date: %s', $this->transactionJournal->date->toW3cString(), $value->toW3cString()));
/** @var TransactionJournalMetaFactory $factory */
$factory = app(TransactionJournalMetaFactory::class);
$set = [
'journal' => $this->transactionJournal,
'name' => '_internal_previous_date',
'data' => null,
];
if ($res) {
Log::debug('Transaction is set to be AFTER its current date. Save also the "_internal_previous_date"-field.');
$set['data'] = clone $this->transactionJournal->date;
}
if (!$res) {
Log::debug('Transaction is NOT set to be AFTER its current date. Remove the "_internal_previous_date"-field.');
}
$factory->updateOrCreate($set);
}
event(new TriggeredAuditLog($this->transactionJournal->user, $this->transactionJournal, sprintf('update_%s', $fieldName), $this->transactionJournal->{$fieldName}, $value));
@@ -652,7 +660,7 @@ class JournalUpdateService
}
$value = $this->data['amount'] ?? '';
Log::debug(sprintf('Amount is now "%s"', $value));
Log::debug(sprintf('[a] Amount is now "%s"', $value));
try {
$amount = $this->getAmount($value);
@@ -661,15 +669,18 @@ class JournalUpdateService
return;
}
Log::debug(sprintf('[b] Amount is now "%s"', $value));
$origSourceTransaction = $this->getSourceTransaction();
$destTransaction = $this->getDestinationTransaction();
$originalSourceAmount = $origSourceTransaction->amount;
$originalDestAmount = $destTransaction->amount;
$origSourceTransaction->amount = Steam::negative($amount);
$origSourceTransaction->balance_dirty = true;
$origSourceTransaction->save();
$destTransaction = $this->getDestinationTransaction();
$originalAmount = $destTransaction->amount;
$destTransaction->amount = Steam::positive($amount);
$destTransaction->balance_dirty = true;
$destTransaction->save();
$origSourceTransaction->save();
// refresh transactions.
$this->sourceTransaction->refresh();
$this->destinationTransaction->refresh();
@@ -679,27 +690,51 @@ class JournalUpdateService
if (null === $group) {
$group = $this->transactionJournal?->transactionGroup;
}
if (null === $group) {
if (null === $group || null === $this->transactionJournal) {
return;
}
if (0 === bccomp($origSourceTransaction->amount, $originalSourceAmount)) {
Log::debug('Amount was not actually changed, return.');
return;
}
Log::debug('Amount was changed.');
$transfer = TransactionTypeEnum::TRANSFER->value === $this->transactionJournal->transactionType->type;
$withdrawal = TransactionTypeEnum::WITHDRAWAL->value === $this->transactionJournal->transactionType->type;
$deposit = TransactionTypeEnum::DEPOSIT->value === $this->transactionJournal->transactionType->type;
$makePositive = $transfer || $deposit ? true : false;
// assume withdrawal, use the source for amount (negative), and destination for currency.
$originalAmount = $originalSourceAmount;
$recordCurrency = $destTransaction->transactionCurrency;
Log::debug(sprintf('Transaction is a %s, original amount is %s and currency is %s', $this->transactionJournal->transactionType->type, $originalAmount, $recordCurrency->code));
if ($withdrawal || $transfer) {
Log::debug('Use these values to record a changed withdrawal amount');
}
if (!$withdrawal && !$transfer) {
$originalAmount = $originalDestAmount;
$recordCurrency = $origSourceTransaction->transactionCurrency;
Log::debug('Use destination amount to record a changed withdrawal amount');
Log::debug(sprintf('Transaction is a %s, original amount now is %s and currency is now %s', $this->transactionJournal->transactionType->type, $originalAmount, $recordCurrency->code));
}
$originalAmount = $makePositive ? Steam::positive($originalAmount) : Steam::negative($originalAmount);
$value = $makePositive ? Steam::positive($value) : Steam::negative($value);
// should not return in NULL but seems to do.
event(new TriggeredAuditLog(
$group->user,
$group,
'update_amount',
[
'currency_symbol' => $destTransaction->transactionCurrency->symbol,
'decimal_places' => $destTransaction->transactionCurrency->decimal_places,
'currency_symbol' => $recordCurrency->symbol,
'decimal_places' => $recordCurrency->decimal_places,
'amount' => $originalAmount,
],
[
'currency_symbol' => $destTransaction->transactionCurrency->symbol,
'decimal_places' => $destTransaction->transactionCurrency->decimal_places,
'currency_symbol' => $recordCurrency->symbol,
'decimal_places' => $recordCurrency->decimal_places,
'amount' => $value,
]
));
}
private function updateForeignAmount(): void

View File

@@ -334,6 +334,11 @@ class Amount
public function getTransactionCurrencyById(int $currencyId): TransactionCurrency
{
if (0 === $currencyId) {
Log::debug('Could never find a currency with ID zero. Throw error.');
throw new FireflyException('Could never find a currency with ID zero. Throw error.');
}
$instance = PreferencesSingleton::getInstance();
$key = sprintf('transaction_currency_%d', $currencyId);

View File

@@ -34,10 +34,16 @@ class DynamicConfigKey
{
public static array $accepted
= [
'configuration.is_demo_site',
'configuration.permission_update_check',
'configuration.single_user_mode',
'configuration.last_update_check',
'configuration.is_demo_site', // boolean
'configuration.permission_update_check', // -1, 0 or 1 (never asked, no permission, permission)
'configuration.single_user_mode', // boolean
'configuration.last_update_check', // timestamp
'configuration.enable_exchange_rates', // boolean
'configuration.use_running_balance', // boolean
'configuration.enable_external_map', // boolean
'configuration.enable_external_rates', // boolean
'configuration.allow_webhooks', // boolean
'configuration.valid_url_protocols', // string ("http,https")
];
/**

View File

@@ -31,6 +31,7 @@ use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use Illuminate\Support\Collection;
use Throwable;
use FireflyIII\Support\Facades\Steam;
use FireflyIII\Support\Facades\Amount;
/**
* Class CurrencyForm
@@ -123,10 +124,10 @@ class CurrencyForm
$classes = $this->getHolderClasses($name);
$value = $this->fillFieldValue($name, $value);
$options['step'] = 'any';
$primaryCurrency = $options['currency'] ?? app('amount')->getPrimaryCurrency();
$primaryCurrency = $options['currency'] ?? Amount::getPrimaryCurrency();
/** @var Collection $currencies */
$currencies = app('amount')->getAllCurrencies();
$currencies = Amount::getAllCurrencies();
unset($options['currency'], $options['placeholder']);
// perhaps the currency has been sent to us in the field $amount_currency_id_$name (amount_currency_id_amount)
@@ -176,10 +177,10 @@ class CurrencyForm
$classes = $this->getHolderClasses($name);
$value = $this->fillFieldValue($name, $value);
$options['step'] = 'any';
$primaryCurrency = $options['currency'] ?? app('amount')->getPrimaryCurrency();
$primaryCurrency = $options['currency'] ?? Amount::getPrimaryCurrency();
/** @var Collection $currencies */
$currencies = app('amount')->getCurrencies();
$currencies = Amount::getCurrencies();
unset($options['currency'], $options['placeholder']);
// perhaps the currency has been sent to us in the field $amount_currency_id_$name (amount_currency_id_amount)
$preFilled = session('preFilled');

View File

@@ -67,7 +67,7 @@ trait ChartGeneration
/** @var AccountRepositoryInterface $accountRepos */
$accountRepos = app(AccountRepositoryInterface::class);
$primary = app('amount')->getPrimaryCurrency();
$primary = Amount::getPrimaryCurrency();
$chartData = [];
Log::debug(sprintf('Start of accountBalanceChart(list, %s, %s)', $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s')));

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

@@ -72,12 +72,25 @@ class AccountBalanceCalculator
$set[$transaction->account_id] = $transaction->account;
}
$accounts = new Collection()->push(...$set);
$object->optimizedCalculation($accounts, $transactionJournal->date);
// find meta value:
$date = $transactionJournal->date;
$meta = $transactionJournal->transactionJournalMeta()->where('name', '_internal_previous_date')->where('data', '!=', '')->first();
Log::debug(sprintf('Date used is "%s"', $date->toW3cString()));
if (null !== $meta) {
$date = Carbon::parse($meta->data);
Log::debug(sprintf('Date is overruled with "%s"', $date->toW3cString()));
}
$object->optimizedCalculation($accounts, $date);
}
private function getLatestBalance(int $accountId, int $currencyId, ?Carbon $notBefore): string
{
if (!$notBefore instanceof Carbon) {
Log::debug(sprintf('Start balance for account #%d and currency #%d is 0.', $accountId, $currencyId));
return '0';
}
Log::debug(sprintf('getLatestBalance: notBefore date is "%s", calculating', $notBefore->format('Y-m-d')));

View File

@@ -23,16 +23,16 @@ declare(strict_types=1);
namespace FireflyIII\Support;
use FireflyIII\Support\Facades\Preferences;
use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Exceptions\IntervalException;
use FireflyIII\Helpers\Fiscal\FiscalHelperInterface;
use FireflyIII\Support\Calendar\Calculator;
use FireflyIII\Support\Calendar\Periodicity;
use FireflyIII\Support\Facades\Preferences;
use FireflyIII\Support\Facades\Steam;
use Illuminate\Support\Facades\Log;
use Throwable;
use FireflyIII\Support\Facades\Steam;
/**
* Class Navigation.
@@ -214,6 +214,11 @@ class Navigation
Log::debug('endOfPeriod() requests "YTD" + future, set it to "1Y" instead.');
$repeatFreq = '1Y';
}
if ('QTD' === $repeatFreq && $end->isFuture()) {
// fall back to a yearly schedule if the requested period is YTD.
Log::debug('endOfPeriod() requests "YTD" + future, set it to "3M" instead.');
$repeatFreq = '3M';
}
$functionMap = [
'1D' => 'endOfDay',
@@ -295,7 +300,25 @@ class Navigation
if (null !== $result) {
// add sanity check.
if ($currentEnd->lt($end)) {
throw new FireflyException(sprintf('[d] endOfPeriod(%s, %s) failed, because it resulted in %s.', $end->toW3cString(), $repeatFreq, $currentEnd->toW3cString()));
switch ($repeatFreq) {
case 'QTD':
$currentEnd = $end->clone()->endOfQuarter()->setMilli(0);
break;
case 'MTD':
$currentEnd = $end->clone()->endOfMonth()->setMilli(0);
break;
case 'YTD':
$currentEnd = $end->clone()->endOfYear()->setMilli(0);
break;
}
if ($currentEnd->lt($end)) {
throw new FireflyException(sprintf('[d] endOfPeriod(%s, %s) failed, because it resulted in %s.', $end->toW3cString(), $repeatFreq, $currentEnd->toW3cString()));
}
}
return $result;

View File

@@ -34,6 +34,7 @@ use FireflyIII\Repositories\Budget\NoBudgetRepositoryInterface;
use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
use FireflyIII\User;
use Illuminate\Support\Collection;
use FireflyIII\Support\Facades\Amount;
/**
* Class BudgetReportGenerator
@@ -136,7 +137,7 @@ class BudgetReportGenerator
$this->blRepository->setUser($user);
$this->opsRepository->setUser($user);
$this->nbRepository->setUser($user);
$this->currency = app('amount')->getPrimaryCurrencyByUserGroup($user->userGroup);
$this->currency = Amount::getPrimaryCurrencyByUserGroup($user->userGroup);
}
/**

View File

@@ -28,6 +28,7 @@ use FireflyIII\Models\Account;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Facades\FireflyConfig;
use FireflyIII\Support\Facades\Steam;
use FireflyIII\Support\Search\OperatorQuerySearch;
use Illuminate\Support\Collection;
@@ -72,6 +73,7 @@ class General extends AbstractExtension
$this->hasRole(),
$this->getRootSearchOperator(),
$this->carbonize(),
$this->fireflyIIIConfig(),
];
}
@@ -180,7 +182,7 @@ class General extends AbstractExtension
if ('balance' === $key) {
// balance in account currency.
if (!$usePrimary) {
$strings[] = app('amount')->formatAnything($currency, $balance, false);
$strings[] = Amount::formatAnything($currency, $balance, false);
}
continue;
@@ -188,14 +190,14 @@ class General extends AbstractExtension
if ('pc_balance' === $key) {
// balance in primary currency.
if ($usePrimary) {
$strings[] = app('amount')->formatAnything($primary, $balance, false);
$strings[] = Amount::formatAnything($primary, $balance, false);
}
continue;
}
// for multi currency accounts.
if ($usePrimary && $key !== $primary->code) {
$strings[] = app('amount')->formatAnything(Amount::getTransactionCurrencyByCode($key), $balance, false);
$strings[] = Amount::formatAnything(Amount::getTransactionCurrencyByCode($key), $balance, false);
}
}
@@ -393,4 +395,14 @@ class General extends AbstractExtension
static fn (string $str): string => date($str)
);
}
private function fireflyIIIConfig()
{
return new TwigFunction(
'fireflyiiiconfig',
static function (string $string, mixed $default): mixed {
return FireflyConfig::get($string, $default)->data;
}
);
}
}

View File

@@ -35,6 +35,7 @@ use Illuminate\Support\Facades\DB;
use Override;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;
use FireflyIII\Support\Facades\Amount;
use function Safe\json_decode;
@@ -172,7 +173,7 @@ class TransactionGroupTwig extends AbstractExtension
if (TransactionTypeEnum::TRANSFER->value === $type) {
$colored = false;
}
$result = app('amount')->formatFlat($array['foreign_currency_symbol'], (int)$array['foreign_currency_decimal_places'], $amount, $colored);
$result = Amount::formatFlat($array['foreign_currency_symbol'], (int)$array['foreign_currency_decimal_places'], $amount, $colored);
if (TransactionTypeEnum::TRANSFER->value === $type) {
return sprintf('<span class="text-info money-transfer">%s</span>', $result);
}
@@ -199,7 +200,7 @@ class TransactionGroupTwig extends AbstractExtension
if (TransactionTypeEnum::TRANSFER->value === $type) {
$colored = false;
}
$result = app('amount')->formatFlat($currency->symbol, $currency->decimal_places, $amount, $colored);
$result = Amount::formatFlat($currency->symbol, $currency->decimal_places, $amount, $colored);
if (TransactionTypeEnum::TRANSFER->value === $type) {
return sprintf('<span class="text-info money-transfer">%s</span>', $result);
}
@@ -230,7 +231,7 @@ class TransactionGroupTwig extends AbstractExtension
$colored = false;
}
$result = app('amount')->formatFlat($array['currency_symbol'], (int)$array['currency_decimal_places'], $amount, $colored);
$result = Amount::formatFlat($array['currency_symbol'], (int)$array['currency_decimal_places'], $amount, $colored);
if (TransactionTypeEnum::TRANSFER->value === $type) {
return sprintf('<span class="text-info money-transfer">%s</span>', $result);
}
@@ -257,7 +258,7 @@ class TransactionGroupTwig extends AbstractExtension
if (TransactionTypeEnum::TRANSFER->value === $type) {
$colored = false;
}
$result = app('amount')->formatFlat($currency->symbol, $currency->decimal_places, $amount, $colored);
$result = Amount::formatFlat($currency->symbol, $currency->decimal_places, $amount, $colored);
if (TransactionTypeEnum::TRANSFER->value === $type) {
return sprintf('<span class="text-info money-transfer">%s</span>', $result);
}

View File

@@ -24,14 +24,14 @@ declare(strict_types=1);
namespace FireflyIII\TransactionRules\Actions;
use Illuminate\Support\Facades\Log;
use FireflyIII\Events\Model\Rule\RuleActionFailedOnArray;
use FireflyIII\Events\TriggeredAuditLog;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\TransactionRules\Traits\RefreshNotesTrait;
use FireflyIII\Support\Facades\Steam;
use FireflyIII\TransactionRules\Traits\RefreshNotesTrait;
use Illuminate\Support\Facades\Log;
class SetAmount implements ActionInterface
{
@@ -75,21 +75,23 @@ class SetAmount implements ActionInterface
$object->transactionGroup->touch();
// event for audit log entry
event(new TriggeredAuditLog(
$this->action->rule,
$object,
'update_amount',
[
'currency_symbol' => $object->transactionCurrency->symbol,
'decimal_places' => $object->transactionCurrency->decimal_places,
'amount' => $journal['amount'],
],
[
'currency_symbol' => $object->transactionCurrency->symbol,
'decimal_places' => $object->transactionCurrency->decimal_places,
'amount' => $value,
]
));
if (0 !== bccomp($journal['amount'], $value)) {
event(new TriggeredAuditLog(
$this->action->rule,
$object,
'update_amount',
[
'currency_symbol' => $object->transactionCurrency->symbol,
'decimal_places' => $object->transactionCurrency->decimal_places,
'amount' => $journal['amount'],
],
[
'currency_symbol' => $object->transactionCurrency->symbol,
'decimal_places' => $object->transactionCurrency->decimal_places,
'amount' => $value,
]
));
}
return true;
}

View File

@@ -75,7 +75,7 @@ class TransactionGroupTransformer extends AbstractTransformer
'recurrence_count',
'recurrence_total',
];
$this->metaDateFields = ['interest_date', 'book_date', 'process_date', 'due_date', 'payment_date', 'invoice_date'];
$this->metaDateFields = ['interest_date', 'book_date', 'process_date', 'due_date', 'payment_date', 'invoice_date', '_internal_previous_date'];
}
public function transform(array $group): array

View File

@@ -37,6 +37,7 @@ use FireflyIII\Repositories\Account\AccountRepository;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\User;
use Illuminate\Support\Facades\Log;
use FireflyIII\Support\Facades\Amount;
/**
* Trait TransactionValidation
@@ -224,7 +225,7 @@ trait TransactionValidation
/** @var AccountRepository $accountRepository */
$accountRepository = app(AccountRepositoryInterface::class);
$primaryCurrency = app('amount')->getPrimaryCurrency();
$primaryCurrency = Amount::getPrimaryCurrency();
$sourceCurrency = $accountRepository->getAccountCurrency($source) ?? $primaryCurrency;
$destinationCurrency = $accountRepository->getAccountCurrency($destination) ?? $primaryCurrency;
// if both accounts have the same currency, continue.
@@ -254,7 +255,7 @@ trait TransactionValidation
// wrong currency information is present
$foreignCurrencyCode = $transaction['foreign_currency_code'] ?? false;
$foreignCurrencyId = (int) ($transaction['foreign_currency_id'] ?? 0);
Log::debug(sprintf('Foreign currency code seems to be #%d "%s"', $foreignCurrencyId, $foreignCurrencyCode), $transaction);
Log::debug(sprintf('[a] Foreign currency code seems to be #%d "%s"', $foreignCurrencyId, $foreignCurrencyCode), $transaction);
if ($foreignCurrencyCode !== $destinationCurrency->code && $foreignCurrencyId !== $destinationCurrency->id) {
$validator->errors()->add(sprintf('transactions.%d.foreign_currency_code', $index), (string) trans('validation.require_foreign_src'));
@@ -281,7 +282,7 @@ trait TransactionValidation
// wrong currency information is present
$foreignCurrencyCode = $transaction['foreign_currency_code'] ?? false;
$foreignCurrencyId = (int) ($transaction['foreign_currency_id'] ?? 0);
Log::debug(sprintf('Foreign currency code seems to be #%d "%s"', $foreignCurrencyId, $foreignCurrencyCode), $transaction);
Log::debug(sprintf('[b] Foreign currency code seems to be #%d "%s"', $foreignCurrencyId, $foreignCurrencyCode), $transaction);
if ($foreignCurrencyCode !== $destinationCurrency->code && $foreignCurrencyId !== $destinationCurrency->id) {
Log::debug(sprintf('No match on code, "%s" vs "%s"', $foreignCurrencyCode, $destinationCurrency->code));
Log::debug(sprintf('No match on ID, #%d vs #%d', $foreignCurrencyId, $destinationCurrency->id));

View File

@@ -3,6 +3,41 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
## v6.4.15 - 2026-01-07
### Added
- [Issue 11264](https://github.com/firefly-iii/firefly-iii/issues/11264) (Add GUI for some settings, replacing environment variables) reported by @jacobburrell
- [Discussion 11433](https://github.com/orgs/firefly-iii/discussions/11433) (Updates to Date Range selection) started by @fett327
### Changed
- Moved some settings to your system settings
### Removed
- The following environment variables are removed and will no longer work. They are now in your settings.
- `ENABLE_EXTERNAL_MAP`
- `ENABLE_EXCHANGE_RATES`
- `ENABLE_EXTERNAL_RATES`
- `VALID_URL_PROTOCOLS`
- `ALLOW_WEBHOOKS`
- `USE_RUNNING_BALANCE`
- Removed sentry.io code
### Fixed
- [Issue 11378](https://github.com/firefly-iii/firefly-iii/issues/11378) (Wrong account balance with initial transfer from different currency) reported by @bozho
- [Issue 11383](https://github.com/firefly-iii/firefly-iii/issues/11383) (Login flow could redirect to javascript path) reported by @stefvonb
- [Issue 11388](https://github.com/firefly-iii/firefly-iii/issues/11388) (TypeError bugs during upgrade to 6.4.14 + account_balances corruption) reported by @jaconde2
- [Issue 11396](https://github.com/firefly-iii/firefly-iii/issues/11396) (Reconciliation adds extra digits) reported by @niklas2810
- [Issue 11399](https://github.com/firefly-iii/firefly-iii/issues/11399) (Unusual behavior in audit logs (multi-currency)) reported by @jgmm81
- [Issue 11403](https://github.com/firefly-iii/firefly-iii/issues/11403) (Error 404 when trying to view the details (Piggy banks section)) reported by @jgmm81
- [Issue 11410](https://github.com/firefly-iii/firefly-iii/issues/11410) (nitpick: Bulk edit tags should keep the option chosen instead of always changing back to "replace") reported by @jxtxzzw
- [Issue 11443](https://github.com/firefly-iii/firefly-iii/issues/11443) (Exception thrown, when subscription is in foreign currency) reported by @ajgon
- [Issue 11445](https://github.com/firefly-iii/firefly-iii/issues/11445) (“Reconcile” screen breaks when Preferences → Layout is set to “Year to date”) reported by @semonsir
- [Issue 11449](https://github.com/firefly-iii/firefly-iii/issues/11449) (Non-strict rules break with "Apply rule" and "Apply rule group") reported by @Bytenka
## v6.4.14 - 2025-12-17
### Fixed

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",
@@ -96,7 +99,7 @@
"league/commonmark": "^2",
"league/csv": "^9.10",
"league/fractal": "0.*",
"mailersend/laravel-driver": "^2.7",
"mailersend/laravel-driver": "^2.12",
"nunomaduro/collision": "^8",
"pragmarx/google2fa": "^8.0",
"predis/predis": "^3",

339
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "8fff223d32252d22c0e6028d19a76756",
"content-hash": "434b4c996dad2af3b38326bd81c57534",
"packages": [
{
"name": "bacon/bacon-qr-code",
@@ -1182,24 +1182,24 @@
},
{
"name": "graham-campbell/result-type",
"version": "v1.1.3",
"version": "v1.1.4",
"source": {
"type": "git",
"url": "https://github.com/GrahamCampbell/Result-Type.git",
"reference": "3ba905c11371512af9d9bdd27d99b782216b6945"
"reference": "e01f4a821471308ba86aa202fed6698b6b695e3b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/3ba905c11371512af9d9bdd27d99b782216b6945",
"reference": "3ba905c11371512af9d9bdd27d99b782216b6945",
"url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/e01f4a821471308ba86aa202fed6698b6b695e3b",
"reference": "e01f4a821471308ba86aa202fed6698b6b695e3b",
"shasum": ""
},
"require": {
"php": "^7.2.5 || ^8.0",
"phpoption/phpoption": "^1.9.3"
"phpoption/phpoption": "^1.9.5"
},
"require-dev": {
"phpunit/phpunit": "^8.5.39 || ^9.6.20 || ^10.5.28"
"phpunit/phpunit": "^8.5.41 || ^9.6.22 || ^10.5.45 || ^11.5.7"
},
"type": "library",
"autoload": {
@@ -1228,7 +1228,7 @@
],
"support": {
"issues": "https://github.com/GrahamCampbell/Result-Type/issues",
"source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.3"
"source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.4"
},
"funding": [
{
@@ -1240,7 +1240,7 @@
"type": "tidelift"
}
],
"time": "2024-07-20T21:45:45+00:00"
"time": "2025-12-27T19:43:20+00:00"
},
{
"name": "guzzlehttp/guzzle",
@@ -1878,16 +1878,16 @@
},
{
"name": "laravel/framework",
"version": "v12.43.1",
"version": "v12.45.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
"reference": "195b893593a9298edee177c0844132ebaa02102f"
"reference": "9dfd2afc48f2519bfdbe6862dfb9849491c673ad"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/195b893593a9298edee177c0844132ebaa02102f",
"reference": "195b893593a9298edee177c0844132ebaa02102f",
"url": "https://api.github.com/repos/laravel/framework/zipball/9dfd2afc48f2519bfdbe6862dfb9849491c673ad",
"reference": "9dfd2afc48f2519bfdbe6862dfb9849491c673ad",
"shasum": ""
},
"require": {
@@ -2096,7 +2096,7 @@
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
},
"time": "2025-12-16T18:53:08+00:00"
"time": "2026-01-06T15:24:52+00:00"
},
{
"name": "laravel/passport",
@@ -2813,16 +2813,16 @@
},
{
"name": "league/csv",
"version": "9.27.1",
"version": "9.28.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/csv.git",
"reference": "26de738b8fccf785397d05ee2fc07b6cd8749797"
"reference": "6582ace29ae09ba5b07049d40ea13eb19c8b5073"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/csv/zipball/26de738b8fccf785397d05ee2fc07b6cd8749797",
"reference": "26de738b8fccf785397d05ee2fc07b6cd8749797",
"url": "https://api.github.com/repos/thephpleague/csv/zipball/6582ace29ae09ba5b07049d40ea13eb19c8b5073",
"reference": "6582ace29ae09ba5b07049d40ea13eb19c8b5073",
"shasum": ""
},
"require": {
@@ -2832,14 +2832,14 @@
"require-dev": {
"ext-dom": "*",
"ext-xdebug": "*",
"friendsofphp/php-cs-fixer": "^3.75.0",
"phpbench/phpbench": "^1.4.1",
"phpstan/phpstan": "^1.12.27",
"friendsofphp/php-cs-fixer": "^3.92.3",
"phpbench/phpbench": "^1.4.3",
"phpstan/phpstan": "^1.12.32",
"phpstan/phpstan-deprecation-rules": "^1.2.1",
"phpstan/phpstan-phpunit": "^1.4.2",
"phpstan/phpstan-strict-rules": "^1.6.2",
"phpunit/phpunit": "^10.5.16 || ^11.5.22 || ^12.3.6",
"symfony/var-dumper": "^6.4.8 || ^7.3.0"
"phpunit/phpunit": "^10.5.16 || ^11.5.22 || ^12.5.4",
"symfony/var-dumper": "^6.4.8 || ^7.4.0 || ^8.0"
},
"suggest": {
"ext-dom": "Required to use the XMLConverter and the HTMLConverter classes",
@@ -2900,7 +2900,7 @@
"type": "github"
}
],
"time": "2025-10-25T08:35:20+00:00"
"time": "2025-12-27T15:18:42+00:00"
},
{
"name": "league/event",
@@ -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",
@@ -3894,16 +3894,16 @@
},
{
"name": "nette/utils",
"version": "v4.1.0",
"version": "v4.1.1",
"source": {
"type": "git",
"url": "https://github.com/nette/utils.git",
"reference": "fa1f0b8261ed150447979eb22e373b7b7ad5a8e0"
"reference": "c99059c0315591f1a0db7ad6002000288ab8dc72"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nette/utils/zipball/fa1f0b8261ed150447979eb22e373b7b7ad5a8e0",
"reference": "fa1f0b8261ed150447979eb22e373b7b7ad5a8e0",
"url": "https://api.github.com/repos/nette/utils/zipball/c99059c0315591f1a0db7ad6002000288ab8dc72",
"reference": "c99059c0315591f1a0db7ad6002000288ab8dc72",
"shasum": ""
},
"require": {
@@ -3977,9 +3977,9 @@
],
"support": {
"issues": "https://github.com/nette/utils/issues",
"source": "https://github.com/nette/utils/tree/v4.1.0"
"source": "https://github.com/nette/utils/tree/v4.1.1"
},
"time": "2025-12-01T17:49:23+00:00"
"time": "2025-12-22T12:14:32+00:00"
},
{
"name": "nunomaduro/collision",
@@ -4749,16 +4749,16 @@
},
{
"name": "phpoption/phpoption",
"version": "1.9.4",
"version": "1.9.5",
"source": {
"type": "git",
"url": "https://github.com/schmittjoh/php-option.git",
"reference": "638a154f8d4ee6a5cfa96d6a34dfbe0cffa9566d"
"reference": "75365b91986c2405cf5e1e012c5595cd487a98be"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/schmittjoh/php-option/zipball/638a154f8d4ee6a5cfa96d6a34dfbe0cffa9566d",
"reference": "638a154f8d4ee6a5cfa96d6a34dfbe0cffa9566d",
"url": "https://api.github.com/repos/schmittjoh/php-option/zipball/75365b91986c2405cf5e1e012c5595cd487a98be",
"reference": "75365b91986c2405cf5e1e012c5595cd487a98be",
"shasum": ""
},
"require": {
@@ -4808,7 +4808,7 @@
],
"support": {
"issues": "https://github.com/schmittjoh/php-option/issues",
"source": "https://github.com/schmittjoh/php-option/tree/1.9.4"
"source": "https://github.com/schmittjoh/php-option/tree/1.9.5"
},
"funding": [
{
@@ -4820,7 +4820,7 @@
"type": "tidelift"
}
],
"time": "2025-08-21T11:53:16+00:00"
"time": "2025-12-27T19:41:33+00:00"
},
{
"name": "phpseclib/phpseclib",
@@ -6204,16 +6204,16 @@
},
{
"name": "spatie/laravel-html",
"version": "3.12.1",
"version": "3.12.3",
"source": {
"type": "git",
"url": "https://github.com/spatie/laravel-html.git",
"reference": "72af3cad24d153c230ff6e1da9fa3b7b702834c9"
"reference": "dd4a946ea9e2d7af8945fdfcf282663c69fac26a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/spatie/laravel-html/zipball/72af3cad24d153c230ff6e1da9fa3b7b702834c9",
"reference": "72af3cad24d153c230ff6e1da9fa3b7b702834c9",
"url": "https://api.github.com/repos/spatie/laravel-html/zipball/dd4a946ea9e2d7af8945fdfcf282663c69fac26a",
"reference": "dd4a946ea9e2d7af8945fdfcf282663c69fac26a",
"shasum": ""
},
"require": {
@@ -6270,7 +6270,7 @@
"spatie"
],
"support": {
"source": "https://github.com/spatie/laravel-html/tree/3.12.1"
"source": "https://github.com/spatie/laravel-html/tree/3.12.3"
},
"funding": [
{
@@ -6278,7 +6278,7 @@
"type": "custom"
}
],
"time": "2025-10-02T07:26:38+00:00"
"time": "2025-12-22T12:05:50+00:00"
},
{
"name": "spatie/laravel-ignition",
@@ -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",
@@ -9918,26 +9918,26 @@
},
{
"name": "vlucas/phpdotenv",
"version": "v5.6.2",
"version": "v5.6.3",
"source": {
"type": "git",
"url": "https://github.com/vlucas/phpdotenv.git",
"reference": "24ac4c74f91ee2c193fa1aaa5c249cb0822809af"
"reference": "955e7815d677a3eaa7075231212f2110983adecc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/24ac4c74f91ee2c193fa1aaa5c249cb0822809af",
"reference": "24ac4c74f91ee2c193fa1aaa5c249cb0822809af",
"url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/955e7815d677a3eaa7075231212f2110983adecc",
"reference": "955e7815d677a3eaa7075231212f2110983adecc",
"shasum": ""
},
"require": {
"ext-pcre": "*",
"graham-campbell/result-type": "^1.1.3",
"graham-campbell/result-type": "^1.1.4",
"php": "^7.2.5 || ^8.0",
"phpoption/phpoption": "^1.9.3",
"symfony/polyfill-ctype": "^1.24",
"symfony/polyfill-mbstring": "^1.24",
"symfony/polyfill-php80": "^1.24"
"phpoption/phpoption": "^1.9.5",
"symfony/polyfill-ctype": "^1.26",
"symfony/polyfill-mbstring": "^1.26",
"symfony/polyfill-php80": "^1.26"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
@@ -9986,7 +9986,7 @@
],
"support": {
"issues": "https://github.com/vlucas/phpdotenv/issues",
"source": "https://github.com/vlucas/phpdotenv/tree/v5.6.2"
"source": "https://github.com/vlucas/phpdotenv/tree/v5.6.3"
},
"funding": [
{
@@ -9998,7 +9998,7 @@
"type": "tidelift"
}
],
"time": "2025-04-30T23:37:27+00:00"
"time": "2025-12-27T19:49:13+00:00"
},
{
"name": "voku/portable-ascii",
@@ -10078,16 +10078,16 @@
"packages-dev": [
{
"name": "barryvdh/laravel-debugbar",
"version": "v3.16.2",
"version": "v3.16.3",
"source": {
"type": "git",
"url": "https://github.com/barryvdh/laravel-debugbar.git",
"reference": "730dbf8bf41f5691e026dd771e64dd54ad1b10b3"
"reference": "c91e57ea113edd6526f5b8cd6b1c6ee02c67b28e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/730dbf8bf41f5691e026dd771e64dd54ad1b10b3",
"reference": "730dbf8bf41f5691e026dd771e64dd54ad1b10b3",
"url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/c91e57ea113edd6526f5b8cd6b1c6ee02c67b28e",
"reference": "c91e57ea113edd6526f5b8cd6b1c6ee02c67b28e",
"shasum": ""
},
"require": {
@@ -10096,7 +10096,7 @@
"illuminate/support": "^10|^11|^12",
"php": "^8.1",
"php-debugbar/php-debugbar": "^2.2.4",
"symfony/finder": "^6|^7"
"symfony/finder": "^6|^7|^8"
},
"require-dev": {
"mockery/mockery": "^1.3.3",
@@ -10147,7 +10147,7 @@
],
"support": {
"issues": "https://github.com/barryvdh/laravel-debugbar/issues",
"source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.16.2"
"source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.16.3"
},
"funding": [
{
@@ -10159,7 +10159,7 @@
"type": "github"
}
],
"time": "2025-12-03T14:52:46+00:00"
"time": "2025-12-23T17:37:00+00:00"
},
{
"name": "barryvdh/laravel-ide-helper",
@@ -10367,16 +10367,16 @@
},
{
"name": "composer/class-map-generator",
"version": "1.7.0",
"version": "1.7.1",
"source": {
"type": "git",
"url": "https://github.com/composer/class-map-generator.git",
"reference": "2373419b7709815ed323ebf18c3c72d03ff4a8a6"
"reference": "8f5fa3cc214230e71f54924bd0197a3bcc705eb1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/class-map-generator/zipball/2373419b7709815ed323ebf18c3c72d03ff4a8a6",
"reference": "2373419b7709815ed323ebf18c3c72d03ff4a8a6",
"url": "https://api.github.com/repos/composer/class-map-generator/zipball/8f5fa3cc214230e71f54924bd0197a3bcc705eb1",
"reference": "8f5fa3cc214230e71f54924bd0197a3bcc705eb1",
"shasum": ""
},
"require": {
@@ -10420,7 +10420,7 @@
],
"support": {
"issues": "https://github.com/composer/class-map-generator/issues",
"source": "https://github.com/composer/class-map-generator/tree/1.7.0"
"source": "https://github.com/composer/class-map-generator/tree/1.7.1"
},
"funding": [
{
@@ -10432,7 +10432,7 @@
"type": "github"
}
],
"time": "2025-11-19T10:41:15+00:00"
"time": "2025-12-29T13:15:25+00:00"
},
{
"name": "composer/pcre",
@@ -10515,16 +10515,16 @@
},
{
"name": "driftingly/rector-laravel",
"version": "2.1.8",
"version": "2.1.9",
"source": {
"type": "git",
"url": "https://github.com/driftingly/rector-laravel.git",
"reference": "5c5f97354e562b6742b2b7989959061bde60fa71"
"reference": "aee9d4a1d489e7ec484fc79f33137f8ee051b3f7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/driftingly/rector-laravel/zipball/5c5f97354e562b6742b2b7989959061bde60fa71",
"reference": "5c5f97354e562b6742b2b7989959061bde60fa71",
"url": "https://api.github.com/repos/driftingly/rector-laravel/zipball/aee9d4a1d489e7ec484fc79f33137f8ee051b3f7",
"reference": "aee9d4a1d489e7ec484fc79f33137f8ee051b3f7",
"shasum": ""
},
"require": {
@@ -10545,9 +10545,9 @@
"description": "Rector upgrades rules for Laravel Framework",
"support": {
"issues": "https://github.com/driftingly/rector-laravel/issues",
"source": "https://github.com/driftingly/rector-laravel/tree/2.1.8"
"source": "https://github.com/driftingly/rector-laravel/tree/2.1.9"
},
"time": "2025-12-17T15:29:24+00:00"
"time": "2025-12-25T23:31:36+00:00"
},
{
"name": "fakerphp/faker",
@@ -11180,31 +11180,32 @@
},
{
"name": "php-debugbar/php-debugbar",
"version": "v2.2.4",
"version": "v2.2.6",
"source": {
"type": "git",
"url": "https://github.com/php-debugbar/php-debugbar.git",
"reference": "3146d04671f51f69ffec2a4207ac3bdcf13a9f35"
"reference": "abb9fa3c5c8dbe7efe03ddba56782917481de3e8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-debugbar/php-debugbar/zipball/3146d04671f51f69ffec2a4207ac3bdcf13a9f35",
"reference": "3146d04671f51f69ffec2a4207ac3bdcf13a9f35",
"url": "https://api.github.com/repos/php-debugbar/php-debugbar/zipball/abb9fa3c5c8dbe7efe03ddba56782917481de3e8",
"reference": "abb9fa3c5c8dbe7efe03ddba56782917481de3e8",
"shasum": ""
},
"require": {
"php": "^8",
"php": "^8.1",
"psr/log": "^1|^2|^3",
"symfony/var-dumper": "^4|^5|^6|^7"
"symfony/var-dumper": "^5.4|^6.4|^7.3|^8.0"
},
"replace": {
"maximebf/debugbar": "self.version"
},
"require-dev": {
"dbrekelmans/bdi": "^1",
"phpunit/phpunit": "^8|^9",
"phpunit/phpunit": "^10",
"symfony/browser-kit": "^6.0|7.0",
"symfony/panther": "^1|^2.1",
"twig/twig": "^1.38|^2.7|^3.0"
"twig/twig": "^3.11.2"
},
"suggest": {
"kriswallsmith/assetic": "The best way to manage assets",
@@ -11214,7 +11215,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.1-dev"
"dev-master": "2.2-dev"
}
},
"autoload": {
@@ -11247,9 +11248,9 @@
],
"support": {
"issues": "https://github.com/php-debugbar/php-debugbar/issues",
"source": "https://github.com/php-debugbar/php-debugbar/tree/v2.2.4"
"source": "https://github.com/php-debugbar/php-debugbar/tree/v2.2.6"
},
"time": "2025-07-22T14:01:30+00:00"
"time": "2025-12-22T13:21:32+00:00"
},
{
"name": "phpstan/extension-installer",
@@ -11449,16 +11450,16 @@
},
{
"name": "phpunit/php-code-coverage",
"version": "12.5.1",
"version": "12.5.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "c467c59a4f6e04b942be422844e7a6352fa01b57"
"reference": "4a9739b51cbcb355f6e95659612f92e282a7077b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c467c59a4f6e04b942be422844e7a6352fa01b57",
"reference": "c467c59a4f6e04b942be422844e7a6352fa01b57",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/4a9739b51cbcb355f6e95659612f92e282a7077b",
"reference": "4a9739b51cbcb355f6e95659612f92e282a7077b",
"shasum": ""
},
"require": {
@@ -11473,7 +11474,7 @@
"sebastian/environment": "^8.0.3",
"sebastian/lines-of-code": "^4.0",
"sebastian/version": "^6.0",
"theseer/tokenizer": "^2.0"
"theseer/tokenizer": "^2.0.1"
},
"require-dev": {
"phpunit/phpunit": "^12.5.1"
@@ -11514,7 +11515,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
"security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/12.5.1"
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/12.5.2"
},
"funding": [
{
@@ -11534,7 +11535,7 @@
"type": "tidelift"
}
],
"time": "2025-12-08T07:17:58+00:00"
"time": "2025-12-24T07:03:04+00:00"
},
{
"name": "phpunit/php-file-iterator",
@@ -11888,16 +11889,16 @@
},
{
"name": "rector/rector",
"version": "2.2.14",
"version": "2.3.0",
"source": {
"type": "git",
"url": "https://github.com/rectorphp/rector.git",
"reference": "6d56bb0e94d4df4f57a78610550ac76ab403657d"
"reference": "f7166355dcf47482f27be59169b0825995f51c7d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/rectorphp/rector/zipball/6d56bb0e94d4df4f57a78610550ac76ab403657d",
"reference": "6d56bb0e94d4df4f57a78610550ac76ab403657d",
"url": "https://api.github.com/repos/rectorphp/rector/zipball/f7166355dcf47482f27be59169b0825995f51c7d",
"reference": "f7166355dcf47482f27be59169b0825995f51c7d",
"shasum": ""
},
"require": {
@@ -11936,7 +11937,7 @@
],
"support": {
"issues": "https://github.com/rectorphp/rector/issues",
"source": "https://github.com/rectorphp/rector/tree/2.2.14"
"source": "https://github.com/rectorphp/rector/tree/2.3.0"
},
"funding": [
{
@@ -11944,7 +11945,7 @@
"type": "github"
}
],
"time": "2025-12-09T10:57:55+00:00"
"time": "2025-12-25T22:00:18+00:00"
},
{
"name": "sebastian/cli-parser",

View File

@@ -75,11 +75,11 @@ return [
'webhooks' => true,
'handle_debts' => true,
'expression_engine' => true,
'running_balance_column' => env('USE_RUNNING_BALANCE', true), // this is only the default value, is not used.
'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-20',
'build_time' => 1766210708,
'version' => '6.4.15',
'build_time' => 1767729818,
'api_version' => '2.1.0', // field is no longer used.
'db_version' => 28, // field is no longer used.

View File

@@ -57,6 +57,7 @@ class TransactionCurrencySeeder extends Seeder
$currencies[] = ['code' => 'ARS', 'name' => 'Argentinian Peso', 'symbol' => '$', 'decimal_places' => 2];
$currencies[] = ['code' => 'COP', 'name' => 'Colombian Peso', 'symbol' => '$', 'decimal_places' => 2];
$currencies[] = ['code' => 'CLP', 'name' => 'Chilean Peso', 'symbol' => '$', 'decimal_places' => 2];
$currencies[] = ['code' => 'UYU', 'name' => 'Uruguayan Peso', 'symbol' => '$', 'decimal_places' => 2];
// oceanian currencies
$currencies[] = ['code' => 'IDR', 'name' => 'Indonesian rupiah', 'symbol' => 'Rp', 'decimal_places' => 2];

271
package-lock.json generated
View File

@@ -2592,9 +2592,9 @@
}
},
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.5.tgz",
"integrity": "sha512-iDGS/h7D8t7tvZ1t6+WPK04KD0MwzLZrG0se1hzBjSi5fyxlsiggoJHwh18PCFNn7tG43OWb6pdZ6Y+rMlmyNQ==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.55.1.tgz",
"integrity": "sha512-9R0DM/ykwfGIlNu6+2U09ga0WXeZ9MRC2Ter8jnz8415VbuIykVuc6bhdrbORFZANDmTDvq26mJrEVTl8TdnDg==",
"cpu": [
"arm"
],
@@ -2606,9 +2606,9 @@
]
},
"node_modules/@rollup/rollup-android-arm64": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.5.tgz",
"integrity": "sha512-wrSAViWvZHBMMlWk6EJhvg8/rjxzyEhEdgfMMjREHEq11EtJ6IP6yfcCH57YAEca2Oe3FNCE9DSTgU70EIGmVw==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.55.1.tgz",
"integrity": "sha512-eFZCb1YUqhTysgW3sj/55du5cG57S7UTNtdMjCW7LwVcj3dTTcowCsC8p7uBdzKsZYa8J7IDE8lhMI+HX1vQvg==",
"cpu": [
"arm64"
],
@@ -2620,9 +2620,9 @@
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.5.tgz",
"integrity": "sha512-S87zZPBmRO6u1YXQLwpveZm4JfPpAa6oHBX7/ghSiGH3rz/KDgAu1rKdGutV+WUI6tKDMbaBJomhnT30Y2t4VQ==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.55.1.tgz",
"integrity": "sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg==",
"cpu": [
"arm64"
],
@@ -2634,9 +2634,9 @@
]
},
"node_modules/@rollup/rollup-darwin-x64": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.5.tgz",
"integrity": "sha512-YTbnsAaHo6VrAczISxgpTva8EkfQus0VPEVJCEaboHtZRIb6h6j0BNxRBOwnDciFTZLDPW5r+ZBmhL/+YpTZgA==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.55.1.tgz",
"integrity": "sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ==",
"cpu": [
"x64"
],
@@ -2648,9 +2648,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-arm64": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.5.tgz",
"integrity": "sha512-1T8eY2J8rKJWzaznV7zedfdhD1BqVs1iqILhmHDq/bqCUZsrMt+j8VCTHhP0vdfbHK3e1IQ7VYx3jlKqwlf+vw==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.55.1.tgz",
"integrity": "sha512-+JiU7Jbp5cdxekIgdte0jfcu5oqw4GCKr6i3PJTlXTCU5H5Fvtkpbs4XJHRmWNXF+hKmn4v7ogI5OQPaupJgOg==",
"cpu": [
"arm64"
],
@@ -2662,9 +2662,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-x64": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.5.tgz",
"integrity": "sha512-sHTiuXyBJApxRn+VFMaw1U+Qsz4kcNlxQ742snICYPrY+DDL8/ZbaC4DVIB7vgZmp3jiDaKA0WpBdP0aqPJoBQ==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.55.1.tgz",
"integrity": "sha512-V5xC1tOVWtLLmr3YUk2f6EJK4qksksOYiz/TCsFHu/R+woubcLWdC9nZQmwjOAbmExBIVKsm1/wKmEy4z4u4Bw==",
"cpu": [
"x64"
],
@@ -2676,9 +2676,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.5.tgz",
"integrity": "sha512-dV3T9MyAf0w8zPVLVBptVlzaXxka6xg1f16VAQmjg+4KMSTWDvhimI/Y6mp8oHwNrmnmVl9XxJ/w/mO4uIQONA==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.55.1.tgz",
"integrity": "sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ==",
"cpu": [
"arm"
],
@@ -2690,9 +2690,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.5.tgz",
"integrity": "sha512-wIGYC1x/hyjP+KAu9+ewDI+fi5XSNiUi9Bvg6KGAh2TsNMA3tSEs+Sh6jJ/r4BV/bx/CyWu2ue9kDnIdRyafcQ==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.55.1.tgz",
"integrity": "sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg==",
"cpu": [
"arm"
],
@@ -2704,9 +2704,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.5.tgz",
"integrity": "sha512-Y+qVA0D9d0y2FRNiG9oM3Hut/DgODZbU9I8pLLPwAsU0tUKZ49cyV1tzmB/qRbSzGvY8lpgGkJuMyuhH7Ma+Vg==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.55.1.tgz",
"integrity": "sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==",
"cpu": [
"arm64"
],
@@ -2718,9 +2718,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.5.tgz",
"integrity": "sha512-juaC4bEgJsyFVfqhtGLz8mbopaWD+WeSOYr5E16y+1of6KQjc0BpwZLuxkClqY1i8sco+MdyoXPNiCkQou09+g==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.55.1.tgz",
"integrity": "sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA==",
"cpu": [
"arm64"
],
@@ -2732,9 +2732,23 @@
]
},
"node_modules/@rollup/rollup-linux-loong64-gnu": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.5.tgz",
"integrity": "sha512-rIEC0hZ17A42iXtHX+EPJVL/CakHo+tT7W0pbzdAGuWOt2jxDFh7A/lRhsNHBcqL4T36+UiAgwO8pbmn3dE8wA==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.55.1.tgz",
"integrity": "sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g==",
"cpu": [
"loong64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-loong64-musl": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.55.1.tgz",
"integrity": "sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw==",
"cpu": [
"loong64"
],
@@ -2746,9 +2760,23 @@
]
},
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.5.tgz",
"integrity": "sha512-T7l409NhUE552RcAOcmJHj3xyZ2h7vMWzcwQI0hvn5tqHh3oSoclf9WgTl+0QqffWFG8MEVZZP1/OBglKZx52Q==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.55.1.tgz",
"integrity": "sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-ppc64-musl": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.55.1.tgz",
"integrity": "sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw==",
"cpu": [
"ppc64"
],
@@ -2760,9 +2788,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.5.tgz",
"integrity": "sha512-7OK5/GhxbnrMcxIFoYfhV/TkknarkYC1hqUw1wU2xUN3TVRLNT5FmBv4KkheSG2xZ6IEbRAhTooTV2+R5Tk0lQ==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.55.1.tgz",
"integrity": "sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw==",
"cpu": [
"riscv64"
],
@@ -2774,9 +2802,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-musl": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.5.tgz",
"integrity": "sha512-GwuDBE/PsXaTa76lO5eLJTyr2k8QkPipAyOrs4V/KJufHCZBJ495VCGJol35grx9xryk4V+2zd3Ri+3v7NPh+w==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.55.1.tgz",
"integrity": "sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg==",
"cpu": [
"riscv64"
],
@@ -2788,9 +2816,9 @@
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.5.tgz",
"integrity": "sha512-IAE1Ziyr1qNfnmiQLHBURAD+eh/zH1pIeJjeShleII7Vj8kyEm2PF77o+lf3WTHDpNJcu4IXJxNO0Zluro8bOw==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.55.1.tgz",
"integrity": "sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg==",
"cpu": [
"s390x"
],
@@ -2802,9 +2830,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.5.tgz",
"integrity": "sha512-Pg6E+oP7GvZ4XwgRJBuSXZjcqpIW3yCBhK4BcsANvb47qMvAbCjR6E+1a/U2WXz1JJxp9/4Dno3/iSJLcm5auw==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.55.1.tgz",
"integrity": "sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==",
"cpu": [
"x64"
],
@@ -2816,9 +2844,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.5.tgz",
"integrity": "sha512-txGtluxDKTxaMDzUduGP0wdfng24y1rygUMnmlUJ88fzCCULCLn7oE5kb2+tRB+MWq1QDZT6ObT5RrR8HFRKqg==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.55.1.tgz",
"integrity": "sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w==",
"cpu": [
"x64"
],
@@ -2829,10 +2857,24 @@
"linux"
]
},
"node_modules/@rollup/rollup-openbsd-x64": {
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.55.1.tgz",
"integrity": "sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
]
},
"node_modules/@rollup/rollup-openharmony-arm64": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.5.tgz",
"integrity": "sha512-3DFiLPnTxiOQV993fMc+KO8zXHTcIjgaInrqlG8zDp1TlhYl6WgrOHuJkJQ6M8zHEcntSJsUp1XFZSY8C1DYbg==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.55.1.tgz",
"integrity": "sha512-xzm44KgEP11te3S2HCSyYf5zIzWmx3n8HDCc7EE59+lTcswEWNpvMLfd9uJvVX8LCg9QWG67Xt75AuHn4vgsXw==",
"cpu": [
"arm64"
],
@@ -2844,9 +2886,9 @@
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.5.tgz",
"integrity": "sha512-nggc/wPpNTgjGg75hu+Q/3i32R00Lq1B6N1DO7MCU340MRKL3WZJMjA9U4K4gzy3dkZPXm9E1Nc81FItBVGRlA==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.55.1.tgz",
"integrity": "sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g==",
"cpu": [
"arm64"
],
@@ -2858,9 +2900,9 @@
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.5.tgz",
"integrity": "sha512-U/54pTbdQpPLBdEzCT6NBCFAfSZMvmjr0twhnD9f4EIvlm9wy3jjQ38yQj1AGznrNO65EWQMgm/QUjuIVrYF9w==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.55.1.tgz",
"integrity": "sha512-3fZBidchE0eY0oFZBnekYCfg+5wAB0mbpCBuofh5mZuzIU/4jIVkbESmd2dOsFNS78b53CYv3OAtwqkZZmU5nA==",
"cpu": [
"ia32"
],
@@ -2872,9 +2914,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-gnu": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.5.tgz",
"integrity": "sha512-2NqKgZSuLH9SXBBV2dWNRCZmocgSOx8OJSdpRaEcRlIfX8YrKxUT6z0F1NpvDVhOsl190UFTRh2F2WDWWCYp3A==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.55.1.tgz",
"integrity": "sha512-xGGY5pXj69IxKb4yv/POoocPy/qmEGhimy/FoTpTSVju3FYXUQQMFCaZZXJVidsmGxRioZAwpThl/4zX41gRKg==",
"cpu": [
"x64"
],
@@ -2886,9 +2928,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.5.tgz",
"integrity": "sha512-JRpZUhCfhZ4keB5v0fe02gQJy05GqboPOaxvjugW04RLSYYoB/9t2lx2u/tMs/Na/1NXfY8QYjgRljRpN+MjTQ==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.55.1.tgz",
"integrity": "sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw==",
"cpu": [
"x64"
],
@@ -4508,9 +4550,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001761",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001761.tgz",
"integrity": "sha512-JF9ptu1vP2coz98+5051jZ4PwQgd2ni8A+gYSN7EA7dPKIMf0pDlSUxhdmVOaV3/fYK5uWBkgSXJaRLr4+3A6g==",
"version": "1.0.30001762",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001762.tgz",
"integrity": "sha512-PxZwGNvH7Ak8WX5iXzoK1KPZttBXNPuaOvI2ZYU7NrlM+d9Ov+TUvlLOBNGzVXAntMSMMlJPd+jY6ovrVjSmUw==",
"dev": true,
"funding": [
{
@@ -6183,9 +6225,9 @@
}
},
"node_modules/fastq": {
"version": "1.19.1",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
"integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
"version": "1.20.1",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
"integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -7082,9 +7124,9 @@
}
},
"node_modules/i18next-chained-backend": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/i18next-chained-backend/-/i18next-chained-backend-4.6.2.tgz",
"integrity": "sha512-2P092fR+nAPQlGzPUoIIxbwo7PTBqQYgLxwv1XhSTQUAUoelLo5LkX+FqRxxSDg9WEAsrc8+2WL6mJtMGIa6WQ==",
"version": "4.6.3",
"resolved": "https://registry.npmjs.org/i18next-chained-backend/-/i18next-chained-backend-4.6.3.tgz",
"integrity": "sha512-Yg4hAKg/98zRAMQs87vJSNevTzaPPrYF3Eb7Kpx+UEaaXLd3p69g7dulAL+hpmZQHeMQ/5gFqHVtdwva53mB0Q==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.23.2"
@@ -9650,9 +9692,9 @@
"license": "MIT"
},
"node_modules/qs": {
"version": "6.14.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
"integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
"version": "6.14.1",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz",
"integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -10036,9 +10078,9 @@
}
},
"node_modules/rollup": {
"version": "4.53.5",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.5.tgz",
"integrity": "sha512-iTNAbFSlRpcHeeWu73ywU/8KuU/LZmNCSxp6fjQkJBD3ivUb8tpDrXhIxEzA05HlYMEwmtaUnb3RP+YNv162OQ==",
"version": "4.55.1",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.55.1.tgz",
"integrity": "sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -10052,28 +10094,31 @@
"npm": ">=8.0.0"
},
"optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.53.5",
"@rollup/rollup-android-arm64": "4.53.5",
"@rollup/rollup-darwin-arm64": "4.53.5",
"@rollup/rollup-darwin-x64": "4.53.5",
"@rollup/rollup-freebsd-arm64": "4.53.5",
"@rollup/rollup-freebsd-x64": "4.53.5",
"@rollup/rollup-linux-arm-gnueabihf": "4.53.5",
"@rollup/rollup-linux-arm-musleabihf": "4.53.5",
"@rollup/rollup-linux-arm64-gnu": "4.53.5",
"@rollup/rollup-linux-arm64-musl": "4.53.5",
"@rollup/rollup-linux-loong64-gnu": "4.53.5",
"@rollup/rollup-linux-ppc64-gnu": "4.53.5",
"@rollup/rollup-linux-riscv64-gnu": "4.53.5",
"@rollup/rollup-linux-riscv64-musl": "4.53.5",
"@rollup/rollup-linux-s390x-gnu": "4.53.5",
"@rollup/rollup-linux-x64-gnu": "4.53.5",
"@rollup/rollup-linux-x64-musl": "4.53.5",
"@rollup/rollup-openharmony-arm64": "4.53.5",
"@rollup/rollup-win32-arm64-msvc": "4.53.5",
"@rollup/rollup-win32-ia32-msvc": "4.53.5",
"@rollup/rollup-win32-x64-gnu": "4.53.5",
"@rollup/rollup-win32-x64-msvc": "4.53.5",
"@rollup/rollup-android-arm-eabi": "4.55.1",
"@rollup/rollup-android-arm64": "4.55.1",
"@rollup/rollup-darwin-arm64": "4.55.1",
"@rollup/rollup-darwin-x64": "4.55.1",
"@rollup/rollup-freebsd-arm64": "4.55.1",
"@rollup/rollup-freebsd-x64": "4.55.1",
"@rollup/rollup-linux-arm-gnueabihf": "4.55.1",
"@rollup/rollup-linux-arm-musleabihf": "4.55.1",
"@rollup/rollup-linux-arm64-gnu": "4.55.1",
"@rollup/rollup-linux-arm64-musl": "4.55.1",
"@rollup/rollup-linux-loong64-gnu": "4.55.1",
"@rollup/rollup-linux-loong64-musl": "4.55.1",
"@rollup/rollup-linux-ppc64-gnu": "4.55.1",
"@rollup/rollup-linux-ppc64-musl": "4.55.1",
"@rollup/rollup-linux-riscv64-gnu": "4.55.1",
"@rollup/rollup-linux-riscv64-musl": "4.55.1",
"@rollup/rollup-linux-s390x-gnu": "4.55.1",
"@rollup/rollup-linux-x64-gnu": "4.55.1",
"@rollup/rollup-linux-x64-musl": "4.55.1",
"@rollup/rollup-openbsd-x64": "4.55.1",
"@rollup/rollup-openharmony-arm64": "4.55.1",
"@rollup/rollup-win32-arm64-msvc": "4.55.1",
"@rollup/rollup-win32-ia32-msvc": "4.55.1",
"@rollup/rollup-win32-x64-gnu": "4.55.1",
"@rollup/rollup-win32-x64-msvc": "4.55.1",
"fsevents": "~2.3.2"
}
},
@@ -10129,9 +10174,9 @@
"license": "MIT"
},
"node_modules/sass": {
"version": "1.97.1",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.97.1.tgz",
"integrity": "sha512-uf6HoO8fy6ClsrShvMgaKUn14f2EHQLQRtpsZZLeU/Mv0Q1K5P0+x2uvH6Cub39TVVbWNSrraUhDAoFph6vh0A==",
"version": "1.97.2",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.97.2.tgz",
"integrity": "sha512-y5LWb0IlbO4e97Zr7c3mlpabcbBtS+ieiZ9iwDooShpFKWXf62zz5pEPdwrLYm+Bxn1fnbwFGzHuCLSA9tBmrw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -11577,7 +11622,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"
},
@@ -11710,9 +11755,9 @@
}
},
"node_modules/watchpack": {
"version": "2.4.4",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz",
"integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==",
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.0.tgz",
"integrity": "sha512-e6vZvY6xboSwLz2GD36c16+O/2Z6fKvIf4pOXptw2rY9MVwE/TXc6RGqxD3I3x0a28lwBY7DE+76uTPSsBrrCA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -12288,9 +12333,9 @@
"license": "ISC"
},
"node_modules/ws": {
"version": "8.18.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
"integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
"version": "8.19.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz",
"integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==",
"dev": true,
"license": "MIT",
"engines": {

View File

@@ -34,12 +34,14 @@ $(document).ready(function () {
$('input[name="ignore_budget"]').attr('checked', false);
});
$('input[name="tags"]').on('itemAdded', function (event) {
var isChecked = $('#tags_action_do_nothing').is(':checked');
if (true === isChecked) {
$('#tags_action_do_nothing').attr('checked', false);
$('#tags_action_do_replace').attr('checked', true);
}
$('input[name="tags"]').on('itemAdded', function(event) {
$('#tags_action_do_nothing').attr('checked', false);
$('#tags_action_do_replace').attr('checked', true);
});
});
});

View File

@@ -68,8 +68,8 @@ export default {
props: ['source', 'destination', 'transactionType', 'value', 'error', 'no_currency', 'title',],
mounted() {
this.liability = false;
// console.log('I am mounted with a ' + this.transactionType + ' transaction type and currency id!');
// console.log(this.value);
console.log('ForeignAmountSelect is mounted with a ' + this.transactionType + ' transaction type and currency id!');
console.log(this.value);
this.loadCurrencies();
},
data() {
@@ -124,23 +124,25 @@ export default {
let sourceIsLiability = liabilities.indexOf(srcType) !== -1;
let destIsLiability = liabilities.indexOf(destType) !== -1;
// console.log(srcType + ' (source) is a liability: ' + sourceIsLiability);
// console.log(destType + ' (dest) is a liability: ' + destIsLiability);
// console.log('tType: ' + tType);
if (tType === 'transfer' || destIsLiability || sourceIsLiability) {
// console.log('Source is liability OR dest is liability, OR transfer. Lock list on currency of destination.');
console.log('Source or dest is a liability.')
console.log('Source is liability OR dest is liability, OR transfer. Lock list on currency of destination.');
// console.log('Length of currencies is ' + this.currencies.length);
// console.log(this.currencies);
this.liability = true;
// lock dropdown list on currencyID of destination.
// lock dropdown list on currencyID of destination UNLESS dest is not liab
for (const key in this.currencies) {
if (this.currencies.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
if (
parseInt(this.currencies[key].id) === parseInt(this.destination.currency_id)
parseInt(this.currencies[key].id) === parseInt(this.destination.currency_id) || !destIsLiability
) {
// console.log('Enable currency!!');
console.log('Enable currency!!');
console.log(this.currencies[key]);
// console.log(this.destination);
// console.log(this.currencies[key]);
this.enabledCurrencies.push(this.currencies[key]);
}
}
@@ -151,6 +153,7 @@ export default {
// if type is withdrawal, list all but skip the source account ID.
if (tType === 'withdrawal' && this.source && false === sourceIsLiability) {
console.log('Type is withdrawal, there is a source, it is not a liability.')
for (const key in this.currencies) {
if (this.currencies.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) {
if (this.source.currency_id !== this.currencies[key].id) {

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',
@@ -149,6 +150,9 @@ return [
'left_in_budget_limit' => 'Left to spend according to budgeting',
'current_period' => 'Current period',
'show_the_current_period_and_overview' => 'Show the current period and overview',
'pref_anonymous' => 'Hidden amounts',
'pref_anonymous_help' => 'For privacy and anonymity, you can make Firefly III hide all amounts. This will not hide amounts in edit boxes, but the rest are hidden. You can also toggle this with the little "eye"-icon in the top bar.',
'pref_anonymous_label' => 'Hide amounts',
'pref_languages_locale' => 'For a language other than English to work properly, your operating system must be equipped with the correct locale-information. If these are not present, currency data, dates and amounts may be formatted wrong.',
'budget_in_period' => 'All transactions for budget ":name" between :start and :end in :currency',
'chart_budget_in_period' => 'Chart for all transactions for budget ":name" between :start and :end in :currency',
@@ -2908,6 +2912,7 @@ return [
'placeholder' => '[Placeholder]',
// audit log entries
'incomplete_ale' => 'Not all events are recorded as audit log entries.',
'audit_log_entries' => 'Audit log entries',
'ale_action_log_add' => 'Added :amount to piggy bank ":name"',
'ale_action_log_remove' => 'Removed :amount from piggy bank ":name"',

View File

@@ -1,16 +1,21 @@
<table class="table" aria-label="Table">
<thead>
<tr>
<td colspan="3"><em>{{ 'incomplete_ale'|_ }}</em></td>
</tr>
</thead>
<tbody>
{% for logEntry in logEntries %}
<tr>
<th style="width:20%;" scope="row">
{# link to object: #}
{% if 'FireflyIII\\Models\\Rule' == logEntry.changer_type %}
<a href="{{ route('rules.edit', [logEntry.changer_id] ) }}">
{% endif %}
<a href="{{ route('rules.edit', [logEntry.changer_id] ) }}">
{% endif %}
{% if 'FireflyIII\\User' == logEntry.changer_type %}
<a href="{{ route('profile.index') }}">
{% endif %}
{{ logEntry.changer_type|replace({"FireflyIII\\Models\\": ""})|replace({"FireflyIII\\": ""}) }}
#{{ logEntry.changer_id }}
{{ logEntry.changer_type|replace({"FireflyIII\\Models\\": ""})|replace({"FireflyIII\\": ""}) }} #{{ logEntry.changer_id }}
</a>
</th>
<td style="width:30%;" title="{{ logEntry.created_at.isoFormat(dateTimeFormat) }}">
@@ -103,4 +108,5 @@
</tr>
{% endfor %}
</tbody>
</table>

View File

@@ -33,7 +33,7 @@
<th class="hidden-xs">&nbsp;</th>
<th>{{ trans('list.description') }}</th>
<th>{{ trans('list.amount') }}</th>
{% if FireflyConfig.get('use_running_balance', config('firefly.feature_flags.running_balance_column')) %}
{% if fireflyiiiconfig('use_running_balance', true) %}
<th>{{ trans('list.running_balance') }}</th>
{% endif %}
<th>{{ trans('list.date') }}</th>
@@ -266,14 +266,15 @@
{% endif %}
{% endif %}
</td>
{% if FireflyConfig.get('use_running_balance', config('firefly.feature_flags.running_balance_column')) %}
{% if (fireflyiiiconfig('use_running_balance', true)) %}
<td>
{# RUNNING BALANCE #}
{% if (null == transaction.balance_dirty or false == transaction.balance_dirty) and null != transaction.destination_balance_after and null != transaction.source_balance_after %}
{% if transaction.transaction_type_type == 'Deposit' %}
{% if transaction.source_account_id == account.id %}
{{ formatAmountBySymbol(transaction.source_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}
<span title="Deposit, source">{{ formatAmountBySymbol(transaction.source_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}</span>
{% else %}
{{ formatAmountBySymbol(transaction.destination_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}
<span title="Deposit, dest">{{ formatAmountBySymbol(transaction.destination_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}</span>
{% endif %}
{% elseif transaction.transaction_type_type == 'Withdrawal' %}
@@ -281,39 +282,39 @@
{% if 'Loan' == transaction.destination_account_type or 'Mortgage' == transaction.destination_account_type or 'Debt' == transaction.destination_account_type %}
{% if currency.id == transaction.currency_id %}
{% if account.id == transaction.source_account_id %}
{{ formatAmountBySymbol(transaction.source_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}
<span title="Withdrawal, liab, source">{{ formatAmountBySymbol(transaction.source_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}</span>
{% elseif account.id == transaction.destination_account_id %}
{{ formatAmountBySymbol(transaction.destination_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}
<span title="Withdrawal, liab, dest">{{ formatAmountBySymbol(transaction.destination_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}</span>
{% else %}
-
{% endif %}
{% endif %}
{% if currency.id == transaction.foreign_currency_id and null != transaction.destination_balance_after and null != transaction.destination_balance_after %}
{{ formatAmountBySymbol(transaction.destination_balance_after, transaction.foreign_currency_symbol ?? transaction.currency_symbol, transaction.foreign_currency_decimal_places ?? transaction.currency_decimal_places) }}
<span title="Withdrawal, liab, dest 2">{{ formatAmountBySymbol(transaction.destination_balance_after, transaction.foreign_currency_symbol ?? transaction.currency_symbol, transaction.foreign_currency_decimal_places ?? transaction.currency_decimal_places) }}</span>
{% endif %}
{# withdrawal into an expense account #}
{% else %}
{% if account.id == transaction.source_account_id %}
{{ formatAmountBySymbol(transaction.source_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}
<span title="Withdrawal, source">{{ formatAmountBySymbol(transaction.source_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}</span>
{% elseif account.id == transaction.destination_account_id %}
{{ formatAmountBySymbol(transaction.destination_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}
<span title="Withdrawal, dest">{{ formatAmountBySymbol(transaction.destination_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}</span>
{% else %}
-
{% endif %}
{% endif %}
{% elseif transaction.transaction_type_type == 'Opening balance' %}
{% if account.id == transaction.source_account_id %}
{{ formatAmountBySymbol(transaction.destination_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}
<span title="Opening balance, dest">{{ formatAmountBySymbol(transaction.destination_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}</span>
{% elseif account.id == transaction.destination_account_id %}
{{ formatAmountBySymbol(transaction.source_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}
{% else %}
<span title="Opening balance, src">{{ formatAmountBySymbol(transaction.source_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}</span>
{% else %}
-
{% endif %}
{% elseif transaction.transaction_type_type == 'Transfer' %}
{% if account.id == transaction.source_account_id %}
{{ formatAmountBySymbol(transaction.source_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}
<span title="Transfer, source">{{ formatAmountBySymbol(transaction.source_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}</span>
{% else %}
{{ formatAmountBySymbol(transaction.destination_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}
<span title="Transfer, dest">{{ formatAmountBySymbol(transaction.destination_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}</span>
{% endif %}
{% else %}
&nbsp;

View File

@@ -119,11 +119,11 @@
</tr>
<tr>
<td>Exchange rates</td>
<td>{% if FireflyConfig.get('enable_exchange_rates', config('cer.enabled')) %}Enabled{% else %}Disabled{% endif %}, downloads {% if FireflyConfig.get('enable_external_rates', config('cer.download_enabled')) %}enabled{% else %}disabled{% endif %}</td>
<td>{% if fireflyiiiconfig('enable_exchange_rates', true) %}Enabled{% else %}Disabled{% endif %}, downloads {% if FireflyConfig.get('enable_external_rates', config('cer.download_enabled')) %}enabled{% else %}disabled{% endif %}</td>
</tr>
<tr>
<td>RB-column</td>
<td>{% if FireflyConfig.get('use_running_balance', config('firefly.feature_flags.running_balance_column')) %}Enabled{% else %}Disabled{% endif %}</td>
<td>{% if fireflyiiiconfig('use_running_balance', true) %}Enabled{% else %}Disabled{% endif %}</td>
</tr>
</tbody>
</table>

View File

@@ -226,7 +226,7 @@
<span>{{ 'currencies'|_ }}</span>
</a>
</li>
{% if FireflyConfig.get('enable_exchange_rates', config('cer.enabled')) %}
{% if (fireflyiiiconfig('enable_exchange_rates', true)) %}
<li class="{{ activeRoutePartial('exchange-rates') }}">
<a class="{{ activeRoutePartial('exchange-rates') }}" href="{{ route('exchange-rates.index') }}">
<span class="fa fa-angle-right fa-fw"></span>

View File

@@ -36,7 +36,7 @@
<td style="width:40%;">{{ 'saveOnAccounts'|_ }}</td>
<td>
{% for account in piggy.accounts %}
<a href="{{ route('accounts.show', account.id) }}">{{ account.name }}</a><br>
<a href="{{ route('accounts.show', [account.account_id]) }}">{{ account.name }}</a><br>
{% endfor %}
</td>
</tr>
@@ -58,7 +58,7 @@
<tr>
<td>
{{ 'saved_so_far'|_ }}
(<a href="{{ route('accounts.show', account.id) }}">{{ account.name }}</a>)
(<a href="{{ route('accounts.show', account.account_id) }}">{{ account.name }}</a>)
</td>
<td>
{{ formatAmountBySymbol(account.current_amount, piggy.currency_symbol, piggy.currency_decimal_places) }}

View File

@@ -101,7 +101,7 @@
</div>
{# conversion back to primary currency #}
{% if FireflyConfig.get('enable_exchange_rates', config('cer.enabled')) %}
{% if fireflyiiiconfig('enable_exchange_rates', true) %}
<div class="preferences-box">
<h3>{{ 'pref_convert_to_primary'|_ }}</h3>
<p class="text-info">
@@ -110,6 +110,14 @@
{{ ExpandedForm.checkbox('convertToPrimary','1',convertToPrimary,{ 'label' : 'pref_convert_primary_help'|_ }) }}
</div>
{% endif %}
{# conversion back to primary currency #}
<div class="preferences-box">
<h3>{{ 'pref_anonymous'|_ }}</h3>
<p class="text-info">
{{ 'pref_anonymous_help'|_ }}
</p>
{{ ExpandedForm.checkbox('anonymous','1',anonymous,{ 'label' : 'pref_anonymous_label'|_ }) }}
</div>
</div>
{# general settings column B #}

View File

@@ -20,7 +20,7 @@
<div class="form-group">
<label for="query" class="col-sm-1 control-label">{{ 'search_query'|_ }}</label>
<div class="col-sm-10">
<input autocomplete="off" maxlength="255" type="text" name="search" id="query" value="{{ fullQuery }}" class="form-control" spellcheck="false"
<input autocomplete="off" type="text" name="search" id="query" value="{{ fullQuery }}" class="form-control" spellcheck="false"
placeholder="{{ fullQuery }}">
</div>
</div>