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",