From a861126c0f8b6517eeb448f8bf13c806374f0090 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 20 Apr 2025 12:41:46 +0200 Subject: [PATCH 1/9] Fix #9878 --- .../Controllers/PiggyBank/EditController.php | 1 + app/Http/Requests/PiggyBankUpdateRequest.php | 22 +++---- .../PiggyBank/ModifiesPiggyBanks.php | 60 +++++++++++-------- resources/views/piggy-banks/edit.twig | 2 +- 4 files changed, 48 insertions(+), 37 deletions(-) diff --git a/app/Http/Controllers/PiggyBank/EditController.php b/app/Http/Controllers/PiggyBank/EditController.php index b46fea3ff0..9f7a23c61f 100644 --- a/app/Http/Controllers/PiggyBank/EditController.php +++ b/app/Http/Controllers/PiggyBank/EditController.php @@ -79,6 +79,7 @@ class EditController extends Controller $preFilled = [ 'name' => $piggyBank->name, + 'transaction_currency_id' => (int) $piggyBank->transaction_currency_id, 'target_amount' => app('steam')->bcround($piggyBank->target_amount, $piggyBank->transactionCurrency->decimal_places), 'target_date' => $targetDate, 'start_date' => $startDate, diff --git a/app/Http/Requests/PiggyBankUpdateRequest.php b/app/Http/Requests/PiggyBankUpdateRequest.php index 249d948478..ea9739baa0 100644 --- a/app/Http/Requests/PiggyBankUpdateRequest.php +++ b/app/Http/Requests/PiggyBankUpdateRequest.php @@ -53,6 +53,7 @@ class PiggyBankUpdateRequest extends FormRequest 'start_date' => $this->getCarbonDate('start_date'), 'target_amount' => trim($this->convertString('target_amount')), 'target_date' => $this->getCarbonDate('target_date'), + 'transaction_currency_id' => $this->convertInteger('transaction_currency_id'), 'notes' => $this->stringWithNewlines('notes'), 'object_group_title' => $this->convertString('object_group'), ]; @@ -75,15 +76,16 @@ class PiggyBankUpdateRequest extends FormRequest $piggy = $this->route()->parameter('piggyBank'); return [ - 'name' => sprintf('required|min:1|max:255|uniquePiggyBankForUser:%d', $piggy->id), - 'accounts' => 'required|array', - 'accounts.*' => 'required|belongsToUser:accounts', - 'target_amount' => ['nullable', new IsValidPositiveAmount()], - 'start_date' => 'date', - 'target_date' => 'date|nullable', - 'order' => 'integer|max:32768|min:1', - 'object_group' => 'min:0|max:255', - 'notes' => 'min:1|max:32768|nullable', + 'name' => sprintf('required|min:1|max:255|uniquePiggyBankForUser:%d', $piggy->id), + 'accounts' => 'required|array', + 'accounts.*' => 'required|belongsToUser:accounts', + 'target_amount' => ['nullable', new IsValidPositiveAmount()], + 'start_date' => 'date', + 'transaction_currency_id' => 'exists:transaction_currencies,id', + 'target_date' => 'date|nullable', + 'order' => 'integer|max:32768|min:1', + 'object_group' => 'min:0|max:255', + 'notes' => 'min:1|max:32768|nullable', ]; } @@ -108,7 +110,7 @@ class PiggyBankUpdateRequest extends FormRequest if ($accountCurrency->id !== $currency->id && 'true' !== $isMultiCurrency) { $validator->errors()->add('accounts', trans('validation.invalid_account_currency')); } - $type = $account->accountType->type; + $type = $account->accountType->type; if (!in_array($type, $types, true)) { $validator->errors()->add('accounts', trans('validation.invalid_account_type')); } diff --git a/app/Repositories/PiggyBank/ModifiesPiggyBanks.php b/app/Repositories/PiggyBank/ModifiesPiggyBanks.php index 568e37895d..559b284bfb 100644 --- a/app/Repositories/PiggyBank/ModifiesPiggyBanks.php +++ b/app/Repositories/PiggyBank/ModifiesPiggyBanks.php @@ -31,6 +31,7 @@ use FireflyIII\Models\Account; use FireflyIII\Models\Note; use FireflyIII\Models\PiggyBank; use FireflyIII\Models\Transaction; +use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionJournal; use FireflyIII\Repositories\ObjectGroup\CreatesObjectGroups; use FireflyIII\Support\Http\Api\ExchangeRateConverter; @@ -68,9 +69,9 @@ trait ModifiesPiggyBanks $pivot->native_current_amount = null; // also update native_current_amount. - $userCurrency = app('amount')->getNativeCurrencyByUserGroup($this->user->userGroup); + $userCurrency = app('amount')->getNativeCurrencyByUserGroup($this->user->userGroup); if ($userCurrency->id !== $piggyBank->transaction_currency_id) { - $converter = new ExchangeRateConverter(); + $converter = new ExchangeRateConverter(); $converter->setIgnoreSettings(true); $pivot->native_current_amount = $converter->convert($piggyBank->transactionCurrency, $userCurrency, today(), $pivot->current_amount); } @@ -91,9 +92,9 @@ trait ModifiesPiggyBanks $pivot->native_current_amount = null; // also update native_current_amount. - $userCurrency = app('amount')->getNativeCurrencyByUserGroup($this->user->userGroup); + $userCurrency = app('amount')->getNativeCurrencyByUserGroup($this->user->userGroup); if ($userCurrency->id !== $piggyBank->transaction_currency_id) { - $converter = new ExchangeRateConverter(); + $converter = new ExchangeRateConverter(); $converter->setIgnoreSettings(true); $pivot->native_current_amount = $converter->convert($piggyBank->transactionCurrency, $userCurrency, today(), $pivot->current_amount); } @@ -125,8 +126,8 @@ trait ModifiesPiggyBanks Log::debug(sprintf('Maximum amount: %s', $maxAmount)); } - $compare = bccomp($amount, $maxAmount); - $result = $compare <= 0; + $compare = bccomp($amount, $maxAmount); + $result = $compare <= 0; Log::debug(sprintf('Compare <= 0? %d, so canAddAmount is %s', $compare, var_export($result, true))); @@ -160,11 +161,11 @@ trait ModifiesPiggyBanks public function setCurrentAmount(PiggyBank $piggyBank, string $amount): PiggyBank { - $repetition = $this->getRepetition($piggyBank); + $repetition = $this->getRepetition($piggyBank); if (null === $repetition) { return $piggyBank; } - $max = $piggyBank->target_amount; + $max = $piggyBank->target_amount; if (1 === bccomp($amount, $max) && 0 !== bccomp($piggyBank->target_amount, '0')) { $amount = $max; } @@ -207,14 +208,14 @@ trait ModifiesPiggyBanks public function update(PiggyBank $piggyBank, array $data): PiggyBank { - $piggyBank = $this->updateProperties($piggyBank, $data); + $piggyBank = $this->updateProperties($piggyBank, $data); if (array_key_exists('notes', $data)) { $this->updateNote($piggyBank, (string) $data['notes']); } // update the order of the piggy bank: - $oldOrder = $piggyBank->order; - $newOrder = (int) ($data['order'] ?? $oldOrder); + $oldOrder = $piggyBank->order; + $newOrder = (int) ($data['order'] ?? $oldOrder); if ($oldOrder !== $newOrder) { $this->setOrder($piggyBank, $newOrder); } @@ -223,6 +224,8 @@ trait ModifiesPiggyBanks $factory = new PiggyBankFactory(); $factory->user = $this->user; + // the piggy bank currency is set or updated FIRST, if it exists. + $factory->linkToAccountIds($piggyBank, $data['accounts'] ?? []); @@ -280,6 +283,13 @@ trait ModifiesPiggyBanks if (array_key_exists('name', $data) && '' !== $data['name']) { $piggyBank->name = $data['name']; } + if (array_key_exists('transaction_currency_id', $data) && is_int($data['transaction_currency_id'])) { + $currency = TransactionCurrency::find($data['transaction_currency_id']); + if (null !== $currency) { + $piggyBank->transaction_currency_id = $currency->id; + } + } + if (array_key_exists('target_amount', $data) && '' !== $data['target_amount']) { $piggyBank->target_amount = $data['target_amount']; } @@ -307,7 +317,7 @@ trait ModifiesPiggyBanks return; } - $dbNote = $piggyBank->notes()->first(); + $dbNote = $piggyBank->notes()->first(); if (null === $dbNote) { $dbNote = new Note(); $dbNote->noteable()->associate($piggyBank); @@ -318,16 +328,15 @@ trait ModifiesPiggyBanks public function setOrder(PiggyBank $piggyBank, int $newOrder): bool { - $oldOrder = $piggyBank->order; + $oldOrder = $piggyBank->order; // Log::debug(sprintf('Will move piggy bank #%d ("%s") from %d to %d', $piggyBank->id, $piggyBank->name, $oldOrder, $newOrder)); if ($newOrder > $oldOrder) { PiggyBank::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id') - ->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id') - ->where('accounts.user_id', $this->user->id) - ->where('piggy_banks.order', '<=', $newOrder)->where('piggy_banks.order', '>', $oldOrder) - ->where('piggy_banks.id', '!=', $piggyBank->id) - ->distinct()->decrement('piggy_banks.order') - ; + ->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id') + ->where('accounts.user_id', $this->user->id) + ->where('piggy_banks.order', '<=', $newOrder)->where('piggy_banks.order', '>', $oldOrder) + ->where('piggy_banks.id', '!=', $piggyBank->id) + ->distinct()->decrement('piggy_banks.order'); $piggyBank->order = $newOrder; Log::debug(sprintf('[1] Order of piggy #%d ("%s") from %d to %d', $piggyBank->id, $piggyBank->name, $oldOrder, $newOrder)); @@ -336,12 +345,11 @@ trait ModifiesPiggyBanks return true; } PiggyBank::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id') - ->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id') - ->where('accounts.user_id', $this->user->id) - ->where('piggy_banks.order', '>=', $newOrder)->where('piggy_banks.order', '<', $oldOrder) - ->where('piggy_banks.id', '!=', $piggyBank->id) - ->distinct()->increment('piggy_banks.order') - ; + ->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id') + ->where('accounts.user_id', $this->user->id) + ->where('piggy_banks.order', '>=', $newOrder)->where('piggy_banks.order', '<', $oldOrder) + ->where('piggy_banks.id', '!=', $piggyBank->id) + ->distinct()->increment('piggy_banks.order'); $piggyBank->order = $newOrder; Log::debug(sprintf('[2] Order of piggy #%d ("%s") from %d to %d', $piggyBank->id, $piggyBank->name, $oldOrder, $newOrder)); @@ -362,7 +370,7 @@ trait ModifiesPiggyBanks } // if this account contains less than the amount, remove the current amount, update the amount and continue. $this->removeAmount($piggyBank, $account, $current); - $amount = bcsub($amount, $current); + $amount = bcsub($amount, $current); } } } diff --git a/resources/views/piggy-banks/edit.twig b/resources/views/piggy-banks/edit.twig index 23617a4a27..8489ca8064 100644 --- a/resources/views/piggy-banks/edit.twig +++ b/resources/views/piggy-banks/edit.twig @@ -23,7 +23,7 @@
{{ ExpandedForm.text('name') }} {{ ExpandedForm.amountNoCurrency('target_amount') }} - {{ CurrencyForm.currencyList('transaction_currency_id', null, {helpText:'piggy_default_currency'|_}) }} + {{ CurrencyForm.currencyList('transaction_currency_id', preFilled.transaction_currency_id, {helpText:'piggy_default_currency'|_}) }} {{ AccountForm.assetLiabilityMultiAccountList('accounts', preFilled.accounts, {label: 'saveOnAccounts'|_, helpText: 'piggy_account_currency_match'|_ }) }}
From 12d74f15c0eb013ad975b6edadd3e9ea49068cb6 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 20 Apr 2025 12:47:13 +0200 Subject: [PATCH 2/9] Fix #9867 --- app/Http/Controllers/Chart/AccountController.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/Chart/AccountController.php b/app/Http/Controllers/Chart/AccountController.php index e0b54071b3..80c803cc68 100644 --- a/app/Http/Controllers/Chart/AccountController.php +++ b/app/Http/Controllers/Chart/AccountController.php @@ -82,13 +82,16 @@ class AccountController extends Controller */ public function expenseAccounts(): JsonResponse { - Log::debug('RevenueAccounts'); + Log::debug('ExpenseAccounts'); /** @var Carbon $start */ $start = clone session('start', today(config('app.timezone'))->startOfMonth()); /** @var Carbon $end */ $end = clone session('end', today(config('app.timezone'))->endOfMonth()); + $start->startOfDay(); + $end->endOfDay(); + $cache = new CacheProperties(); $cache->addProperty($start); $cache->addProperty($end); @@ -97,7 +100,6 @@ class AccountController extends Controller if ($cache->has()) { return response()->json($cache->get()); } - $start->subDay(); // prep some vars: $currencies = []; @@ -557,6 +559,10 @@ class AccountController extends Controller /** @var Carbon $end */ $end = clone session('end', today(config('app.timezone'))->endOfMonth()); + + $start->startOfDay(); + $end->endOfDay(); + $cache = new CacheProperties(); $cache->addProperty($start); $cache->addProperty($end); @@ -565,7 +571,6 @@ class AccountController extends Controller if ($cache->has()) { return response()->json($cache->get()); } - $start->subDay(); // prep some vars: $currencies = []; From 984c4e2449819afce341c49162565ee6e478395c Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 20 Apr 2025 12:58:45 +0200 Subject: [PATCH 3/9] Fix #9755 --- resources/assets/v1/mix-manifest.json | 10 ++++++++++ .../v1/src/components/transactions/AccountSelect.vue | 2 +- .../v1/src/components/transactions/EditTransaction.vue | 8 +++++++- .../components/transactions/ForeignAmountSelect.vue | 1 - 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/resources/assets/v1/mix-manifest.json b/resources/assets/v1/mix-manifest.json index ff2938f703..145eaf58f2 100644 --- a/resources/assets/v1/mix-manifest.json +++ b/resources/assets/v1/mix-manifest.json @@ -20,8 +20,12 @@ "/public/v1/js/app.js.LICENSE.txt": "/public/v1/js/app.js.LICENSE.txt", "/public/v1/js/app_vue.js": "/public/v1/js/app_vue.js", "/public/v1/js/app_vue.js.LICENSE.txt": "/public/v1/js/app_vue.js.LICENSE.txt", + "/public/v1/js/create.js": "/public/v1/js/create.js", + "/public/v1/js/create.js.LICENSE.txt": "/public/v1/js/create.js.LICENSE.txt", "/public/v1/js/create_transaction.js": "/public/v1/js/create_transaction.js", "/public/v1/js/create_transaction.js.LICENSE.txt": "/public/v1/js/create_transaction.js.LICENSE.txt", + "/public/v1/js/edit.js": "/public/v1/js/edit.js", + "/public/v1/js/edit.js.LICENSE.txt": "/public/v1/js/edit.js.LICENSE.txt", "/public/v1/js/edit_transaction.js": "/public/v1/js/edit_transaction.js", "/public/v1/js/edit_transaction.js.LICENSE.txt": "/public/v1/js/edit_transaction.js.LICENSE.txt", "/public/v1/js/exchange-rates/index.js": "/public/v1/js/exchange-rates/index.js", @@ -96,6 +100,8 @@ "/public/v1/js/ff/transactions/mass/edit-bulk.js": "/public/v1/js/ff/transactions/mass/edit-bulk.js", "/public/v1/js/ff/transactions/mass/edit.js": "/public/v1/js/ff/transactions/mass/edit.js", "/public/v1/js/ff/transactions/show.js": "/public/v1/js/ff/transactions/show.js", + "/public/v1/js/index.js": "/public/v1/js/index.js", + "/public/v1/js/index.js.LICENSE.txt": "/public/v1/js/index.js.LICENSE.txt", "/public/v1/js/lib/Chart.bundle.min.js": "/public/v1/js/lib/Chart.bundle.min.js", "/public/v1/js/lib/accounting.min.js": "/public/v1/js/lib/accounting.min.js", "/public/v1/js/lib/bootstrap-multiselect.js": "/public/v1/js/lib/bootstrap-multiselect.js", @@ -120,6 +126,7 @@ "/public/v1/js/lib/moment/en_US.js": "/public/v1/js/lib/moment/en_US.js", "/public/v1/js/lib/moment/es_ES.js": "/public/v1/js/lib/moment/es_ES.js", "/public/v1/js/lib/moment/es_MX.js": "/public/v1/js/lib/moment/es_MX.js", + "/public/v1/js/lib/moment/fa_IR.js": "/public/v1/js/lib/moment/fa_IR.js", "/public/v1/js/lib/moment/fi_FI.js": "/public/v1/js/lib/moment/fi_FI.js", "/public/v1/js/lib/moment/fr_FR.js": "/public/v1/js/lib/moment/fr_FR.js", "/public/v1/js/lib/moment/hu_HU.js": "/public/v1/js/lib/moment/hu_HU.js", @@ -143,6 +150,7 @@ "/public/v1/js/lib/moment/vi_VN.js": "/public/v1/js/lib/moment/vi_VN.js", "/public/v1/js/lib/moment/zh_CN.js": "/public/v1/js/lib/moment/zh_CN.js", "/public/v1/js/lib/moment/zh_TW.js": "/public/v1/js/lib/moment/zh_TW.js", + "/public/v1/js/lib/moment-tz.js": "/public/v1/js/lib/moment-tz.js", "/public/v1/js/lib/moment.min.js": "/public/v1/js/lib/moment.min.js", "/public/v1/js/lib/respond.min.js": "/public/v1/js/lib/respond.min.js", "/public/v1/js/lib/typeahead/bloodhound.js": "/public/v1/js/lib/typeahead/bloodhound.js", @@ -154,6 +162,8 @@ "/public/v1/js/lib/vue.js": "/public/v1/js/lib/vue.js", "/public/v1/js/profile.js": "/public/v1/js/profile.js", "/public/v1/js/profile.js.LICENSE.txt": "/public/v1/js/profile.js.LICENSE.txt", + "/public/v1/js/show.js": "/public/v1/js/show.js", + "/public/v1/js/show.js.LICENSE.txt": "/public/v1/js/show.js.LICENSE.txt", "/public/v1/js/webhooks/create.js": "/public/v1/js/webhooks/create.js", "/public/v1/js/webhooks/create.js.LICENSE.txt": "/public/v1/js/webhooks/create.js.LICENSE.txt", "/public/v1/js/webhooks/edit.js": "/public/v1/js/webhooks/edit.js", diff --git a/resources/assets/v1/src/components/transactions/AccountSelect.vue b/resources/assets/v1/src/components/transactions/AccountSelect.vue index 097a3bcf1b..4e3f3b1b1b 100644 --- a/resources/assets/v1/src/components/transactions/AccountSelect.vue +++ b/resources/assets/v1/src/components/transactions/AccountSelect.vue @@ -216,7 +216,7 @@ export default { } }, selectedItem: function (e) { - console.log('In SelectedItem()'); + // console.log('In SelectedItem()'); if (typeof this.name === 'undefined') { // console.log('Is undefined'); return; diff --git a/resources/assets/v1/src/components/transactions/EditTransaction.vue b/resources/assets/v1/src/components/transactions/EditTransaction.vue index 97fbf78f41..cdab12ba1f 100644 --- a/resources/assets/v1/src/components/transactions/EditTransaction.vue +++ b/resources/assets/v1/src/components/transactions/EditTransaction.vue @@ -540,12 +540,18 @@ export default { allowed_types: window.expectedSourceTypes.destination[this.ucFirst(transaction.type)] } }; + // console.log('Destination currency id is ' + result.destination_account.currency_id); // if transaction type is transfer, the destination currency_id etc. MUST match the actual account currency info. - if ('transfer' === transaction.type && null !== transaction.foreign_currency_code) { + // OR if the transaction type is a withdrawal, and the destination account is a liability account, same as above. + if ( + ('transfer' === transaction.type && null !== transaction.foreign_currency_code) || + ('withdrawal' === transaction.type && ['Loan', 'Debt', 'Mortgage'].includes(transaction.destination_type) && null !== transaction.foreign_currency_code) + ) { result.destination_account.currency_id = transaction.foreign_currency_id; result.destination_account.currency_name = transaction.foreign_currency_name; result.destination_account.currency_code = transaction.foreign_currency_code; result.destination_account.currency_decimal_places = transaction.foreign_currency_decimal_places; + // console.log('Set destination currency_id to ' + result.destination_account.currency_id); } diff --git a/resources/assets/v1/src/components/transactions/ForeignAmountSelect.vue b/resources/assets/v1/src/components/transactions/ForeignAmountSelect.vue index a09016e23e..3f61bec9ed 100644 --- a/resources/assets/v1/src/components/transactions/ForeignAmountSelect.vue +++ b/resources/assets/v1/src/components/transactions/ForeignAmountSelect.vue @@ -137,7 +137,6 @@ export default { // lock dropdown list on currencyID of destination. 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) ) { From 01aca092a18b78e0c6b071f8801e7f1969a8620b Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 20 Apr 2025 21:00:43 +0200 Subject: [PATCH 4/9] Fix #10068 --- app/Support/Export/ExportDataGenerator.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Support/Export/ExportDataGenerator.php b/app/Support/Export/ExportDataGenerator.php index 3b86d45ec9..ca58d58384 100644 --- a/app/Support/Export/ExportDataGenerator.php +++ b/app/Support/Export/ExportDataGenerator.php @@ -57,6 +57,7 @@ use FireflyIII\Support\Facades\Steam; use FireflyIII\Support\Request\ConvertsDataTypes; use FireflyIII\User; use Illuminate\Support\Collection; +use Illuminate\Support\Facades\Log; use League\Csv\CannotInsertRecord; use League\Csv\Exception; use League\Csv\Writer; From b70c0e4ab384a7bd1104a6ca3426dea22aa78bf0 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 20 Apr 2025 21:01:23 +0200 Subject: [PATCH 5/9] Add some piggy bank events. --- app/Factory/PiggyBankFactory.php | 82 +++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 27 deletions(-) diff --git a/app/Factory/PiggyBankFactory.php b/app/Factory/PiggyBankFactory.php index 068cd0841a..b1cdbaaabe 100644 --- a/app/Factory/PiggyBankFactory.php +++ b/app/Factory/PiggyBankFactory.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Factory; +use FireflyIII\Events\Model\PiggyBank\ChangedAmount; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\PiggyBank; use FireflyIII\Models\TransactionCurrency; @@ -67,7 +68,7 @@ class PiggyBankFactory public function store(array $data): PiggyBank { - $piggyBankData = $data; + $piggyBankData = $data; // unset some fields unset($piggyBankData['object_group_title'], $piggyBankData['transaction_currency_code'], $piggyBankData['transaction_currency_id'], $piggyBankData['accounts'], $piggyBankData['object_group_id'], $piggyBankData['notes']); @@ -91,11 +92,11 @@ class PiggyBankFactory throw new FireflyException('400005: Could not store new piggy bank.', 0, $e); } - $piggyBank = $this->setOrder($piggyBank, $data); + $piggyBank = $this->setOrder($piggyBank, $data); $this->linkToAccountIds($piggyBank, $data['accounts']); $this->piggyBankRepository->updateNote($piggyBank, $data['notes']); - $objectGroupTitle = $data['object_group_title'] ?? ''; + $objectGroupTitle = $data['object_group_title'] ?? ''; if ('' !== $objectGroupTitle) { $objectGroup = $this->findOrCreateObjectGroup($objectGroupTitle); if (null !== $objectGroup) { @@ -103,7 +104,7 @@ class PiggyBankFactory } } // try also with ID - $objectGroupId = (int) ($data['object_group_id'] ?? 0); + $objectGroupId = (int) ($data['object_group_id'] ?? 0); if (0 !== $objectGroupId) { $objectGroup = $this->findObjectGroupById($objectGroupId); if (null !== $objectGroup) { @@ -111,7 +112,7 @@ class PiggyBankFactory } } Log::debug('Touch piggy bank'); - $piggyBank->encrypted = false; + $piggyBank->encrypted = false; $piggyBank->save(); $piggyBank->touch(); @@ -144,11 +145,10 @@ class PiggyBankFactory // first find by ID: if ($piggyBankId > 0) { $piggyBank = PiggyBank::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id') - ->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id') - ->where('accounts.user_id', $this->user->id) - ->where('piggy_banks.id', $piggyBankId) - ->first(['piggy_banks.*']) - ; + ->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id') + ->where('accounts.user_id', $this->user->id) + ->where('piggy_banks.id', $piggyBankId) + ->first(['piggy_banks.*']); if (null !== $piggyBank) { return $piggyBank; } @@ -169,17 +169,16 @@ class PiggyBankFactory public function findByName(string $name): ?PiggyBank { return PiggyBank::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id') - ->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id') - ->where('accounts.user_id', $this->user->id) - ->where('piggy_banks.name', $name) - ->first(['piggy_banks.*']) - ; + ->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id') + ->where('accounts.user_id', $this->user->id) + ->where('piggy_banks.name', $name) + ->first(['piggy_banks.*']); } private function setOrder(PiggyBank $piggyBank, array $data): PiggyBank { $this->resetOrder(); - $order = $this->getMaxOrder() + 1; + $order = $this->getMaxOrder() + 1; if (array_key_exists('order', $data)) { $order = $data['order']; } @@ -194,15 +193,14 @@ class PiggyBankFactory { // TODO duplicate code $set = PiggyBank::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id') - ->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id') - ->where('accounts.user_id', $this->user->id) - ->with( - [ - 'objectGroups', - ] - ) - ->orderBy('piggy_banks.order', 'ASC')->get(['piggy_banks.*']) - ; + ->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id') + ->where('accounts.user_id', $this->user->id) + ->with( + [ + 'objectGroups', + ] + ) + ->orderBy('piggy_banks.order', 'ASC')->get(['piggy_banks.*']); $current = 1; foreach ($set as $piggyBank) { if ($piggyBank->order !== $current) { @@ -237,20 +235,45 @@ class PiggyBankFactory } } - /** @var array $info */ foreach ($accounts as $info) { $account = $this->accountRepository->find((int) ($info['account_id'] ?? 0)); if (null === $account) { + Log::debug(sprintf('Account #%d not found, skipping.', (int) ($info['account_id'] ?? 0))); continue; } if (array_key_exists('current_amount', $info) && null !== $info['current_amount']) { + // an amount is set, first check out if there is a difference with the previous amount. + $previous = $toBeLinked[$account->id]['current_amount'] ?? '0'; + $diff = bcsub($info['current_amount'], $previous); + + // create event for difference. + if (0 !== bccomp($diff, '0')) { + Log::debug(sprintf('[a] Will save event for difference %s (previous value was %s)', $diff, $previous)); + event(new ChangedAmount($piggyBank, $diff, null, null)); + } + $toBeLinked[$account->id] = ['current_amount' => $info['current_amount']]; Log::debug(sprintf('[a] Will link account #%d with amount %s', $account->id, $info['current_amount'])); } if (array_key_exists('current_amount', $info) && null === $info['current_amount']) { + // an amount is set, first check out if there is a difference with the previous amount. + $previous = $toBeLinked[$account->id]['current_amount'] ?? '0'; + $diff = bcsub('0', $previous); + + // create event for difference. + if (0 !== bccomp($diff, '0')) { + Log::debug(sprintf('[b] Will save event for difference %s (previous value was %s)', $diff, $previous)); + event(new ChangedAmount($piggyBank, $diff, null, null)); + } + + // no amount set, use previous amount or go to ZERO. $toBeLinked[$account->id] = ['current_amount' => $toBeLinked[$account->id]['current_amount'] ?? '0']; Log::debug(sprintf('[b] Will link account #%d with amount %s', $account->id, $toBeLinked[$account->id]['current_amount'] ?? '0')); + + // create event: + Log::debug('linkToAccountIds: Trigger change for positive amount [b].'); + event(new ChangedAmount($piggyBank, $toBeLinked[$account->id]['current_amount'], null, null)); } if (!array_key_exists('current_amount', $info)) { $toBeLinked[$account->id] ??= []; @@ -258,6 +281,11 @@ class PiggyBankFactory } } Log::debug(sprintf('Link information: %s', json_encode($toBeLinked))); - $piggyBank->accounts()->sync($toBeLinked); + if (0 !== count($toBeLinked)) { + $piggyBank->accounts()->sync($toBeLinked); + } + if (0 === count($toBeLinked)) { + Log::warning('No accounts to link to piggy bank, will not change whatever is there now.'); + } } } From 0075f10f98b1be7f0e500335f4d0b98d1e8ecc62 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 20 Apr 2025 21:02:54 +0200 Subject: [PATCH 6/9] Fix #10162 --- app/Http/Middleware/TrustProxies.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/Http/Middleware/TrustProxies.php b/app/Http/Middleware/TrustProxies.php index 986bb2e5b8..ee1e7ef9d2 100644 --- a/app/Http/Middleware/TrustProxies.php +++ b/app/Http/Middleware/TrustProxies.php @@ -32,12 +32,12 @@ use Symfony\Component\HttpFoundation\Request; class TrustProxies extends Middleware { // After... - protected $headers - = Request::HEADER_X_FORWARDED_FOR - | Request::HEADER_X_FORWARDED_HOST - | Request::HEADER_X_FORWARDED_PORT - | Request::HEADER_X_FORWARDED_PROTO - | Request::HEADER_X_FORWARDED_AWS_ELB; + protected $headers = Request::HEADER_X_FORWARDED_FOR | + Request::HEADER_X_FORWARDED_HOST | + Request::HEADER_X_FORWARDED_PORT | + Request::HEADER_X_FORWARDED_PROTO | + Request::HEADER_X_FORWARDED_PREFIX | + Request::HEADER_X_FORWARDED_AWS_ELB; /** * TrustProxies constructor. From 6b73b9327ab064df283554e1955cabfb22313d12 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 20 Apr 2025 21:06:27 +0200 Subject: [PATCH 7/9] Update changelog --- changelog.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/changelog.md b/changelog.md index e42065170c..b12aaa634e 100644 --- a/changelog.md +++ b/changelog.md @@ -3,6 +3,16 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## 6.2.12 - 2025-04-21 + +### Fixed + +- #9755 +- #9867 +- #9878 +- #10068 +- #10162 + ## 6.2.11 - 2025-04-21 ### Added From b1dbd3ee172617367ee7204093a5c1b884e54fd5 Mon Sep 17 00:00:00 2001 From: JC5 Date: Sun, 20 Apr 2025 21:12:34 +0200 Subject: [PATCH 8/9] =?UTF-8?q?=F0=9F=A4=96=20Auto=20commit=20for=20releas?= =?UTF-8?q?e=20'develop'=20on=202025-04-20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Factory/PiggyBankFactory.php | 56 ++++++++++--------- .../Controllers/PiggyBank/EditController.php | 14 ++--- app/Http/Middleware/TrustProxies.php | 12 ++-- app/Http/Requests/PiggyBankUpdateRequest.php | 14 ++--- .../PiggyBank/ModifiesPiggyBanks.php | 50 +++++++++-------- changelog.md | 10 ++-- config/firefly.php | 2 +- resources/assets/v1/mix-manifest.json | 10 ---- 8 files changed, 82 insertions(+), 86 deletions(-) diff --git a/app/Factory/PiggyBankFactory.php b/app/Factory/PiggyBankFactory.php index b1cdbaaabe..5c308c1d08 100644 --- a/app/Factory/PiggyBankFactory.php +++ b/app/Factory/PiggyBankFactory.php @@ -68,7 +68,7 @@ class PiggyBankFactory public function store(array $data): PiggyBank { - $piggyBankData = $data; + $piggyBankData = $data; // unset some fields unset($piggyBankData['object_group_title'], $piggyBankData['transaction_currency_code'], $piggyBankData['transaction_currency_id'], $piggyBankData['accounts'], $piggyBankData['object_group_id'], $piggyBankData['notes']); @@ -92,11 +92,11 @@ class PiggyBankFactory throw new FireflyException('400005: Could not store new piggy bank.', 0, $e); } - $piggyBank = $this->setOrder($piggyBank, $data); + $piggyBank = $this->setOrder($piggyBank, $data); $this->linkToAccountIds($piggyBank, $data['accounts']); $this->piggyBankRepository->updateNote($piggyBank, $data['notes']); - $objectGroupTitle = $data['object_group_title'] ?? ''; + $objectGroupTitle = $data['object_group_title'] ?? ''; if ('' !== $objectGroupTitle) { $objectGroup = $this->findOrCreateObjectGroup($objectGroupTitle); if (null !== $objectGroup) { @@ -104,7 +104,7 @@ class PiggyBankFactory } } // try also with ID - $objectGroupId = (int) ($data['object_group_id'] ?? 0); + $objectGroupId = (int) ($data['object_group_id'] ?? 0); if (0 !== $objectGroupId) { $objectGroup = $this->findObjectGroupById($objectGroupId); if (null !== $objectGroup) { @@ -112,7 +112,7 @@ class PiggyBankFactory } } Log::debug('Touch piggy bank'); - $piggyBank->encrypted = false; + $piggyBank->encrypted = false; $piggyBank->save(); $piggyBank->touch(); @@ -145,10 +145,11 @@ class PiggyBankFactory // first find by ID: if ($piggyBankId > 0) { $piggyBank = PiggyBank::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id') - ->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id') - ->where('accounts.user_id', $this->user->id) - ->where('piggy_banks.id', $piggyBankId) - ->first(['piggy_banks.*']); + ->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id') + ->where('accounts.user_id', $this->user->id) + ->where('piggy_banks.id', $piggyBankId) + ->first(['piggy_banks.*']) + ; if (null !== $piggyBank) { return $piggyBank; } @@ -169,16 +170,17 @@ class PiggyBankFactory public function findByName(string $name): ?PiggyBank { return PiggyBank::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id') - ->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id') - ->where('accounts.user_id', $this->user->id) - ->where('piggy_banks.name', $name) - ->first(['piggy_banks.*']); + ->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id') + ->where('accounts.user_id', $this->user->id) + ->where('piggy_banks.name', $name) + ->first(['piggy_banks.*']) + ; } private function setOrder(PiggyBank $piggyBank, array $data): PiggyBank { $this->resetOrder(); - $order = $this->getMaxOrder() + 1; + $order = $this->getMaxOrder() + 1; if (array_key_exists('order', $data)) { $order = $data['order']; } @@ -193,14 +195,15 @@ class PiggyBankFactory { // TODO duplicate code $set = PiggyBank::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id') - ->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id') - ->where('accounts.user_id', $this->user->id) - ->with( - [ - 'objectGroups', - ] - ) - ->orderBy('piggy_banks.order', 'ASC')->get(['piggy_banks.*']); + ->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id') + ->where('accounts.user_id', $this->user->id) + ->with( + [ + 'objectGroups', + ] + ) + ->orderBy('piggy_banks.order', 'ASC')->get(['piggy_banks.*']) + ; $current = 1; foreach ($set as $piggyBank) { if ($piggyBank->order !== $current) { @@ -240,12 +243,13 @@ class PiggyBankFactory $account = $this->accountRepository->find((int) ($info['account_id'] ?? 0)); if (null === $account) { Log::debug(sprintf('Account #%d not found, skipping.', (int) ($info['account_id'] ?? 0))); + continue; } if (array_key_exists('current_amount', $info) && null !== $info['current_amount']) { // an amount is set, first check out if there is a difference with the previous amount. - $previous = $toBeLinked[$account->id]['current_amount'] ?? '0'; - $diff = bcsub($info['current_amount'], $previous); + $previous = $toBeLinked[$account->id]['current_amount'] ?? '0'; + $diff = bcsub($info['current_amount'], $previous); // create event for difference. if (0 !== bccomp($diff, '0')) { @@ -258,8 +262,8 @@ class PiggyBankFactory } if (array_key_exists('current_amount', $info) && null === $info['current_amount']) { // an amount is set, first check out if there is a difference with the previous amount. - $previous = $toBeLinked[$account->id]['current_amount'] ?? '0'; - $diff = bcsub('0', $previous); + $previous = $toBeLinked[$account->id]['current_amount'] ?? '0'; + $diff = bcsub('0', $previous); // create event for difference. if (0 !== bccomp($diff, '0')) { diff --git a/app/Http/Controllers/PiggyBank/EditController.php b/app/Http/Controllers/PiggyBank/EditController.php index 9f7a23c61f..b7b29683ae 100644 --- a/app/Http/Controllers/PiggyBank/EditController.php +++ b/app/Http/Controllers/PiggyBank/EditController.php @@ -78,14 +78,14 @@ class EditController extends Controller $startDate = $piggyBank->start_date?->format('Y-m-d'); $preFilled = [ - 'name' => $piggyBank->name, + 'name' => $piggyBank->name, 'transaction_currency_id' => (int) $piggyBank->transaction_currency_id, - 'target_amount' => app('steam')->bcround($piggyBank->target_amount, $piggyBank->transactionCurrency->decimal_places), - 'target_date' => $targetDate, - 'start_date' => $startDate, - 'accounts' => [], - 'object_group' => null !== $piggyBank->objectGroups->first() ? $piggyBank->objectGroups->first()->title : '', - 'notes' => null === $note ? '' : $note->text, + 'target_amount' => app('steam')->bcround($piggyBank->target_amount, $piggyBank->transactionCurrency->decimal_places), + 'target_date' => $targetDate, + 'start_date' => $startDate, + 'accounts' => [], + 'object_group' => null !== $piggyBank->objectGroups->first() ? $piggyBank->objectGroups->first()->title : '', + 'notes' => null === $note ? '' : $note->text, ]; foreach ($piggyBank->accounts as $account) { $preFilled['accounts'][] = $account->id; diff --git a/app/Http/Middleware/TrustProxies.php b/app/Http/Middleware/TrustProxies.php index ee1e7ef9d2..b36aaa900e 100644 --- a/app/Http/Middleware/TrustProxies.php +++ b/app/Http/Middleware/TrustProxies.php @@ -32,12 +32,12 @@ use Symfony\Component\HttpFoundation\Request; class TrustProxies extends Middleware { // After... - protected $headers = Request::HEADER_X_FORWARDED_FOR | - Request::HEADER_X_FORWARDED_HOST | - Request::HEADER_X_FORWARDED_PORT | - Request::HEADER_X_FORWARDED_PROTO | - Request::HEADER_X_FORWARDED_PREFIX | - Request::HEADER_X_FORWARDED_AWS_ELB; + protected $headers = Request::HEADER_X_FORWARDED_FOR + | Request::HEADER_X_FORWARDED_HOST + | Request::HEADER_X_FORWARDED_PORT + | Request::HEADER_X_FORWARDED_PROTO + | Request::HEADER_X_FORWARDED_PREFIX + | Request::HEADER_X_FORWARDED_AWS_ELB; /** * TrustProxies constructor. diff --git a/app/Http/Requests/PiggyBankUpdateRequest.php b/app/Http/Requests/PiggyBankUpdateRequest.php index ea9739baa0..d1d38467e5 100644 --- a/app/Http/Requests/PiggyBankUpdateRequest.php +++ b/app/Http/Requests/PiggyBankUpdateRequest.php @@ -49,13 +49,13 @@ class PiggyBankUpdateRequest extends FormRequest { $accounts = $this->get('accounts'); $data = [ - 'name' => $this->convertString('name'), - 'start_date' => $this->getCarbonDate('start_date'), - 'target_amount' => trim($this->convertString('target_amount')), - 'target_date' => $this->getCarbonDate('target_date'), + 'name' => $this->convertString('name'), + 'start_date' => $this->getCarbonDate('start_date'), + 'target_amount' => trim($this->convertString('target_amount')), + 'target_date' => $this->getCarbonDate('target_date'), 'transaction_currency_id' => $this->convertInteger('transaction_currency_id'), - 'notes' => $this->stringWithNewlines('notes'), - 'object_group_title' => $this->convertString('object_group'), + 'notes' => $this->stringWithNewlines('notes'), + 'object_group_title' => $this->convertString('object_group'), ]; if (!is_array($accounts)) { $accounts = []; @@ -110,7 +110,7 @@ class PiggyBankUpdateRequest extends FormRequest if ($accountCurrency->id !== $currency->id && 'true' !== $isMultiCurrency) { $validator->errors()->add('accounts', trans('validation.invalid_account_currency')); } - $type = $account->accountType->type; + $type = $account->accountType->type; if (!in_array($type, $types, true)) { $validator->errors()->add('accounts', trans('validation.invalid_account_type')); } diff --git a/app/Repositories/PiggyBank/ModifiesPiggyBanks.php b/app/Repositories/PiggyBank/ModifiesPiggyBanks.php index 559b284bfb..0be738ef48 100644 --- a/app/Repositories/PiggyBank/ModifiesPiggyBanks.php +++ b/app/Repositories/PiggyBank/ModifiesPiggyBanks.php @@ -69,9 +69,9 @@ trait ModifiesPiggyBanks $pivot->native_current_amount = null; // also update native_current_amount. - $userCurrency = app('amount')->getNativeCurrencyByUserGroup($this->user->userGroup); + $userCurrency = app('amount')->getNativeCurrencyByUserGroup($this->user->userGroup); if ($userCurrency->id !== $piggyBank->transaction_currency_id) { - $converter = new ExchangeRateConverter(); + $converter = new ExchangeRateConverter(); $converter->setIgnoreSettings(true); $pivot->native_current_amount = $converter->convert($piggyBank->transactionCurrency, $userCurrency, today(), $pivot->current_amount); } @@ -92,9 +92,9 @@ trait ModifiesPiggyBanks $pivot->native_current_amount = null; // also update native_current_amount. - $userCurrency = app('amount')->getNativeCurrencyByUserGroup($this->user->userGroup); + $userCurrency = app('amount')->getNativeCurrencyByUserGroup($this->user->userGroup); if ($userCurrency->id !== $piggyBank->transaction_currency_id) { - $converter = new ExchangeRateConverter(); + $converter = new ExchangeRateConverter(); $converter->setIgnoreSettings(true); $pivot->native_current_amount = $converter->convert($piggyBank->transactionCurrency, $userCurrency, today(), $pivot->current_amount); } @@ -126,8 +126,8 @@ trait ModifiesPiggyBanks Log::debug(sprintf('Maximum amount: %s', $maxAmount)); } - $compare = bccomp($amount, $maxAmount); - $result = $compare <= 0; + $compare = bccomp($amount, $maxAmount); + $result = $compare <= 0; Log::debug(sprintf('Compare <= 0? %d, so canAddAmount is %s', $compare, var_export($result, true))); @@ -161,11 +161,11 @@ trait ModifiesPiggyBanks public function setCurrentAmount(PiggyBank $piggyBank, string $amount): PiggyBank { - $repetition = $this->getRepetition($piggyBank); + $repetition = $this->getRepetition($piggyBank); if (null === $repetition) { return $piggyBank; } - $max = $piggyBank->target_amount; + $max = $piggyBank->target_amount; if (1 === bccomp($amount, $max) && 0 !== bccomp($piggyBank->target_amount, '0')) { $amount = $max; } @@ -208,14 +208,14 @@ trait ModifiesPiggyBanks public function update(PiggyBank $piggyBank, array $data): PiggyBank { - $piggyBank = $this->updateProperties($piggyBank, $data); + $piggyBank = $this->updateProperties($piggyBank, $data); if (array_key_exists('notes', $data)) { $this->updateNote($piggyBank, (string) $data['notes']); } // update the order of the piggy bank: - $oldOrder = $piggyBank->order; - $newOrder = (int) ($data['order'] ?? $oldOrder); + $oldOrder = $piggyBank->order; + $newOrder = (int) ($data['order'] ?? $oldOrder); if ($oldOrder !== $newOrder) { $this->setOrder($piggyBank, $newOrder); } @@ -317,7 +317,7 @@ trait ModifiesPiggyBanks return; } - $dbNote = $piggyBank->notes()->first(); + $dbNote = $piggyBank->notes()->first(); if (null === $dbNote) { $dbNote = new Note(); $dbNote->noteable()->associate($piggyBank); @@ -328,15 +328,16 @@ trait ModifiesPiggyBanks public function setOrder(PiggyBank $piggyBank, int $newOrder): bool { - $oldOrder = $piggyBank->order; + $oldOrder = $piggyBank->order; // Log::debug(sprintf('Will move piggy bank #%d ("%s") from %d to %d', $piggyBank->id, $piggyBank->name, $oldOrder, $newOrder)); if ($newOrder > $oldOrder) { PiggyBank::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id') - ->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id') - ->where('accounts.user_id', $this->user->id) - ->where('piggy_banks.order', '<=', $newOrder)->where('piggy_banks.order', '>', $oldOrder) - ->where('piggy_banks.id', '!=', $piggyBank->id) - ->distinct()->decrement('piggy_banks.order'); + ->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id') + ->where('accounts.user_id', $this->user->id) + ->where('piggy_banks.order', '<=', $newOrder)->where('piggy_banks.order', '>', $oldOrder) + ->where('piggy_banks.id', '!=', $piggyBank->id) + ->distinct()->decrement('piggy_banks.order') + ; $piggyBank->order = $newOrder; Log::debug(sprintf('[1] Order of piggy #%d ("%s") from %d to %d', $piggyBank->id, $piggyBank->name, $oldOrder, $newOrder)); @@ -345,11 +346,12 @@ trait ModifiesPiggyBanks return true; } PiggyBank::leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id') - ->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id') - ->where('accounts.user_id', $this->user->id) - ->where('piggy_banks.order', '>=', $newOrder)->where('piggy_banks.order', '<', $oldOrder) - ->where('piggy_banks.id', '!=', $piggyBank->id) - ->distinct()->increment('piggy_banks.order'); + ->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id') + ->where('accounts.user_id', $this->user->id) + ->where('piggy_banks.order', '>=', $newOrder)->where('piggy_banks.order', '<', $oldOrder) + ->where('piggy_banks.id', '!=', $piggyBank->id) + ->distinct()->increment('piggy_banks.order') + ; $piggyBank->order = $newOrder; Log::debug(sprintf('[2] Order of piggy #%d ("%s") from %d to %d', $piggyBank->id, $piggyBank->name, $oldOrder, $newOrder)); @@ -370,7 +372,7 @@ trait ModifiesPiggyBanks } // if this account contains less than the amount, remove the current amount, update the amount and continue. $this->removeAmount($piggyBank, $account, $current); - $amount = bcsub($amount, $current); + $amount = bcsub($amount, $current); } } } diff --git a/changelog.md b/changelog.md index b12aaa634e..78e8c940df 100644 --- a/changelog.md +++ b/changelog.md @@ -7,11 +7,11 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed -- #9755 -- #9867 -- #9878 -- #10068 -- #10162 +- [Issue 9755](https://github.com/firefly-iii/firefly-iii/issues/9755) (Unable to create transactions with non-native currency accounts when "display amounts in native currency" is enabled) reported by @dicksonleong +- [Issue 9867](https://github.com/firefly-iii/firefly-iii/issues/9867) (Transactions from Jan 31 being counted in February) reported by @edbingo +- [Issue 9878](https://github.com/firefly-iii/firefly-iii/issues/9878) (Piggy bank currency - wrong setting displayed or setting not saved) reported by @dethegeek +- [Issue 10068](https://github.com/firefly-iii/firefly-iii/issues/10068) (Export Data isn't exporting all transactions in the data) reported by @firsttiger +- [Discussion 10162](https://github.com/orgs/firefly-iii/discussions/10162) (Reverse proxy and `X-Forwarded-Prefix` header) started by @frenchu ## 6.2.11 - 2025-04-21 diff --git a/config/firefly.php b/config/firefly.php index f83c90da92..da00eb3424 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -78,7 +78,7 @@ return [ 'running_balance_column' => env('USE_RUNNING_BALANCE', false), // see cer.php for exchange rates feature flag. ], - 'version' => '6.2.11', + 'version' => 'develop/2025-04-20', 'api_version' => '2.1.0', // field is no longer used. 'db_version' => 25, diff --git a/resources/assets/v1/mix-manifest.json b/resources/assets/v1/mix-manifest.json index 145eaf58f2..ff2938f703 100644 --- a/resources/assets/v1/mix-manifest.json +++ b/resources/assets/v1/mix-manifest.json @@ -20,12 +20,8 @@ "/public/v1/js/app.js.LICENSE.txt": "/public/v1/js/app.js.LICENSE.txt", "/public/v1/js/app_vue.js": "/public/v1/js/app_vue.js", "/public/v1/js/app_vue.js.LICENSE.txt": "/public/v1/js/app_vue.js.LICENSE.txt", - "/public/v1/js/create.js": "/public/v1/js/create.js", - "/public/v1/js/create.js.LICENSE.txt": "/public/v1/js/create.js.LICENSE.txt", "/public/v1/js/create_transaction.js": "/public/v1/js/create_transaction.js", "/public/v1/js/create_transaction.js.LICENSE.txt": "/public/v1/js/create_transaction.js.LICENSE.txt", - "/public/v1/js/edit.js": "/public/v1/js/edit.js", - "/public/v1/js/edit.js.LICENSE.txt": "/public/v1/js/edit.js.LICENSE.txt", "/public/v1/js/edit_transaction.js": "/public/v1/js/edit_transaction.js", "/public/v1/js/edit_transaction.js.LICENSE.txt": "/public/v1/js/edit_transaction.js.LICENSE.txt", "/public/v1/js/exchange-rates/index.js": "/public/v1/js/exchange-rates/index.js", @@ -100,8 +96,6 @@ "/public/v1/js/ff/transactions/mass/edit-bulk.js": "/public/v1/js/ff/transactions/mass/edit-bulk.js", "/public/v1/js/ff/transactions/mass/edit.js": "/public/v1/js/ff/transactions/mass/edit.js", "/public/v1/js/ff/transactions/show.js": "/public/v1/js/ff/transactions/show.js", - "/public/v1/js/index.js": "/public/v1/js/index.js", - "/public/v1/js/index.js.LICENSE.txt": "/public/v1/js/index.js.LICENSE.txt", "/public/v1/js/lib/Chart.bundle.min.js": "/public/v1/js/lib/Chart.bundle.min.js", "/public/v1/js/lib/accounting.min.js": "/public/v1/js/lib/accounting.min.js", "/public/v1/js/lib/bootstrap-multiselect.js": "/public/v1/js/lib/bootstrap-multiselect.js", @@ -126,7 +120,6 @@ "/public/v1/js/lib/moment/en_US.js": "/public/v1/js/lib/moment/en_US.js", "/public/v1/js/lib/moment/es_ES.js": "/public/v1/js/lib/moment/es_ES.js", "/public/v1/js/lib/moment/es_MX.js": "/public/v1/js/lib/moment/es_MX.js", - "/public/v1/js/lib/moment/fa_IR.js": "/public/v1/js/lib/moment/fa_IR.js", "/public/v1/js/lib/moment/fi_FI.js": "/public/v1/js/lib/moment/fi_FI.js", "/public/v1/js/lib/moment/fr_FR.js": "/public/v1/js/lib/moment/fr_FR.js", "/public/v1/js/lib/moment/hu_HU.js": "/public/v1/js/lib/moment/hu_HU.js", @@ -150,7 +143,6 @@ "/public/v1/js/lib/moment/vi_VN.js": "/public/v1/js/lib/moment/vi_VN.js", "/public/v1/js/lib/moment/zh_CN.js": "/public/v1/js/lib/moment/zh_CN.js", "/public/v1/js/lib/moment/zh_TW.js": "/public/v1/js/lib/moment/zh_TW.js", - "/public/v1/js/lib/moment-tz.js": "/public/v1/js/lib/moment-tz.js", "/public/v1/js/lib/moment.min.js": "/public/v1/js/lib/moment.min.js", "/public/v1/js/lib/respond.min.js": "/public/v1/js/lib/respond.min.js", "/public/v1/js/lib/typeahead/bloodhound.js": "/public/v1/js/lib/typeahead/bloodhound.js", @@ -162,8 +154,6 @@ "/public/v1/js/lib/vue.js": "/public/v1/js/lib/vue.js", "/public/v1/js/profile.js": "/public/v1/js/profile.js", "/public/v1/js/profile.js.LICENSE.txt": "/public/v1/js/profile.js.LICENSE.txt", - "/public/v1/js/show.js": "/public/v1/js/show.js", - "/public/v1/js/show.js.LICENSE.txt": "/public/v1/js/show.js.LICENSE.txt", "/public/v1/js/webhooks/create.js": "/public/v1/js/webhooks/create.js", "/public/v1/js/webhooks/create.js.LICENSE.txt": "/public/v1/js/webhooks/create.js.LICENSE.txt", "/public/v1/js/webhooks/edit.js": "/public/v1/js/webhooks/edit.js", From c57f36820b713dea845db47a1c60af8b37c30bd7 Mon Sep 17 00:00:00 2001 From: JC5 Date: Sun, 20 Apr 2025 21:21:56 +0200 Subject: [PATCH 9/9] =?UTF-8?q?=F0=9F=A4=96=20Auto=20commit=20for=20releas?= =?UTF-8?q?e=20'v6.2.12'=20on=202025-04-20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/firefly.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/firefly.php b/config/firefly.php index da00eb3424..e16d645d92 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -78,7 +78,7 @@ return [ 'running_balance_column' => env('USE_RUNNING_BALANCE', false), // see cer.php for exchange rates feature flag. ], - 'version' => 'develop/2025-04-20', + 'version' => '6.2.12', 'api_version' => '2.1.0', // field is no longer used. 'db_version' => 25,