mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2026-04-02 02:15:04 +00:00
Compare commits
23 Commits
develop-20
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1ac6949f95 | ||
|
|
43acafb7a7 | ||
|
|
ca85a4c034 | ||
|
|
22752559e1 | ||
|
|
a341cae6bb | ||
|
|
64035a71ea | ||
|
|
074ca1756d | ||
|
|
0aa73ccf96 | ||
|
|
85c37d8812 | ||
|
|
16eb2ca4ca | ||
|
|
f491155f9b | ||
|
|
c5706e95b7 | ||
|
|
fdabb2c994 | ||
|
|
615fa733e6 | ||
|
|
d3fc8673d3 | ||
|
|
db156ffcf2 | ||
|
|
59510a9acc | ||
|
|
7f9640087e | ||
|
|
29c51ad0e2 | ||
|
|
bf8c40d502 | ||
|
|
99912483de | ||
|
|
a3f4ab9b1b | ||
|
|
953fe7d9eb |
84
.ci/php-cs-fixer/composer.lock
generated
84
.ci/php-cs-fixer/composer.lock
generated
@@ -1264,16 +1264,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v8.0.7",
|
||||
"version": "v8.0.8",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "15ed9008a4ebe2d6a78e4937f74e0c13ef2e618a"
|
||||
"reference": "5b66d385dc58f69652e56f78a4184615e3f2b7f7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/15ed9008a4ebe2d6a78e4937f74e0c13ef2e618a",
|
||||
"reference": "15ed9008a4ebe2d6a78e4937f74e0c13ef2e618a",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/5b66d385dc58f69652e56f78a4184615e3f2b7f7",
|
||||
"reference": "5b66d385dc58f69652e56f78a4184615e3f2b7f7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1330,7 +1330,7 @@
|
||||
"terminal"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/console/tree/v8.0.7"
|
||||
"source": "https://github.com/symfony/console/tree/v8.0.8"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1350,7 +1350,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2026-03-06T14:06:22+00:00"
|
||||
"time": "2026-03-30T15:14:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/deprecation-contracts",
|
||||
@@ -1421,16 +1421,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
"version": "v8.0.4",
|
||||
"version": "v8.0.8",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/event-dispatcher.git",
|
||||
"reference": "99301401da182b6cfaa4700dbe9987bb75474b47"
|
||||
"reference": "f662acc6ab22a3d6d716dcb44c381c6002940df6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/99301401da182b6cfaa4700dbe9987bb75474b47",
|
||||
"reference": "99301401da182b6cfaa4700dbe9987bb75474b47",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/f662acc6ab22a3d6d716dcb44c381c6002940df6",
|
||||
"reference": "f662acc6ab22a3d6d716dcb44c381c6002940df6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1482,7 +1482,7 @@
|
||||
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/event-dispatcher/tree/v8.0.4"
|
||||
"source": "https://github.com/symfony/event-dispatcher/tree/v8.0.8"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1502,7 +1502,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2026-01-05T11:45:55+00:00"
|
||||
"time": "2026-03-30T15:14:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher-contracts",
|
||||
@@ -1652,16 +1652,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
"version": "v8.0.6",
|
||||
"version": "v8.0.8",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/finder.git",
|
||||
"reference": "441404f09a54de6d1bd6ad219e088cdf4c91f97c"
|
||||
"reference": "8da41214757b87d97f181e3d14a4179286151007"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/441404f09a54de6d1bd6ad219e088cdf4c91f97c",
|
||||
"reference": "441404f09a54de6d1bd6ad219e088cdf4c91f97c",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/8da41214757b87d97f181e3d14a4179286151007",
|
||||
"reference": "8da41214757b87d97f181e3d14a4179286151007",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1696,7 +1696,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.6"
|
||||
"source": "https://github.com/symfony/finder/tree/v8.0.8"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1716,20 +1716,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2026-01-29T09:41:02+00:00"
|
||||
"time": "2026-03-30T15:14:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/options-resolver",
|
||||
"version": "v8.0.0",
|
||||
"version": "v8.0.8",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/options-resolver.git",
|
||||
"reference": "d2b592535ffa6600c265a3893a7f7fd2bad82dd7"
|
||||
"reference": "b48bce0a70b914f6953dafbd10474df232ed4de8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/d2b592535ffa6600c265a3893a7f7fd2bad82dd7",
|
||||
"reference": "d2b592535ffa6600c265a3893a7f7fd2bad82dd7",
|
||||
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/b48bce0a70b914f6953dafbd10474df232ed4de8",
|
||||
"reference": "b48bce0a70b914f6953dafbd10474df232ed4de8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1767,7 +1767,7 @@
|
||||
"options"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/options-resolver/tree/v8.0.0"
|
||||
"source": "https://github.com/symfony/options-resolver/tree/v8.0.8"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1787,7 +1787,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-11-12T15:55:31+00:00"
|
||||
"time": "2026-03-30T15:14:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
@@ -2370,16 +2370,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v8.0.5",
|
||||
"version": "v8.0.8",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/process.git",
|
||||
"reference": "b5f3aa6762e33fd95efbaa2ec4f4bc9fdd16d674"
|
||||
"reference": "cb8939aff03470d1a9d1d1b66d08c6fa71b3bbdc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/b5f3aa6762e33fd95efbaa2ec4f4bc9fdd16d674",
|
||||
"reference": "b5f3aa6762e33fd95efbaa2ec4f4bc9fdd16d674",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/cb8939aff03470d1a9d1d1b66d08c6fa71b3bbdc",
|
||||
"reference": "cb8939aff03470d1a9d1d1b66d08c6fa71b3bbdc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2411,7 +2411,7 @@
|
||||
"description": "Executes commands in sub-processes",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/process/tree/v8.0.5"
|
||||
"source": "https://github.com/symfony/process/tree/v8.0.8"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -2431,7 +2431,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2026-01-26T15:08:38+00:00"
|
||||
"time": "2026-03-30T15:14:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/service-contracts",
|
||||
@@ -2522,16 +2522,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/stopwatch",
|
||||
"version": "v8.0.0",
|
||||
"version": "v8.0.8",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/stopwatch.git",
|
||||
"reference": "67df1914c6ccd2d7b52f70d40cf2aea02159d942"
|
||||
"reference": "85954ed72d5440ea4dc9a10b7e49e01df766ffa3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/stopwatch/zipball/67df1914c6ccd2d7b52f70d40cf2aea02159d942",
|
||||
"reference": "67df1914c6ccd2d7b52f70d40cf2aea02159d942",
|
||||
"url": "https://api.github.com/repos/symfony/stopwatch/zipball/85954ed72d5440ea4dc9a10b7e49e01df766ffa3",
|
||||
"reference": "85954ed72d5440ea4dc9a10b7e49e01df766ffa3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2564,7 +2564,7 @@
|
||||
"description": "Provides a way to profile code",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/stopwatch/tree/v8.0.0"
|
||||
"source": "https://github.com/symfony/stopwatch/tree/v8.0.8"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -2584,20 +2584,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-08-04T07:36:47+00:00"
|
||||
"time": "2026-03-30T15:14:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/string",
|
||||
"version": "v8.0.6",
|
||||
"version": "v8.0.8",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/string.git",
|
||||
"reference": "6c9e1108041b5dce21a9a4984b531c4923aa9ec4"
|
||||
"reference": "ae9488f874d7603f9d2dfbf120203882b645d963"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/6c9e1108041b5dce21a9a4984b531c4923aa9ec4",
|
||||
"reference": "6c9e1108041b5dce21a9a4984b531c4923aa9ec4",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/ae9488f874d7603f9d2dfbf120203882b645d963",
|
||||
"reference": "ae9488f874d7603f9d2dfbf120203882b645d963",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2654,7 +2654,7 @@
|
||||
"utf8"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/string/tree/v8.0.6"
|
||||
"source": "https://github.com/symfony/string/tree/v8.0.8"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -2674,7 +2674,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2026-02-09T10:14:57+00:00"
|
||||
"time": "2026-03-30T15:14:47+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
|
||||
@@ -116,6 +116,7 @@ final class PiggyBankController extends Controller
|
||||
'currency_decimal_places' => $currency->decimal_places,
|
||||
'object_group_id' => null === $objectGroup ? null : (string) $objectGroup->id,
|
||||
'object_group_title' => $objectGroup?->title,
|
||||
'object_group_order' => $objectGroup?->order,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\Note;
|
||||
use FireflyIII\Models\Recurrence;
|
||||
use FireflyIII\Models\Rule;
|
||||
use FireflyIII\Models\RuleGroup;
|
||||
@@ -85,6 +86,9 @@ final class PurgeController extends Controller
|
||||
// rules
|
||||
Rule::whereUserId($user->id)->onlyTrashed()->forceDelete();
|
||||
|
||||
// notes (this will actually purge EVERYBODY's deleted notes)
|
||||
Note::onlyTrashed()->forceDelete();
|
||||
|
||||
// recurring transactions
|
||||
Recurrence::whereUserId($user->id)->onlyTrashed()->forceDelete();
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Rules\IsValidPositiveAmount;
|
||||
use FireflyIII\Rules\IsValidZeroOrMoreAmount;
|
||||
use FireflyIII\Rules\LessThanPiggyTarget;
|
||||
use FireflyIII\Rules\PiggyBank\IsEnoughInAccounts;
|
||||
use FireflyIII\Support\Request\ChecksLogin;
|
||||
use FireflyIII\Support\Request\ConvertsDataTypes;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
@@ -84,7 +85,7 @@ class UpdateRequest extends FormRequest
|
||||
'accounts' => 'array',
|
||||
'accounts.*' => 'array',
|
||||
'accounts.*.account_id' => ['required', 'numeric', 'belongsToUser:accounts,id'],
|
||||
'accounts.*.current_amount' => ['numeric', 'nullable', new IsValidZeroOrMoreAmount(true)],
|
||||
'accounts.*.current_amount' => ['numeric', 'nullable', new IsValidZeroOrMoreAmount(true), new IsEnoughInAccounts($piggyBank, $this->getAll())],
|
||||
'object_group_id' => 'numeric|belongsToUser:object_groups,id',
|
||||
'object_group_title' => ['min:1', 'max:255'],
|
||||
'transaction_currency_id' => 'exists:transaction_currencies,id|nullable',
|
||||
|
||||
@@ -33,6 +33,7 @@ use FireflyIII\Models\TransactionGroup;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class CorrectsGroupAccounts extends Command
|
||||
{
|
||||
@@ -46,6 +47,7 @@ class CorrectsGroupAccounts extends Command
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
Log::debug('Start of correction:group-accounts');
|
||||
$groups = [];
|
||||
$res = TransactionJournal::groupBy('transaction_group_id')->get(['transaction_group_id', DB::raw('COUNT(transaction_group_id) as the_count')]);
|
||||
|
||||
@@ -59,13 +61,16 @@ class CorrectsGroupAccounts extends Command
|
||||
$flags->applyRules = false;
|
||||
$flags->fireWebhooks = false;
|
||||
$flags->recalculateCredit = true;
|
||||
$flags->unifyOnly = true;
|
||||
$objects = new TransactionGroupEventObjects();
|
||||
foreach ($groups as $groupId) {
|
||||
$group = TransactionGroup::find($groupId);
|
||||
$objects->appendFromTransactionGroup($group);
|
||||
}
|
||||
Log::debug(sprintf('Fire event for %d transaction group(s)', count($groups)));
|
||||
event(new UpdatedSingleTransactionGroup($flags, $objects));
|
||||
event(new WebhookMessagesRequestSending());
|
||||
Log::debug('End of correction:group-accounts');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -30,4 +30,5 @@ class TransactionGroupEventFlags
|
||||
public bool $fireWebhooks = true;
|
||||
public bool $batchSubmission = false;
|
||||
public bool $recalculateCredit = true;
|
||||
public bool $unifyOnly = false;
|
||||
}
|
||||
|
||||
@@ -134,6 +134,13 @@ class PiggyBankFactory
|
||||
$previous = $toBeLinked[$account->id]['current_amount'] ?? '0';
|
||||
$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)) {
|
||||
Log::debug(sprintf('Cannot add amount %s to piggy bank #%d ("%s")', $diff, $piggyBank->id, $piggyBank->name));
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// create event for difference.
|
||||
if (0 !== bccomp($diff, '0')) {
|
||||
// 2025-10-01 for issue #10990 disable this event.
|
||||
|
||||
@@ -172,8 +172,8 @@ final class BudgetLimitController extends Controller
|
||||
// return empty array:
|
||||
return response()->json([]);
|
||||
}
|
||||
if ((int) $amount > 268_435_456) { // intentional cast to integer
|
||||
$amount = '268435456';
|
||||
if ((int) $amount > 2_147_483_647) { // intentional cast to integer
|
||||
$amount = '2147483647';
|
||||
}
|
||||
if (-1 === bccomp($amount, '0')) {
|
||||
$amount = bcmul($amount, '-1');
|
||||
@@ -232,8 +232,8 @@ final class BudgetLimitController extends Controller
|
||||
if ('' === $amount) {
|
||||
$amount = '0';
|
||||
}
|
||||
if ((int) $amount > 268_435_456) { // 268 million, intentional integer
|
||||
$amount = '268435456';
|
||||
if ((int) $amount > 2_147_483_647) { // 268 million, intentional integer
|
||||
$amount = '2147483647';
|
||||
}
|
||||
// sanity check on amount:
|
||||
if (0 === bccomp($amount, '0')) {
|
||||
|
||||
@@ -40,8 +40,8 @@ class ProcessesUpdatedTransactionGroup
|
||||
public function handle(UpdatedSingleTransactionGroup $event): void
|
||||
{
|
||||
Log::debug(sprintf('Now handling event %s', get_class($event)));
|
||||
$this->unifyAccounts($event);
|
||||
|
||||
$effect = $this->unifyAccounts($event);
|
||||
Log::debug(sprintf('Effect of unifyAccounts = %d', $effect));
|
||||
Log::debug(sprintf('Transaction journal count is %d', $event->objects->transactionJournals->count()));
|
||||
if (!$event->flags->applyRules) {
|
||||
Log::debug(sprintf('Will NOT process rules for %d journal(s)', $event->objects->transactionJournals->count()));
|
||||
@@ -63,7 +63,13 @@ class ProcessesUpdatedTransactionGroup
|
||||
$this->createWebhookMessages($event->objects->transactionGroups, WebhookTrigger::UPDATE_TRANSACTION);
|
||||
}
|
||||
$this->removePeriodStatistics($event->objects);
|
||||
$this->recalculateRunningBalance($event->objects);
|
||||
if (0 === $effect && true === $event->flags->unifyOnly) {
|
||||
Log::debug('Effect = 0, will not recalculate running balance.');
|
||||
}
|
||||
if (0 !== $effect || false === $event->flags->unifyOnly) {
|
||||
Log::debug(sprintf('Effect is != 0 (%d) OR unifyOnly = false, will recalc running balance', $effect));
|
||||
$this->recalculateRunningBalance($event->objects);
|
||||
}
|
||||
|
||||
Log::debug('Done with handle() for UpdatedSingleTransactionGroup');
|
||||
}
|
||||
@@ -71,23 +77,26 @@ class ProcessesUpdatedTransactionGroup
|
||||
/**
|
||||
* This method will make sure all source / destination accounts are the same.
|
||||
*/
|
||||
protected function unifyAccounts(UpdatedSingleTransactionGroup $updatedGroupEvent): void
|
||||
protected function unifyAccounts(UpdatedSingleTransactionGroup $updatedGroupEvent): int
|
||||
{
|
||||
Log::debug('Now in unifyAccounts()');
|
||||
$effect = 0;
|
||||
|
||||
/** @var TransactionGroup $group */
|
||||
foreach ($updatedGroupEvent->objects->transactionGroups as $group) {
|
||||
$this->unifyAccountsForGroup($group);
|
||||
$effect += $this->unifyAccountsForGroup($group);
|
||||
}
|
||||
Log::debug('Done with unifyAccounts()');
|
||||
Log::debug(sprintf('Done with unifyAccounts(%d)', $effect));
|
||||
|
||||
return $effect;
|
||||
}
|
||||
|
||||
private function unifyAccountsForGroup(TransactionGroup $group): void
|
||||
private function unifyAccountsForGroup(TransactionGroup $group): int
|
||||
{
|
||||
if (1 === $group->transactionJournals->count()) {
|
||||
Log::debug('Nothing to do in unifyAccounts()');
|
||||
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// first journal:
|
||||
@@ -104,7 +113,7 @@ class ProcessesUpdatedTransactionGroup
|
||||
if (null === $first) {
|
||||
Log::warning(sprintf('Group #%d has no transaction journals.', $group->id));
|
||||
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
$all = $group->transactionJournals()->get()->pluck('id')->toArray();
|
||||
@@ -116,13 +125,30 @@ class ProcessesUpdatedTransactionGroup
|
||||
$destAccount = $first->transactions()->where('amount', '>', '0')->first()->account;
|
||||
|
||||
$type = $first->transactionType->type;
|
||||
$effect = 0;
|
||||
if (TransactionTypeEnum::TRANSFER->value === $type || TransactionTypeEnum::WITHDRAWAL->value === $type) {
|
||||
// set all source transactions to source account:
|
||||
Transaction::whereIn('transaction_journal_id', $all)->where('amount', '<', 0)->update(['account_id' => $sourceAccount->id]);
|
||||
$effect += Transaction::whereIn('transaction_journal_id', $all)
|
||||
->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:
|
||||
Transaction::whereIn('transaction_journal_id', $all)->where('amount', '>', 0)->update(['account_id' => $destAccount->id]);
|
||||
$effect += Transaction::whereIn('transaction_journal_id', $all)
|
||||
->where('account_id', '!=', $destAccount->id)
|
||||
->where('amount', '>', 0)
|
||||
->update(['account_id' => $destAccount->id])
|
||||
;
|
||||
}
|
||||
if (0 === $effect) {
|
||||
Log::debug(sprintf('Had nothing to do in unifyAccounts(#%d)', $group->id));
|
||||
|
||||
return 0;
|
||||
}
|
||||
Log::debug(sprintf('Updated %d transaction(s) in unifyAccounts(#%d)', $effect, $group->id));
|
||||
|
||||
return $effect;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace FireflyIII\Notifications;
|
||||
|
||||
use Exception;
|
||||
use FireflyIII\Notifications\Notifiables\OwnerNotifiable;
|
||||
use FireflyIII\Support\Facades\Preferences;
|
||||
use FireflyIII\User;
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
use Illuminate\Notifications\Notification;
|
||||
@@ -36,8 +37,16 @@ class NotificationSender
|
||||
{
|
||||
public static function send(OwnerNotifiable|User $user, Notification $notification): void
|
||||
{
|
||||
// ::locale($user->locale))
|
||||
$lang = config('firefly.default_language');
|
||||
Log::debug(sprintf('Notification send language defaults to "%s"', $lang));
|
||||
if ($user instanceof User) {
|
||||
$lang = Preferences::getForUser($user, 'language', $lang)->data;
|
||||
Log::debug(sprintf('Notification send language set to "%s"', $lang));
|
||||
}
|
||||
|
||||
try {
|
||||
NotificationFacade::send($user, $notification);
|
||||
NotificationFacade::locale($lang)->send($user, $notification);
|
||||
} catch (ClientException $e) {
|
||||
Log::error(sprintf('[a] Error sending notification: %s', $e->getMessage()));
|
||||
} catch (Exception $e) {
|
||||
|
||||
@@ -48,9 +48,10 @@ class UserTestNotificationEmail extends Notification
|
||||
public function toMail(User $notifiable): MailMessage
|
||||
{
|
||||
$address = (string) $notifiable->email;
|
||||
$link = route('index');
|
||||
|
||||
return new MailMessage()
|
||||
->markdown('emails.admin-test', ['email' => $address])
|
||||
->markdown('emails.admin-test', ['email' => $address, 'link' => $link])
|
||||
->subject((string) trans('email.admin_test_subject'))
|
||||
;
|
||||
}
|
||||
|
||||
73
app/Rules/PiggyBank/IsEnoughInAccounts.php
Normal file
73
app/Rules/PiggyBank/IsEnoughInAccounts.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* IsEnoughInAccounts.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\Rules\PiggyBank;
|
||||
|
||||
use Closure;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
use Override;
|
||||
|
||||
class IsEnoughInAccounts implements ValidationRule
|
||||
{
|
||||
public function __construct(
|
||||
private readonly PiggyBank $piggyBank,
|
||||
private readonly array $data
|
||||
) {}
|
||||
|
||||
#[Override]
|
||||
public function validate(string $attribute, mixed $value, Closure $fail): void
|
||||
{
|
||||
// TODO: Implement validate() method.
|
||||
if (!array_key_exists('accounts', $this->data)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var AccountRepositoryInterface $repository */
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
|
||||
/** @var PiggyBankRepositoryInterface $piggyRepos */
|
||||
$piggyRepos = app(PiggyBankRepositoryInterface::class);
|
||||
|
||||
$accounts = $this->data['accounts'];
|
||||
foreach ($accounts as $info) {
|
||||
$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')) {
|
||||
continue;
|
||||
}
|
||||
$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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -474,7 +474,10 @@ trait ConvertsDataTypes
|
||||
if (!array_key_exists('current_amount', $entry)) {
|
||||
$amount = null;
|
||||
}
|
||||
$return[] = ['account_id' => $this->integerFromValue((string) ($entry['account_id'] ?? '0')), 'current_amount' => $amount];
|
||||
$return[] = [
|
||||
'account_id' => $this->integerFromValue((string) ($entry['account_id'] ?? '0')),
|
||||
'current_amount' => $amount,
|
||||
];
|
||||
}
|
||||
|
||||
return $return;
|
||||
|
||||
@@ -72,7 +72,7 @@ trait ValidatesAutoBudgetRequest
|
||||
$validator->errors()->add('auto_budget_amount', (string) trans('validation.require_currency_info'));
|
||||
}
|
||||
// too big amount
|
||||
if ((int) $amount > 268_435_456) {
|
||||
if ((int) $amount > 2_147_483_647) {
|
||||
$validator->errors()->add('auto_budget_amount', (string) trans('validation.amount_required_for_auto_budget'));
|
||||
}
|
||||
}
|
||||
|
||||
441
composer.lock
generated
441
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -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-04-01',
|
||||
'build_time' => 1775021114,
|
||||
'api_version' => '2.1.0', // field is no longer used.
|
||||
'db_version' => 28, // field is no longer used.
|
||||
|
||||
|
||||
102
package-lock.json
generated
102
package-lock.json
generated
@@ -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.13",
|
||||
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.13.tgz",
|
||||
"integrity": "sha512-BL2sTuHOdy0YT1lYieUxTw/QMtPBC3pmlJC6xk8BBYVv6vcw3SGdKemQ+Xsx9ik2F/lYDO9tqsFQH1r9PFuHKw==",
|
||||
"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": {
|
||||
@@ -3964,9 +3969,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/browserslist": {
|
||||
"version": "4.28.1",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz",
|
||||
"integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==",
|
||||
"version": "4.28.2",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz",
|
||||
"integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@@ -3984,11 +3989,11 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"baseline-browser-mapping": "^2.9.0",
|
||||
"caniuse-lite": "^1.0.30001759",
|
||||
"electron-to-chromium": "^1.5.263",
|
||||
"node-releases": "^2.0.27",
|
||||
"update-browserslist-db": "^1.2.0"
|
||||
"baseline-browser-mapping": "^2.10.12",
|
||||
"caniuse-lite": "^1.0.30001782",
|
||||
"electron-to-chromium": "^1.5.328",
|
||||
"node-releases": "^2.0.36",
|
||||
"update-browserslist-db": "^1.2.3"
|
||||
},
|
||||
"bin": {
|
||||
"browserslist": "cli.js"
|
||||
@@ -4129,9 +4134,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001781",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001781.tgz",
|
||||
"integrity": "sha512-RdwNCyMsNBftLjW6w01z8bKEvT6e/5tpPVEgtn22TiLGlstHOVecsX2KHFkD5e/vRnIE4EGzpuIODb3mtswtkw==",
|
||||
"version": "1.0.30001784",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001784.tgz",
|
||||
"integrity": "sha512-WU346nBTklUV9YfUl60fqRbU5ZqyXlqvo1SgigE1OAXK5bFL8LL9q1K7aap3N739l4BvNqnkm3YrGHiY9sfUQw==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@@ -4683,12 +4688,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/cross-fetch": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz",
|
||||
"integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==",
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.1.0.tgz",
|
||||
"integrity": "sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"node-fetch": "^2.6.12"
|
||||
"node-fetch": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
@@ -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.330",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.330.tgz",
|
||||
"integrity": "sha512-jFNydB5kFtYUobh4IkWUnXeyDbjf/r9gcUEXe1xcrcUxIGfTdzPXA+ld6zBRbwvgIGVzDll/LTIiDztEtckSnA==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
@@ -6682,12 +6687,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/i18next-http-backend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-3.0.2.tgz",
|
||||
"integrity": "sha512-PdlvPnvIp4E1sYi46Ik4tBYh/v/NbYfFFgTjkwFl0is8A18s7/bx9aXqsrOax9WUbeNS6mD2oix7Z0yGGf6m5g==",
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-3.0.4.tgz",
|
||||
"integrity": "sha512-udwrBIE6cNpqn1gRAqRULq3+7MzIIuaiKRWrz++dVz5SqWW2VwXmPJtAgkI0JtMLFaADC9qNmnZAxWAhsxXx2g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cross-fetch": "4.0.0"
|
||||
"cross-fetch": "4.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/i18next-localstorage-backend": {
|
||||
@@ -7750,9 +7755,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/lodash": {
|
||||
"version": "4.17.23",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz",
|
||||
"integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==",
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
@@ -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",
|
||||
|
||||
@@ -81,6 +81,9 @@ export default {
|
||||
let currentPiggy = res.data[key];
|
||||
if (null !== currentPiggy.object_group_id) {
|
||||
let groupOrder = currentPiggy.object_group_order;
|
||||
if(0 === groupOrder) {
|
||||
groupOrder = 1;
|
||||
}
|
||||
if (!tempList[groupOrder]) {
|
||||
tempList[groupOrder] = {
|
||||
group: {
|
||||
|
||||
@@ -189,6 +189,6 @@
|
||||
},
|
||||
"config": {
|
||||
"html_language": "ru",
|
||||
"date_time_fns": "d MMMM yyyy @ HH:mm:ss"
|
||||
"date_time_fns": "d MMMM yyyy, HH:mm:ss"
|
||||
}
|
||||
}
|
||||
@@ -70,6 +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.',
|
||||
'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.',
|
||||
|
||||
@@ -282,7 +282,8 @@
|
||||
{% if transaction.source_account_id == account.id %}
|
||||
<span title="Deposit, source">{{ formatAmountBySymbol(transaction.source_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}</span>
|
||||
{% else %}
|
||||
<span title="Deposit, dest">{{ formatAmountBySymbol(transaction.destination_balance_after, transaction.currency_symbol, transaction.currency_decimal_places) }}</span>
|
||||
{# changed from normal currency_symbol to foreign_currency_symbol for #12043 #}
|
||||
<span title="Deposit, dest">{{ formatAmountBySymbol(transaction.destination_balance_after, transaction.foreign_currency_symbol, transaction.foreign_currency_decimal_places) }}</span>
|
||||
{% endif %}
|
||||
|
||||
{% elseif transaction.transaction_type_type == 'Withdrawal' %}
|
||||
|
||||
Reference in New Issue
Block a user