From bf8c40d50201014b2a343b6e2c87fca1cfd6c091 Mon Sep 17 00:00:00 2001 From: JC5 Date: Sun, 29 Mar 2026 16:46:09 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=A4=96=20Auto=20commit=20for=20release=20?= =?UTF-8?q?'develop'=20on=202026-03-29?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Models/PiggyBank/UpdateRequest.php | 6 +- .../Correction/CorrectsGroupAccounts.php | 1 + app/Factory/PiggyBankFactory.php | 3 +- .../ProcessesUpdatedTransactionGroup.php | 17 +++--- .../PiggyBankRepositoryInterface.php | 1 + app/Rules/PiggyBank/IsEnoughInAccounts.php | 19 ++++-- app/Support/Request/ConvertsDataTypes.php | 4 +- composer.lock | 53 ++++++++--------- config/firefly.php | 4 +- package-lock.json | 58 +++++++++++-------- resources/lang/en_US/validation.php | 2 +- 11 files changed, 94 insertions(+), 74 deletions(-) diff --git a/app/Api/V1/Requests/Models/PiggyBank/UpdateRequest.php b/app/Api/V1/Requests/Models/PiggyBank/UpdateRequest.php index 4271b52ba7..7f46f1ee18 100644 --- a/app/Api/V1/Requests/Models/PiggyBank/UpdateRequest.php +++ b/app/Api/V1/Requests/Models/PiggyBank/UpdateRequest.php @@ -31,7 +31,6 @@ use FireflyIII\Rules\LessThanPiggyTarget; use FireflyIII\Rules\PiggyBank\IsEnoughInAccounts; use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ConvertsDataTypes; -use FireflyIII\Validation\FireflyValidator; use Illuminate\Foundation\Http\FormRequest; /** @@ -49,7 +48,7 @@ class UpdateRequest extends FormRequest */ public function getAll(): array { - $fields = [ + $fields = [ 'name' => ['name', 'convertString'], 'target_amount' => ['target_amount', 'convertString'], 'start_date' => ['start_date', 'convertDateTime'], @@ -77,7 +76,7 @@ class UpdateRequest extends FormRequest $piggyBank = $this->route()->parameter('piggyBank'); return [ - 'name' => 'min:1|max:255|uniquePiggyBankForUser:' . $piggyBank->id, + 'name' => 'min:1|max:255|uniquePiggyBankForUser:'.$piggyBank->id, 'current_amount' => ['nullable', new LessThanPiggyTarget(), new IsValidPositiveAmount()], 'target_amount' => ['nullable', new IsValidZeroOrMoreAmount()], 'start_date' => 'date|nullable', @@ -93,5 +92,4 @@ class UpdateRequest extends FormRequest 'transaction_currency_code' => 'exists:transaction_currencies,code|nullable', ]; } - } diff --git a/app/Console/Commands/Correction/CorrectsGroupAccounts.php b/app/Console/Commands/Correction/CorrectsGroupAccounts.php index 8d69249916..15b8bc54ec 100644 --- a/app/Console/Commands/Correction/CorrectsGroupAccounts.php +++ b/app/Console/Commands/Correction/CorrectsGroupAccounts.php @@ -70,6 +70,7 @@ class CorrectsGroupAccounts extends Command event(new UpdatedSingleTransactionGroup($flags, $objects)); event(new WebhookMessagesRequestSending()); Log::debug('End of correction:group-accounts'); + return 0; } } diff --git a/app/Factory/PiggyBankFactory.php b/app/Factory/PiggyBankFactory.php index d21abb917c..135bf7f266 100644 --- a/app/Factory/PiggyBankFactory.php +++ b/app/Factory/PiggyBankFactory.php @@ -135,8 +135,9 @@ class PiggyBankFactory $diff = bcsub($info['current_amount'], $previous); // if money is added, check if we can! - if(1 === bccomp($diff, '0') && !$this->piggyBankRepository->canAddAmount($piggyBank, $account, $diff)) { + if (1 === bccomp($diff, '0') && !$this->piggyBankRepository->canAddAmount($piggyBank, $account, $diff)) { Log::debug(sprintf('Cannot add amount %s to piggy bank #%d ("%s")', $diff, $piggyBank->id, $piggyBank->name)); + continue; } diff --git a/app/Listeners/Model/TransactionGroup/ProcessesUpdatedTransactionGroup.php b/app/Listeners/Model/TransactionGroup/ProcessesUpdatedTransactionGroup.php index 46aa099edf..e79e80244a 100644 --- a/app/Listeners/Model/TransactionGroup/ProcessesUpdatedTransactionGroup.php +++ b/app/Listeners/Model/TransactionGroup/ProcessesUpdatedTransactionGroup.php @@ -116,23 +116,26 @@ class ProcessesUpdatedTransactionGroup $destAccount = $first->transactions()->where('amount', '>', '0')->first()->account; $type = $first->transactionType->type; - $effect = 0; + $effect = 0; if (TransactionTypeEnum::TRANSFER->value === $type || TransactionTypeEnum::WITHDRAWAL->value === $type) { // set all source transactions to source account: $effect += Transaction::whereIn('transaction_journal_id', $all) - ->where('account_id', '!=', $sourceAccount->id) - ->where('amount', '<', 0) - ->update(['account_id' => $sourceAccount->id]); + ->where('account_id', '!=', $sourceAccount->id) + ->where('amount', '<', 0) + ->update(['account_id' => $sourceAccount->id]) + ; } if (TransactionTypeEnum::TRANSFER->value === $type || TransactionTypeEnum::DEPOSIT->value === $type) { // set all destination transactions to destination account: $effect += Transaction::whereIn('transaction_journal_id', $all) ->where('account_id', '!=', $destAccount->id) - ->where('amount', '>', 0) - ->update(['account_id' => $destAccount->id]); + ->where('amount', '>', 0) + ->update(['account_id' => $destAccount->id]) + ; } - if(0 === $effect) { + if (0 === $effect) { Log::debug(sprintf('Had nothing to do in unifyAccounts(#%d)', $group->id)); + return; } Log::debug(sprintf('Updated %d transaction(s) in unifyAccounts(#%d)', $effect, $group->id)); diff --git a/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php b/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php index 8ceb899052..bdcd9d138e 100644 --- a/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php +++ b/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php @@ -52,6 +52,7 @@ interface PiggyBankRepositoryInterface public function addAmountToPiggyBank(PiggyBank $piggyBank, string $amount, TransactionJournal $journal): void; public function canAddAmount(PiggyBank $piggyBank, Account $account, string $amount): bool; + public function canRemoveAmount(PiggyBank $piggyBank, Account $account, string $amount): bool; /** diff --git a/app/Rules/PiggyBank/IsEnoughInAccounts.php b/app/Rules/PiggyBank/IsEnoughInAccounts.php index ecbab27737..0f963dbcd1 100644 --- a/app/Rules/PiggyBank/IsEnoughInAccounts.php +++ b/app/Rules/PiggyBank/IsEnoughInAccounts.php @@ -1,4 +1,7 @@ data)) { return; } + /** @var AccountRepositoryInterface $repository */ $repository = app(AccountRepositoryInterface::class); + /** @var PiggyBankRepositoryInterface $piggyRepos */ $piggyRepos = app(PiggyBankRepositoryInterface::class); - $accounts = $this->data['accounts']; + $accounts = $this->data['accounts']; foreach ($accounts as $info) { - $account = $repository->find((int)$info['account_id']); + $account = $repository->find((int) $info['account_id']); $amount = $info['current_amount'] ?? '0'; if (null === $account) { $fail('validation.no_asset_account')->translate(); + return; } if ('' === $amount || 0 === bccomp($amount, '0')) { $fail('validation.more_than_zero_correct')->translate(); + return; } - $diff = bcsub($amount, $piggyRepos->getCurrentAmount($this->piggyBank, $account)); + $diff = bcsub($amount, $piggyRepos->getCurrentAmount($this->piggyBank, $account)); if (1 === bccomp($diff, '0') && !$piggyRepos->canAddAmount($this->piggyBank, $account, $amount)) { $fail('validation.cannot_add_piggy_amount')->translate(); } diff --git a/app/Support/Request/ConvertsDataTypes.php b/app/Support/Request/ConvertsDataTypes.php index 8337c6eb98..818fcd44de 100644 --- a/app/Support/Request/ConvertsDataTypes.php +++ b/app/Support/Request/ConvertsDataTypes.php @@ -475,8 +475,8 @@ trait ConvertsDataTypes $amount = null; } $return[] = [ - 'account_id' => $this->integerFromValue((string) ($entry['account_id'] ?? '0')), - 'current_amount' => $amount + 'account_id' => $this->integerFromValue((string) ($entry['account_id'] ?? '0')), + 'current_amount' => $amount, ]; } diff --git a/composer.lock b/composer.lock index 0f00f9fe7b..99ddce139e 100644 --- a/composer.lock +++ b/composer.lock @@ -1009,16 +1009,16 @@ }, { "name": "firebase/php-jwt", - "version": "v7.0.3", + "version": "v7.0.4", "source": { "type": "git", "url": "https://github.com/firebase/php-jwt.git", - "reference": "28aa0694bcfdfa5e2959c394d5a1ee7a5083629e" + "reference": "e41f1bd7dbe3c5455c3f72d4338cfeb083b71931" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/firebase/php-jwt/zipball/28aa0694bcfdfa5e2959c394d5a1ee7a5083629e", - "reference": "28aa0694bcfdfa5e2959c394d5a1ee7a5083629e", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/e41f1bd7dbe3c5455c3f72d4338cfeb083b71931", + "reference": "e41f1bd7dbe3c5455c3f72d4338cfeb083b71931", "shasum": "" }, "require": { @@ -1026,6 +1026,7 @@ }, "require-dev": { "guzzlehttp/guzzle": "^7.4", + "phpfastcache/phpfastcache": "^9.2", "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.5", "psr/cache": "^2.0||^3.0", @@ -1066,9 +1067,9 @@ ], "support": { "issues": "https://github.com/firebase/php-jwt/issues", - "source": "https://github.com/firebase/php-jwt/tree/v7.0.3" + "source": "https://github.com/firebase/php-jwt/tree/v7.0.4" }, - "time": "2026-02-25T22:16:40+00:00" + "time": "2026-03-27T21:17:19+00:00" }, { "name": "fruitcake/php-cors", @@ -10173,22 +10174,22 @@ }, { "name": "cloudcreativity/json-api-testing", - "version": "v6.2.0", + "version": "v6.3.0", "source": { "type": "git", "url": "https://github.com/cloudcreativity/json-api-testing.git", - "reference": "bb2ff0a87013d40781ca7f959023491d6f1b4ed2" + "reference": "c6f1460dae648a28217b182195f8ca4ed0ee9bd5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cloudcreativity/json-api-testing/zipball/bb2ff0a87013d40781ca7f959023491d6f1b4ed2", - "reference": "bb2ff0a87013d40781ca7f959023491d6f1b4ed2", + "url": "https://api.github.com/repos/cloudcreativity/json-api-testing/zipball/c6f1460dae648a28217b182195f8ca4ed0ee9bd5", + "reference": "c6f1460dae648a28217b182195f8ca4ed0ee9bd5", "shasum": "" }, "require": { "ext-json": "*", - "illuminate/contracts": "^10.0|^11.0|^12.0", - "illuminate/support": "^10.0|^11.0|^12.0", + "illuminate/contracts": "^10.0|^11.0|^12.0|^13.0", + "illuminate/support": "^10.0|^11.0|^12.0|^13.0", "php": "^8.2", "phpunit/phpunit": "^10.5|^11.0|^12.0" }, @@ -10225,9 +10226,9 @@ ], "support": { "issues": "https://github.com/cloudcreativity/json-api/issues", - "source": "https://github.com/cloudcreativity/json-api-testing/tree/v6.2.0" + "source": "https://github.com/cloudcreativity/json-api-testing/tree/v6.3.0" }, - "time": "2025-04-09T19:15:46+00:00" + "time": "2026-03-28T18:04:28+00:00" }, { "name": "composer/class-map-generator", @@ -10835,28 +10836,28 @@ }, { "name": "laravel-json-api/testing", - "version": "v3.1.0", + "version": "v3.2.0", "source": { "type": "git", "url": "https://github.com/laravel-json-api/testing.git", - "reference": "bbf3b31b977955eff93c47ff101c4a134a3ffa8f" + "reference": "506d434a47ebd9bcc7dfca0096c63b79d28427a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel-json-api/testing/zipball/bbf3b31b977955eff93c47ff101c4a134a3ffa8f", - "reference": "bbf3b31b977955eff93c47ff101c4a134a3ffa8f", + "url": "https://api.github.com/repos/laravel-json-api/testing/zipball/506d434a47ebd9bcc7dfca0096c63b79d28427a8", + "reference": "506d434a47ebd9bcc7dfca0096c63b79d28427a8", "shasum": "" }, "require": { - "cloudcreativity/json-api-testing": "^6.1", + "cloudcreativity/json-api-testing": "^6.3", "ext-json": "*", - "illuminate/http": "^11.0|^12.0", - "illuminate/support": "^11.0|^12.0", - "illuminate/testing": "^11.0|^12.0", + "illuminate/http": "^11.0|^12.0|^13.0", + "illuminate/support": "^11.0|^12.0|^13.0", + "illuminate/testing": "^11.0|^12.0|^13.0", "php": "^8.2" }, "require-dev": { - "laravel/framework": "^11.0|^12.0", + "laravel/framework": "^11.0|^12.0|^13.0", "phpunit/phpunit": "^10.5|^11.0" }, "type": "library", @@ -10881,7 +10882,7 @@ }, { "name": "Christopher Gammie", - "email": "contact@gammie.co.uk" + "email": "chris@cloudcreativity.co.uk" } ], "description": "Test helpers for JSON:API compliant APIs.", @@ -10894,9 +10895,9 @@ ], "support": { "issues": "https://github.com/laravel-json-api/testing/issues", - "source": "https://github.com/laravel-json-api/testing/tree/v3.1.0" + "source": "https://github.com/laravel-json-api/testing/tree/v3.2.0" }, - "time": "2025-02-24T20:39:08+00:00" + "time": "2026-03-28T18:06:47+00:00" }, { "name": "mockery/mockery", diff --git a/config/firefly.php b/config/firefly.php index 5d33516720..9b785e8045 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -78,8 +78,8 @@ return [ 'running_balance_column' => (bool)envDefaultWhenEmpty(env('USE_RUNNING_BALANCE'), true), // this is only the default value, is not used. // see cer.php for exchange rates feature flag. ], - 'version' => 'develop/2026-03-27', - 'build_time' => 1774582537, + 'version' => 'develop/2026-03-29', + 'build_time' => 1774795378, 'api_version' => '2.1.0', // field is no longer used. 'db_version' => 28, // field is no longer used. diff --git a/package-lock.json b/package-lock.json index 819ebde76b..c58dcd15dd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1709,6 +1709,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "dependencies": { "@emnapi/wasi-threads": "1.2.0", "tslib": "^2.4.0" @@ -1721,6 +1722,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "dependencies": { "tslib": "^2.4.0" } @@ -1732,6 +1734,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "dependencies": { "tslib": "^2.4.0" } @@ -1840,20 +1843,22 @@ "license": "MIT" }, "node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.1.tgz", - "integrity": "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.2.tgz", + "integrity": "sha512-sNXv5oLJ7ob93xkZ1XnxisYhGYXfaG9f65/ZgYuAu3qt7b3NadcOEhLvx28hv31PgX8SZJRYrAIPQilQmFpLVw==", "dev": true, "license": "MIT", "optional": true, "dependencies": { - "@emnapi/core": "^1.7.1", - "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" }, "funding": { "type": "github", "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" } }, "node_modules/@nodelib/fs.scandir": { @@ -3380,9 +3385,9 @@ } }, "node_modules/alpinejs": { - "version": "3.15.8", - "resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.15.8.tgz", - "integrity": "sha512-zxIfCRTBGvF1CCLIOMQOxAyBuqibxSEwS6Jm1a3HGA9rgrJVcjEWlwLcQTVGAWGS8YhAsTRLVrtQ5a5QT9bSSQ==", + "version": "3.15.9", + "resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.15.9.tgz", + "integrity": "sha512-O30m8Tw/aARbLXmeTnISAFgrNm0K71PT7bZy/1NgRqFD36QGb34VJ4a6WBL1iIO/bofN+LkIkKLikUTkfPL2wQ==", "license": "MIT", "dependencies": { "@vue/reactivity": "~3.1.1" @@ -3565,15 +3570,15 @@ } }, "node_modules/axios": { - "version": "1.13.6", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz", - "integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.14.0.tgz", + "integrity": "sha512-3Y8yrqLSwjuzpXuZ0oIYZ/XGgLwUIBU3uLvbcpb0pidD9ctpShJd43KSlEEkVQg6DS0G9NKyzOvBfUtDKEyHvQ==", "dev": true, "license": "MIT", "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", - "proxy-from-env": "^1.1.0" + "proxy-from-env": "^2.1.0" } }, "node_modules/babel-loader": { @@ -3677,9 +3682,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.10.11", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.11.tgz", - "integrity": "sha512-DAKrHphkJyiGuau/cFieRYhcTFeK/lBuD++C7cZ6KZHbMhBrisoi+EvhQ5RZrIfV5qwsW8kgQ07JIC+MDJRAhg==", + "version": "2.10.12", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.12.tgz", + "integrity": "sha512-qyq26DxfY4awP2gIRXhhLWfwzwI+N5Nxk6iQi8EFizIaWIjqicQTE4sLnZZVdeKPRcVNoJOkkpfzoIYuvCKaIQ==", "dev": true, "license": "Apache-2.0", "bin": { @@ -3848,9 +3853,9 @@ "license": "MIT" }, "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "dev": true, "license": "MIT", "dependencies": { @@ -5333,9 +5338,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.327", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.327.tgz", - "integrity": "sha512-hLxLdIJDf8zIzKoH2TPCs+Botc+wUmj9sp4jVMwklY/sKleM8xxxOExRX3Gxj73nCXmJe3anhG7SvsDDPDvmuQ==", + "version": "1.5.328", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.328.tgz", + "integrity": "sha512-QNQ5l45DzYytThO21403XN3FvK0hOkWDG8viNf6jqS42msJ8I4tGDSpBCgvDRRPnkffafiwAym2X2eHeGD2V0w==", "dev": true, "license": "ISC" }, @@ -9460,11 +9465,14 @@ } }, "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=10" + } }, "node_modules/pseudomap": { "version": "1.0.2", diff --git a/resources/lang/en_US/validation.php b/resources/lang/en_US/validation.php index 2fb4e477df..dbe2d3d327 100644 --- a/resources/lang/en_US/validation.php +++ b/resources/lang/en_US/validation.php @@ -70,7 +70,7 @@ return [ 'rule_action_value' => 'This value is invalid for the selected action.', 'file_already_attached' => 'Uploaded file ":name" is already attached to this object.', 'file_attached' => 'Successfully uploaded file ":name".', - 'cannot_add_piggy_amount' => 'This amount cannot be added to the piggy bank.', + 'cannot_add_piggy_amount' => 'This amount cannot be added to the piggy bank.', 'file_zero' => 'The file is zero bytes in size.', 'must_exist' => 'The ID in field :attribute does not exist in the database.', 'all_accounts_equal' => 'All accounts in this field must be equal.',