From 01695b3342d6e1a35c32fceb7afd1e48892c4554 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2025 04:08:56 +0100 Subject: [PATCH 01/24] Auto commit for release 'develop' on 2025-02-03 --- changelog.md | 20 ++++++++++---------- config/firefly.php | 2 +- resources/assets/v1/src/locales/pl.json | 6 +++--- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/changelog.md b/changelog.md index 52d6b46167..db58039faa 100644 --- a/changelog.md +++ b/changelog.md @@ -9,19 +9,19 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed -- #9713 -- #9727 -- #9729 -- #9730 -- #9731 -- #9732 -- #9736 -- #9738 -- #9744 +- [Issue 9713](https://github.com/firefly-iii/firefly-iii/issues/9713) (Many decimal points in amounts) reported by @memo-567 +- [Discussion 9727](https://github.com/orgs/firefly-iii/discussions/9727) (Odd behavior from graphs) started by @jbrandwi +- [Issue 9729](https://github.com/firefly-iii/firefly-iii/issues/9729) (Type mismatch in transaction collector) reported by @electrofloat +- [Issue 9730](https://github.com/firefly-iii/firefly-iii/issues/9730) (API: `PiggyBankAccountRead.id` should return string, returns int) reported by @dreautall +- [Issue 9731](https://github.com/firefly-iii/firefly-iii/issues/9731) ($userGroup must not be accessed before initialization) reported by @Azmodeszer +- [Issue 9732](https://github.com/firefly-iii/firefly-iii/issues/9732) (Editing dates of a piggy bank does not save) reported by @Simeam +- [Issue 9736](https://github.com/firefly-iii/firefly-iii/issues/9736) (Wrong `finalAccountBalance` result) reported by @gthbusrr +- [Issue 9738](https://github.com/firefly-iii/firefly-iii/issues/9738) (Missing pagination controls on exchange rate page) reported by @dicksonleong +- [Discussion 9744](https://github.com/orgs/firefly-iii/discussions/9744) (Downloading exchange rates results in 404 error) started by @electrofloat ### Added -- #9743 +- [PR 9743](https://github.com/firefly-iii/firefly-iii/pull/9743) (Feature nordic currencies) reported by @mansehr ## 6.2.1 - 2025-02-01 diff --git a/config/firefly.php b/config/firefly.php index ea8887f5bc..d3201beb64 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -81,7 +81,7 @@ return [ 'running_balance_column' => env('USE_RUNNING_BALANCE', false), // see cer.php for exchange rates feature flag. ], - 'version' => '6.2.2', + 'version' => 'develop/2025-02-03', 'api_version' => '2.1.0', // field is no longer used. 'db_version' => 25, diff --git a/resources/assets/v1/src/locales/pl.json b/resources/assets/v1/src/locales/pl.json index d2f4defc7e..5550e23310 100644 --- a/resources/assets/v1/src/locales/pl.json +++ b/resources/assets/v1/src/locales/pl.json @@ -28,7 +28,7 @@ "apply_rules_checkbox": "Zastosuj regu\u0142y", "fire_webhooks_checkbox": "Uruchom webhooki", "no_budget_pointer": "Wygl\u0105da na to, \u017ce nie masz jeszcze bud\u017cet\u00f3w. Powiniene\u015b utworzy\u0107 kilka na stronie bud\u017cet\u00f3w<\/a>. Bud\u017cety mog\u0105 Ci pom\u00f3c \u015bledzi\u0107 wydatki.", - "no_bill_pointer": "You seem to have no subscription yet. You should create some on the subscription<\/a>-page. Subscriptions can help you keep track of expenses.", + "no_bill_pointer": "Wygl\u0105da na to, \u017ce nie masz jeszcze subskrypcji. Powiniene\u015b utworzy\u0107 j\u0105 na stronie subskrypcji<\/a>. Subskrypcje mog\u0105 pom\u00f3c Ci \u015bledzi\u0107 wydatki.", "source_account": "Konto \u017ar\u00f3d\u0142owe", "hidden_fields_preferences": "Mo\u017cesz w\u0142\u0105czy\u0107 wi\u0119cej opcji transakcji w swoich ustawieniach<\/a>.", "destination_account": "Konto docelowe", @@ -151,7 +151,7 @@ "url": "URL", "active": "Aktywny", "interest_date": "Data odsetek", - "administration_currency": "Native currency", + "administration_currency": "Waluta natywna", "title": "Tytu\u0142", "date": "Data", "book_date": "Data ksi\u0119gowania", @@ -166,7 +166,7 @@ "webhook_delivery": "Dor\u0119czenie", "from_currency_to_currency": "{from} → {to}", "to_currency_from_currency": "{to} → {from}", - "rate": "Rate" + "rate": "Kurs" }, "list": { "title": "Tytu\u0142", From 065d1652119df5eb85abdf30c3d37367685e6e4b Mon Sep 17 00:00:00 2001 From: Sander Dorigo Date: Tue, 4 Feb 2025 08:28:43 +0100 Subject: [PATCH 02/24] Fix #9713 --- app/Http/Controllers/Json/ReconcileController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Json/ReconcileController.php b/app/Http/Controllers/Json/ReconcileController.php index 7037e7428a..a32c27178b 100644 --- a/app/Http/Controllers/Json/ReconcileController.php +++ b/app/Http/Controllers/Json/ReconcileController.php @@ -195,8 +195,8 @@ class ReconcileController extends Controller $startDate->subDay(); $currency = $this->accountRepos->getAccountCurrency($account) ?? $this->defaultCurrency; - $startBalance = Steam::finalAccountBalance($account, $startDate)['balance']; - $endBalance = Steam::finalAccountBalance($account, $end)['balance']; + $startBalance = Steam::bcround(Steam::finalAccountBalance($account, $startDate)['balance'], $currency->decimal_places); + $endBalance = Steam::bcround(Steam::finalAccountBalance($account, $end)['balance'], $currency->decimal_places); // get the transactions $selectionStart = clone $start; From 72132a19b0b3a57416d9ce5ad13c188129c3fb2c Mon Sep 17 00:00:00 2001 From: Sander Dorigo Date: Tue, 4 Feb 2025 08:30:27 +0100 Subject: [PATCH 03/24] Fix #9736 --- app/Http/Controllers/Account/ReconcileController.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/Http/Controllers/Account/ReconcileController.php b/app/Http/Controllers/Account/ReconcileController.php index a49b1b0c1a..1ad97d14e4 100644 --- a/app/Http/Controllers/Account/ReconcileController.php +++ b/app/Http/Controllers/Account/ReconcileController.php @@ -113,7 +113,6 @@ class ReconcileController extends Controller $end->endOfDay(); $startDate = clone $start; - $startDate->subDay(); $startBalance = Steam::bcround(Steam::finalAccountBalance($account, $startDate)['balance'], $currency->decimal_places); $endBalance = Steam::bcround(Steam::finalAccountBalance($account, $end)['balance'], $currency->decimal_places); $subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $account->accountType->type)); From 51f84b3060d0a220a842756f789e62bb129dad12 Mon Sep 17 00:00:00 2001 From: Sander Dorigo Date: Tue, 4 Feb 2025 08:37:02 +0100 Subject: [PATCH 04/24] Fix #9762 --- resources/views/piggy-banks/show.twig | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/resources/views/piggy-banks/show.twig b/resources/views/piggy-banks/show.twig index e91db15a5d..9bb716af79 100644 --- a/resources/views/piggy-banks/show.twig +++ b/resources/views/piggy-banks/show.twig @@ -71,8 +71,8 @@ {{ 'start_date'|_ }} - {% if piggyBank.startdate %} - {{ piggyBank.startdate.isoFormat(monthAndDayFormat) }} + {% if piggyBank.start_date %} + {{ piggyBank.start_date.isoFormat(monthAndDayFormat) }} {% else %} {{ 'no_start_date'|_ }} {% endif %} @@ -81,14 +81,14 @@ {{ 'target_date'|_ }} - {% if piggyBank.targetdate %} - {{ piggyBank.targetdate.isoFormat(monthAndDayFormat) }} + {% if piggyBank.target_date %} + {{ piggyBank.target_date.isoFormat(monthAndDayFormat) }} {% else %} {{ 'no_target_date'|_ }} {% endif %} - {% if piggyBank.targetdate and piggy.save_per_month %} + {% if piggyBank.target_date and piggy.save_per_month %} {{ 'suggested_amount'|_ }} From b36a50381bd069ee4d8a999e05bb710fc843498d Mon Sep 17 00:00:00 2001 From: Sander Dorigo Date: Tue, 4 Feb 2025 08:42:54 +0100 Subject: [PATCH 05/24] Fix #9747 --- resources/assets/v1/src/components/exchange-rates/Rates.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/assets/v1/src/components/exchange-rates/Rates.vue b/resources/assets/v1/src/components/exchange-rates/Rates.vue index 3639830270..150af3e8eb 100644 --- a/resources/assets/v1/src/components/exchange-rates/Rates.vue +++ b/resources/assets/v1/src/components/exchange-rates/Rates.vue @@ -97,10 +97,10 @@ > - + - +
From 8f6eefb5e74ca4d7cd0bba9a5b8140891ab2a980 Mon Sep 17 00:00:00 2001 From: Sander Dorigo Date: Tue, 4 Feb 2025 08:45:08 +0100 Subject: [PATCH 06/24] Fix #9745 --- app/Helpers/Collector/GroupCollector.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Helpers/Collector/GroupCollector.php b/app/Helpers/Collector/GroupCollector.php index 1c5cb8c91d..66062e2b86 100644 --- a/app/Helpers/Collector/GroupCollector.php +++ b/app/Helpers/Collector/GroupCollector.php @@ -100,7 +100,7 @@ class GroupCollector implements GroupCollectorInterface 'category_id', 'budget_id', ]; - $this->stringFields = ['amount', 'foreign_amount']; + $this->stringFields = ['amount', 'foreign_amount','native_amount','native_foreign_amount']; $this->total = 0; $this->fields = [ // group From 6ada5fa560491b81b897f2b0240cc842a516863f Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 4 Feb 2025 19:43:53 +0100 Subject: [PATCH 07/24] Fix #9751 --- app/Support/Steam.php | 233 +++++++++++++++++++++--------------------- 1 file changed, 118 insertions(+), 115 deletions(-) diff --git a/app/Support/Steam.php b/app/Support/Steam.php index 6616f5aebf..cafabdc33f 100644 --- a/app/Support/Steam.php +++ b/app/Support/Steam.php @@ -28,10 +28,11 @@ use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\Account; use FireflyIII\Models\Transaction; use FireflyIII\Models\TransactionCurrency; +use FireflyIII\Support\Facades\Amount; +use FireflyIII\Support\Http\Api\ExchangeRateConverter; use Illuminate\Support\Collection; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; -use FireflyIII\Support\Facades\Amount; /** * Class Steam. @@ -40,8 +41,8 @@ class Steam { public function getAccountCurrency(Account $account): ?TransactionCurrency { - $type = $account->accountType->type; - $list = config('firefly.valid_currency_account_types'); + $type = $account->accountType->type; + $list = config('firefly.valid_currency_account_types'); // return null if not in this list. if (!in_array($type, $list, true)) { @@ -63,7 +64,7 @@ class Steam Log::debug(sprintf('finalAccountBalanceInRange(#%d, %s, %s)', $account->id, $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s'))); // set up cache - $cache = new CacheProperties(); + $cache = new CacheProperties(); $cache->addProperty($account->id); $cache->addProperty('final-balance-in-range'); $cache->addProperty($start); @@ -72,66 +73,65 @@ class Steam return $cache->get(); } - $balances = []; - $formatted = $start->format('Y-m-d'); - $startBalance = $this->finalAccountBalance($account, $start); - $defaultCurrency = app('amount')->getNativeCurrencyByUserGroup($account->user->userGroup); - $accountCurrency = $this->getAccountCurrency($account); - $hasCurrency = null !== $accountCurrency; - $currency = $accountCurrency ?? $defaultCurrency; + $balances = []; + $formatted = $start->format('Y-m-d'); + $startBalance = $this->finalAccountBalance($account, $start); + $defaultCurrency = app('amount')->getNativeCurrencyByUserGroup($account->user->userGroup); + $accountCurrency = $this->getAccountCurrency($account); + $hasCurrency = null !== $accountCurrency; + $currency = $accountCurrency ?? $defaultCurrency; Log::debug(sprintf('Currency is %s', $currency->code)); if (!$hasCurrency) { Log::debug(sprintf('Also set start balance in %s', $defaultCurrency->code)); $startBalance[$defaultCurrency->code] ??= '0'; } - $currencies = [ + $currencies = [ $currency->id => $currency, $defaultCurrency->id => $defaultCurrency, ]; $startBalance[$currency->code] ??= '0'; - $balances[$formatted] = $startBalance; + $balances[$formatted] = $startBalance; Log::debug('Final start balance: ', $startBalance); // sums up the balance changes per day, for foreign, native and normal amounts. - $set = $account->transactions() - ->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') - ->where('transaction_journals.date', '>=', $start->format('Y-m-d H:i:s')) - ->where('transaction_journals.date', '<=', $end->format('Y-m-d H:i:s')) - ->groupBy('transaction_journals.date') - ->groupBy('transactions.transaction_currency_id') - ->groupBy('transactions.foreign_currency_id') - ->orderBy('transaction_journals.date', 'ASC') - ->whereNull('transaction_journals.deleted_at') - ->get( - [ // @phpstan-ignore-line - 'transaction_journals.date', - 'transactions.transaction_currency_id', - DB::raw('SUM(transactions.amount) AS modified'), - 'transactions.foreign_currency_id', - DB::raw('SUM(transactions.foreign_amount) AS modified_foreign'), - DB::raw('SUM(transactions.native_amount) AS modified_native'), - ] - ) - ; + $set = $account->transactions() + ->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') + ->where('transaction_journals.date', '>=', $start->format('Y-m-d H:i:s')) + ->where('transaction_journals.date', '<=', $end->format('Y-m-d H:i:s')) + ->groupBy('transaction_journals.date') + ->groupBy('transactions.transaction_currency_id') + ->groupBy('transactions.foreign_currency_id') + ->orderBy('transaction_journals.date', 'ASC') + ->whereNull('transaction_journals.deleted_at') + ->get( + [ // @phpstan-ignore-line + 'transaction_journals.date', + 'transactions.transaction_currency_id', + DB::raw('SUM(transactions.amount) AS modified'), + 'transactions.foreign_currency_id', + DB::raw('SUM(transactions.foreign_amount) AS modified_foreign'), + DB::raw('SUM(transactions.native_amount) AS modified_native'), + ] + ); - $currentBalance = $startBalance; + $currentBalance = $startBalance; /** @var Transaction $entry */ foreach ($set as $entry) { // normal, native and foreign amount - $carbon = new Carbon($entry->date, $entry->date_tz); - $modified = (string) (null === $entry->modified ? '0' : $entry->modified); - $foreignModified = (string) (null === $entry->modified_foreign ? '0' : $entry->modified_foreign); - $nativeModified = (string) (null === $entry->modified_native ? '0' : $entry->modified_native); + $carbon = new Carbon($entry->date, $entry->date_tz); + $modified = (string) (null === $entry->modified ? '0' : $entry->modified); + $foreignModified = (string) (null === $entry->modified_foreign ? '0' : $entry->modified_foreign); + $nativeModified = (string) (null === $entry->modified_native ? '0' : $entry->modified_native); // find currency of this entry. $currencies[$entry->transaction_currency_id] ??= TransactionCurrency::find($entry->transaction_currency_id); /** @var TransactionCurrency $entryCurrency */ - $entryCurrency = $currencies[$entry->transaction_currency_id]; + $entryCurrency = $currencies[$entry->transaction_currency_id]; Log::debug(sprintf('Processing transaction(s) on date %s', $carbon->format('Y-m-d H:i:s'))); @@ -163,7 +163,7 @@ class Steam if (!$convertToNative) { Log::debug(sprintf('Amount is %s %s, foreign amount is %s, native amount is %s', $entryCurrency->code, $modified, $foreignModified, $nativeModified)); // add to balance, as expected. - $currentBalance['balance'] = bcadd($currentBalance['balance'] ?? '0', $modified); + $currentBalance['balance'] = bcadd($currentBalance['balance'] ?? '0', $modified); // add to GBP, as expected. $currentBalance[$entryCurrency->code] = bcadd($currentBalance[$entryCurrency->code] ?? '0', $modified); } @@ -205,10 +205,10 @@ class Steam // Log::debug(sprintf('Trying bcround("%s",%d)', $number, $precision)); if (str_contains($number, '.')) { if ('-' !== $number[0]) { - return bcadd($number, '0.'.str_repeat('0', $precision).'5', $precision); + return bcadd($number, '0.' . str_repeat('0', $precision) . '5', $precision); } - return bcsub($number, '0.'.str_repeat('0', $precision).'5', $precision); + return bcsub($number, '0.' . str_repeat('0', $precision) . '5', $precision); } return $number; @@ -296,11 +296,11 @@ class Steam */ public function finalAccountBalance(Account $account, Carbon $date): array { - $cache = new CacheProperties(); + $cache = new CacheProperties(); $cache->addProperty($account->id); $cache->addProperty($date); if ($cache->has()) { - return $cache->get(); + //return $cache->get(); } Log::debug(sprintf('Now in finalAccountBalance(#%d, "%s", "%s")', $account->id, $account->name, $date->format('Y-m-d H:i:s'))); @@ -310,61 +310,47 @@ class Steam $accountCurrency = $this->getAccountCurrency($account); $hasCurrency = null !== $accountCurrency; $currency = $hasCurrency ? $accountCurrency : $native; - $return = []; - - // first, the "balance", as described earlier. - if ($convertToNative) { - // normal balance - $return['balance'] = (string) $account->transactions() - ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s')) - ->where('transactions.transaction_currency_id', $native->id) - ->sum('transactions.amount') - ; - // plus virtual balance, if the account has a virtual_balance in the native currency - if ($native->id === $accountCurrency?->id) { - $return['balance'] = bcadd('' === (string) $account->virtual_balance ? '0' : $account->virtual_balance, $return['balance']); - } - // Log::debug(sprintf('balance is (%s only) %s (with virtual balance)', $native->code, $this->bcround($return['balance'], 2))); - - // native balance - $return['native_balance'] = (string) $account->transactions() - ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s')) - ->whereNot('transactions.transaction_currency_id', $native->id) - ->sum('transactions.native_amount') - ; - // plus native virtual balance. - $return['native_balance'] = bcadd('' === (string) $account->native_virtual_balance ? '0' : $account->native_virtual_balance, $return['native_balance']); - // Log::debug(sprintf('native_balance is (all transactions to %s) %s (with virtual balance)', $native->code, $this->bcround($return['native_balance']))); - - // plus foreign transactions in THIS currency. - $sum = (string) $account->transactions() - ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s')) - ->whereNot('transactions.transaction_currency_id', $native->id) - ->where('transactions.foreign_currency_id', $native->id) - ->sum('transactions.foreign_amount') - ; - $return['native_balance'] = bcadd($return['native_balance'], $sum); - - // Log::debug(sprintf('Foreign amount transactions add (%s only) %s, total native_balance is now %s', $native->code, $this->bcround($sum), $this->bcround($return['native_balance']))); - } - + $return = [ + 'balance' => '0', + 'native_balance' => '0', + ]; // balance(s) in other (all) currencies. - $array = $account->transactions() - ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->leftJoin('transaction_currencies', 'transaction_currencies.id', '=', 'transactions.transaction_currency_id') - ->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s')) - ->get(['transaction_currencies.code', 'transactions.amount'])->toArray() - ; - $others = $this->groupAndSumTransactions($array, 'code', 'amount'); - // Log::debug('All balances are (joined)', $others); - // if the account has no own currency preference, drop balance in favor of native balance - if ($hasCurrency && !$convertToNative) { + $array = $account->transactions() + ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') + ->leftJoin('transaction_currencies', 'transaction_currencies.id', '=', 'transactions.transaction_currency_id') + ->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s')) + ->get(['transaction_currencies.code', 'transactions.amount'])->toArray(); + $others = $this->groupAndSumTransactions($array, 'code', 'amount'); + Log::debug('All balances are (joined)', $others); + // if there is no request to convert, take this as "balance" and "native_balance". + if (!$convertToNative) { $return['balance'] = $others[$currency->code] ?? '0'; $return['native_balance'] = $others[$currency->code] ?? '0'; - // Log::debug(sprintf('Set balance + native_balance to %s', $return['balance'])); + Log::debug(sprintf('Set balance + native_balance to %s', $return['balance'])); + } + // if there is a request to convert, convert to "native_balance" and use "balance" for whichever amount is in the native currency. + if ($convertToNative) { + $return['balance'] = $others[$native->code] ?? '0'; + $return['native_balance'] = $this->convertAllBalances($others, $native, $date);// todo sum all and convert. + Log::debug(sprintf('Set balance to %s and native_balance to %s', $return['balance'], $return['native_balance'])); + } + + // either way, the balance is always combined with the virtual balance: + $virtualBalance = (string) ('' === (string) $account->virtual_balance ? '0' : $account->virtual_balance); + $return['balance'] = bcadd($return['balance'], $virtualBalance); + Log::debug(sprintf('Virtual balance makes the total %s', $return['balance'])); + + if ($convertToNative) { + // the native balance is combined with a converted virtual_balance: + $converter = new ExchangeRateConverter(); + $nativeVirtualBalance = $converter->convert($currency, $native, $date, $virtualBalance); + $return['native_balance'] = bcadd($nativeVirtualBalance, $return['native_balance']); + Log::debug(sprintf('Native virtual balance makes the native total %s', $return['native_balance'])); + } + if (!$convertToNative) { + // if not, also increase the native balance for consistency. + $return['native_balance'] = bcadd($return['native_balance'], $virtualBalance); + Log::debug(sprintf('Virtual balance makes the (native) total %s', $return['balance'])); } // if the currency is the same as the native currency, set the native_balance to the balance for consistency. @@ -372,18 +358,20 @@ class Steam // $return['native_balance'] = $return['balance']; // } - if (!$hasCurrency && array_key_exists('balance', $return)) { - // Log::debug('Account has no currency preference, dropping balance in favor of native balance.'); - $sum = bcadd($return['balance'], $return['native_balance']); - // Log::debug(sprintf('%s + %s = %s', $return['balance'], $return['native_balance'], $sum)); - $return['native_balance'] = $sum; - unset($return['balance']); - } +// if (!$hasCurrency && array_key_exists('balance', $return)) { +// // Log::debug('Account has no currency preference, dropping balance in favor of native balance.'); +// $sum = bcadd($return['balance'], $return['native_balance']); +// // Log::debug(sprintf('%s + %s = %s', $return['balance'], $return['native_balance'], $sum)); +// $return['native_balance'] = $sum; +// unset($return['balance']); +// } $final = array_merge($return, $others); - // Log::debug('Return is', $final); - $cache->store($final); +// // Log::debug('Return is', $final); - return array_merge($return, $others); + $cache->store($final); + return $final; + + //return array_merge($return, $others); // Log::debug('Return is', $final); } @@ -487,15 +475,15 @@ class Steam { $list = []; - $set = auth()->user()->transactions() - ->whereIn('transactions.account_id', $accounts) - ->groupBy(['transactions.account_id', 'transaction_journals.user_id']) - ->get(['transactions.account_id', \DB::raw('MAX(transaction_journals.date) AS max_date')]) // @phpstan-ignore-line + $set = auth()->user()->transactions() + ->whereIn('transactions.account_id', $accounts) + ->groupBy(['transactions.account_id', 'transaction_journals.user_id']) + ->get(['transactions.account_id', \DB::raw('MAX(transaction_journals.date) AS max_date')]) // @phpstan-ignore-line ; /** @var Transaction $entry */ foreach ($set as $entry) { - $date = new Carbon($entry->max_date, config('app.timezone')); + $date = new Carbon($entry->max_date, config('app.timezone')); $date->setTimezone(config('app.timezone')); $list[(int) $entry->account_id] = $date; } @@ -570,9 +558,9 @@ class Steam public function getSafeUrl(string $unknownUrl, string $safeUrl): string { // Log::debug(sprintf('getSafeUrl(%s, %s)', $unknownUrl, $safeUrl)); - $returnUrl = $safeUrl; - $unknownHost = parse_url($unknownUrl, PHP_URL_HOST); - $safeHost = parse_url($safeUrl, PHP_URL_HOST); + $returnUrl = $safeUrl; + $unknownHost = parse_url($unknownUrl, PHP_URL_HOST); + $safeHost = parse_url($safeUrl, PHP_URL_HOST); if (null !== $unknownHost && $unknownHost === $safeHost) { $returnUrl = $unknownUrl; @@ -609,7 +597,7 @@ class Steam */ public function floatalize(string $value): string { - $value = strtoupper($value); + $value = strtoupper($value); if (!str_contains($value, 'E')) { return $value; } @@ -687,4 +675,19 @@ class Steam return $amount; } + + private function convertAllBalances(array $others, TransactionCurrency $native, Carbon $date): string { + $total = '0'; + $converter = new ExchangeRateConverter(); + foreach($others as $key => $amount) { + $currency = TransactionCurrency::where('code', $key)->first(); + if(null === $currency) { + continue; + } + $current = $converter->convert($currency, $native, $date, $amount); + Log::debug(sprintf('Convert %s %s to %s %s', $currency->code, $amount, $native->code, $current)); + $total = bcadd($current, $total); + } + return $total; + } } From 2297589dca8e073946b1c6493067cfa84249e721 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 4 Feb 2025 19:48:38 +0100 Subject: [PATCH 08/24] Auto commit for release 'develop' on 2025-02-04 --- app/Helpers/Collector/GroupCollector.php | 2 +- app/Support/Steam.php | 167 ++++++++++---------- composer.lock | 12 +- config/firefly.php | 2 +- package-lock.json | 188 +++++++++++------------ resources/assets/v1/src/locales/pl.json | 2 +- resources/assets/v1/src/locales/sl.json | 2 +- 7 files changed, 190 insertions(+), 185 deletions(-) diff --git a/app/Helpers/Collector/GroupCollector.php b/app/Helpers/Collector/GroupCollector.php index 66062e2b86..7d090996a7 100644 --- a/app/Helpers/Collector/GroupCollector.php +++ b/app/Helpers/Collector/GroupCollector.php @@ -100,7 +100,7 @@ class GroupCollector implements GroupCollectorInterface 'category_id', 'budget_id', ]; - $this->stringFields = ['amount', 'foreign_amount','native_amount','native_foreign_amount']; + $this->stringFields = ['amount', 'foreign_amount', 'native_amount', 'native_foreign_amount']; $this->total = 0; $this->fields = [ // group diff --git a/app/Support/Steam.php b/app/Support/Steam.php index cafabdc33f..804a386e44 100644 --- a/app/Support/Steam.php +++ b/app/Support/Steam.php @@ -41,8 +41,8 @@ class Steam { public function getAccountCurrency(Account $account): ?TransactionCurrency { - $type = $account->accountType->type; - $list = config('firefly.valid_currency_account_types'); + $type = $account->accountType->type; + $list = config('firefly.valid_currency_account_types'); // return null if not in this list. if (!in_array($type, $list, true)) { @@ -64,7 +64,7 @@ class Steam Log::debug(sprintf('finalAccountBalanceInRange(#%d, %s, %s)', $account->id, $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s'))); // set up cache - $cache = new CacheProperties(); + $cache = new CacheProperties(); $cache->addProperty($account->id); $cache->addProperty('final-balance-in-range'); $cache->addProperty($start); @@ -73,65 +73,66 @@ class Steam return $cache->get(); } - $balances = []; - $formatted = $start->format('Y-m-d'); - $startBalance = $this->finalAccountBalance($account, $start); - $defaultCurrency = app('amount')->getNativeCurrencyByUserGroup($account->user->userGroup); - $accountCurrency = $this->getAccountCurrency($account); - $hasCurrency = null !== $accountCurrency; - $currency = $accountCurrency ?? $defaultCurrency; + $balances = []; + $formatted = $start->format('Y-m-d'); + $startBalance = $this->finalAccountBalance($account, $start); + $defaultCurrency = app('amount')->getNativeCurrencyByUserGroup($account->user->userGroup); + $accountCurrency = $this->getAccountCurrency($account); + $hasCurrency = null !== $accountCurrency; + $currency = $accountCurrency ?? $defaultCurrency; Log::debug(sprintf('Currency is %s', $currency->code)); if (!$hasCurrency) { Log::debug(sprintf('Also set start balance in %s', $defaultCurrency->code)); $startBalance[$defaultCurrency->code] ??= '0'; } - $currencies = [ + $currencies = [ $currency->id => $currency, $defaultCurrency->id => $defaultCurrency, ]; $startBalance[$currency->code] ??= '0'; - $balances[$formatted] = $startBalance; + $balances[$formatted] = $startBalance; Log::debug('Final start balance: ', $startBalance); // sums up the balance changes per day, for foreign, native and normal amounts. - $set = $account->transactions() - ->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') - ->where('transaction_journals.date', '>=', $start->format('Y-m-d H:i:s')) - ->where('transaction_journals.date', '<=', $end->format('Y-m-d H:i:s')) - ->groupBy('transaction_journals.date') - ->groupBy('transactions.transaction_currency_id') - ->groupBy('transactions.foreign_currency_id') - ->orderBy('transaction_journals.date', 'ASC') - ->whereNull('transaction_journals.deleted_at') - ->get( - [ // @phpstan-ignore-line - 'transaction_journals.date', - 'transactions.transaction_currency_id', - DB::raw('SUM(transactions.amount) AS modified'), - 'transactions.foreign_currency_id', - DB::raw('SUM(transactions.foreign_amount) AS modified_foreign'), - DB::raw('SUM(transactions.native_amount) AS modified_native'), - ] - ); + $set = $account->transactions() + ->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') + ->where('transaction_journals.date', '>=', $start->format('Y-m-d H:i:s')) + ->where('transaction_journals.date', '<=', $end->format('Y-m-d H:i:s')) + ->groupBy('transaction_journals.date') + ->groupBy('transactions.transaction_currency_id') + ->groupBy('transactions.foreign_currency_id') + ->orderBy('transaction_journals.date', 'ASC') + ->whereNull('transaction_journals.deleted_at') + ->get( + [ // @phpstan-ignore-line + 'transaction_journals.date', + 'transactions.transaction_currency_id', + DB::raw('SUM(transactions.amount) AS modified'), + 'transactions.foreign_currency_id', + DB::raw('SUM(transactions.foreign_amount) AS modified_foreign'), + DB::raw('SUM(transactions.native_amount) AS modified_native'), + ] + ) + ; - $currentBalance = $startBalance; + $currentBalance = $startBalance; /** @var Transaction $entry */ foreach ($set as $entry) { // normal, native and foreign amount - $carbon = new Carbon($entry->date, $entry->date_tz); - $modified = (string) (null === $entry->modified ? '0' : $entry->modified); - $foreignModified = (string) (null === $entry->modified_foreign ? '0' : $entry->modified_foreign); - $nativeModified = (string) (null === $entry->modified_native ? '0' : $entry->modified_native); + $carbon = new Carbon($entry->date, $entry->date_tz); + $modified = (string) (null === $entry->modified ? '0' : $entry->modified); + $foreignModified = (string) (null === $entry->modified_foreign ? '0' : $entry->modified_foreign); + $nativeModified = (string) (null === $entry->modified_native ? '0' : $entry->modified_native); // find currency of this entry. $currencies[$entry->transaction_currency_id] ??= TransactionCurrency::find($entry->transaction_currency_id); /** @var TransactionCurrency $entryCurrency */ - $entryCurrency = $currencies[$entry->transaction_currency_id]; + $entryCurrency = $currencies[$entry->transaction_currency_id]; Log::debug(sprintf('Processing transaction(s) on date %s', $carbon->format('Y-m-d H:i:s'))); @@ -163,7 +164,7 @@ class Steam if (!$convertToNative) { Log::debug(sprintf('Amount is %s %s, foreign amount is %s, native amount is %s', $entryCurrency->code, $modified, $foreignModified, $nativeModified)); // add to balance, as expected. - $currentBalance['balance'] = bcadd($currentBalance['balance'] ?? '0', $modified); + $currentBalance['balance'] = bcadd($currentBalance['balance'] ?? '0', $modified); // add to GBP, as expected. $currentBalance[$entryCurrency->code] = bcadd($currentBalance[$entryCurrency->code] ?? '0', $modified); } @@ -205,10 +206,10 @@ class Steam // Log::debug(sprintf('Trying bcround("%s",%d)', $number, $precision)); if (str_contains($number, '.')) { if ('-' !== $number[0]) { - return bcadd($number, '0.' . str_repeat('0', $precision) . '5', $precision); + return bcadd($number, '0.'.str_repeat('0', $precision).'5', $precision); } - return bcsub($number, '0.' . str_repeat('0', $precision) . '5', $precision); + return bcsub($number, '0.'.str_repeat('0', $precision).'5', $precision); } return $number; @@ -296,31 +297,32 @@ class Steam */ public function finalAccountBalance(Account $account, Carbon $date): array { - $cache = new CacheProperties(); + $cache = new CacheProperties(); $cache->addProperty($account->id); $cache->addProperty($date); if ($cache->has()) { - //return $cache->get(); + // return $cache->get(); } Log::debug(sprintf('Now in finalAccountBalance(#%d, "%s", "%s")', $account->id, $account->name, $date->format('Y-m-d H:i:s'))); - $native = Amount::getNativeCurrencyByUserGroup($account->user->userGroup); - $convertToNative = Amount::convertToNative($account->user); - $accountCurrency = $this->getAccountCurrency($account); - $hasCurrency = null !== $accountCurrency; - $currency = $hasCurrency ? $accountCurrency : $native; - $return = [ + $native = Amount::getNativeCurrencyByUserGroup($account->user->userGroup); + $convertToNative = Amount::convertToNative($account->user); + $accountCurrency = $this->getAccountCurrency($account); + $hasCurrency = null !== $accountCurrency; + $currency = $hasCurrency ? $accountCurrency : $native; + $return = [ 'balance' => '0', 'native_balance' => '0', ]; // balance(s) in other (all) currencies. - $array = $account->transactions() - ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->leftJoin('transaction_currencies', 'transaction_currencies.id', '=', 'transactions.transaction_currency_id') - ->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s')) - ->get(['transaction_currencies.code', 'transactions.amount'])->toArray(); - $others = $this->groupAndSumTransactions($array, 'code', 'amount'); + $array = $account->transactions() + ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') + ->leftJoin('transaction_currencies', 'transaction_currencies.id', '=', 'transactions.transaction_currency_id') + ->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s')) + ->get(['transaction_currencies.code', 'transactions.amount'])->toArray() + ; + $others = $this->groupAndSumTransactions($array, 'code', 'amount'); Log::debug('All balances are (joined)', $others); // if there is no request to convert, take this as "balance" and "native_balance". if (!$convertToNative) { @@ -331,7 +333,7 @@ class Steam // if there is a request to convert, convert to "native_balance" and use "balance" for whichever amount is in the native currency. if ($convertToNative) { $return['balance'] = $others[$native->code] ?? '0'; - $return['native_balance'] = $this->convertAllBalances($others, $native, $date);// todo sum all and convert. + $return['native_balance'] = $this->convertAllBalances($others, $native, $date); // todo sum all and convert. Log::debug(sprintf('Set balance to %s and native_balance to %s', $return['balance'], $return['native_balance'])); } @@ -358,20 +360,21 @@ class Steam // $return['native_balance'] = $return['balance']; // } -// if (!$hasCurrency && array_key_exists('balance', $return)) { -// // Log::debug('Account has no currency preference, dropping balance in favor of native balance.'); -// $sum = bcadd($return['balance'], $return['native_balance']); -// // Log::debug(sprintf('%s + %s = %s', $return['balance'], $return['native_balance'], $sum)); -// $return['native_balance'] = $sum; -// unset($return['balance']); -// } - $final = array_merge($return, $others); -// // Log::debug('Return is', $final); + // if (!$hasCurrency && array_key_exists('balance', $return)) { + // // Log::debug('Account has no currency preference, dropping balance in favor of native balance.'); + // $sum = bcadd($return['balance'], $return['native_balance']); + // // Log::debug(sprintf('%s + %s = %s', $return['balance'], $return['native_balance'], $sum)); + // $return['native_balance'] = $sum; + // unset($return['balance']); + // } + $final = array_merge($return, $others); + // // Log::debug('Return is', $final); $cache->store($final); + return $final; - //return array_merge($return, $others); + // return array_merge($return, $others); // Log::debug('Return is', $final); } @@ -475,15 +478,15 @@ class Steam { $list = []; - $set = auth()->user()->transactions() - ->whereIn('transactions.account_id', $accounts) - ->groupBy(['transactions.account_id', 'transaction_journals.user_id']) - ->get(['transactions.account_id', \DB::raw('MAX(transaction_journals.date) AS max_date')]) // @phpstan-ignore-line + $set = auth()->user()->transactions() + ->whereIn('transactions.account_id', $accounts) + ->groupBy(['transactions.account_id', 'transaction_journals.user_id']) + ->get(['transactions.account_id', \DB::raw('MAX(transaction_journals.date) AS max_date')]) // @phpstan-ignore-line ; /** @var Transaction $entry */ foreach ($set as $entry) { - $date = new Carbon($entry->max_date, config('app.timezone')); + $date = new Carbon($entry->max_date, config('app.timezone')); $date->setTimezone(config('app.timezone')); $list[(int) $entry->account_id] = $date; } @@ -558,9 +561,9 @@ class Steam public function getSafeUrl(string $unknownUrl, string $safeUrl): string { // Log::debug(sprintf('getSafeUrl(%s, %s)', $unknownUrl, $safeUrl)); - $returnUrl = $safeUrl; - $unknownHost = parse_url($unknownUrl, PHP_URL_HOST); - $safeHost = parse_url($safeUrl, PHP_URL_HOST); + $returnUrl = $safeUrl; + $unknownHost = parse_url($unknownUrl, PHP_URL_HOST); + $safeHost = parse_url($safeUrl, PHP_URL_HOST); if (null !== $unknownHost && $unknownHost === $safeHost) { $returnUrl = $unknownUrl; @@ -597,7 +600,7 @@ class Steam */ public function floatalize(string $value): string { - $value = strtoupper($value); + $value = strtoupper($value); if (!str_contains($value, 'E')) { return $value; } @@ -676,18 +679,20 @@ class Steam return $amount; } - private function convertAllBalances(array $others, TransactionCurrency $native, Carbon $date): string { - $total = '0'; - $converter = new ExchangeRateConverter(); - foreach($others as $key => $amount) { + private function convertAllBalances(array $others, TransactionCurrency $native, Carbon $date): string + { + $total = '0'; + $converter = new ExchangeRateConverter(); + foreach ($others as $key => $amount) { $currency = TransactionCurrency::where('code', $key)->first(); - if(null === $currency) { + if (null === $currency) { continue; } - $current = $converter->convert($currency, $native, $date, $amount); + $current = $converter->convert($currency, $native, $date, $amount); Log::debug(sprintf('Convert %s %s to %s %s', $currency->code, $amount, $native->code, $current)); - $total = bcadd($current, $total); + $total = bcadd($current, $total); } + return $total; } } diff --git a/composer.lock b/composer.lock index a0117c3388..27c5088853 100644 --- a/composer.lock +++ b/composer.lock @@ -1571,16 +1571,16 @@ }, { "name": "guzzlehttp/uri-template", - "version": "v1.0.3", + "version": "v1.0.4", "source": { "type": "git", "url": "https://github.com/guzzle/uri-template.git", - "reference": "ecea8feef63bd4fef1f037ecb288386999ecc11c" + "reference": "30e286560c137526eccd4ce21b2de477ab0676d2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/uri-template/zipball/ecea8feef63bd4fef1f037ecb288386999ecc11c", - "reference": "ecea8feef63bd4fef1f037ecb288386999ecc11c", + "url": "https://api.github.com/repos/guzzle/uri-template/zipball/30e286560c137526eccd4ce21b2de477ab0676d2", + "reference": "30e286560c137526eccd4ce21b2de477ab0676d2", "shasum": "" }, "require": { @@ -1637,7 +1637,7 @@ ], "support": { "issues": "https://github.com/guzzle/uri-template/issues", - "source": "https://github.com/guzzle/uri-template/tree/v1.0.3" + "source": "https://github.com/guzzle/uri-template/tree/v1.0.4" }, "funding": [ { @@ -1653,7 +1653,7 @@ "type": "tidelift" } ], - "time": "2023-12-03T19:50:20+00:00" + "time": "2025-02-03T10:55:03+00:00" }, { "name": "jc5/google2fa-laravel", diff --git a/config/firefly.php b/config/firefly.php index d3201beb64..499253dbbe 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -81,7 +81,7 @@ return [ 'running_balance_column' => env('USE_RUNNING_BALANCE', false), // see cer.php for exchange rates feature flag. ], - 'version' => 'develop/2025-02-03', + 'version' => 'develop/2025-02-04', 'api_version' => '2.1.0', // field is no longer used. 'db_version' => 25, diff --git a/package-lock.json b/package-lock.json index 7cd97b3125..5f615fd967 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2591,9 +2591,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.34.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.0.tgz", - "integrity": "sha512-Eeao7ewDq79jVEsrtWIj5RNqB8p2knlm9fhR6uJ2gqP7UfbLrTrxevudVrEPDM7Wkpn/HpRC2QfazH7MXLz3vQ==", + "version": "4.34.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.2.tgz", + "integrity": "sha512-6Fyg9yQbwJR+ykVdT9sid1oc2ewejS6h4wzQltmJfSW53N60G/ah9pngXGANdy9/aaE/TcUFpWosdm7JXS1WTQ==", "cpu": [ "arm" ], @@ -2605,9 +2605,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.34.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.0.tgz", - "integrity": "sha512-yVh0Kf1f0Fq4tWNf6mWcbQBCLDpDrDEl88lzPgKhrgTcDrTtlmun92ywEF9dCjmYO3EFiSuJeeo9cYRxl2FswA==", + "version": "4.34.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.2.tgz", + "integrity": "sha512-K5GfWe+vtQ3kyEbihrimM38UgX57UqHp+oME7X/EX9Im6suwZfa7Hsr8AtzbJvukTpwMGs+4s29YMSO3rwWtsw==", "cpu": [ "arm64" ], @@ -2619,9 +2619,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.34.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.0.tgz", - "integrity": "sha512-gCs0ErAZ9s0Osejpc3qahTsqIPUDjSKIyxK/0BGKvL+Tn0n3Kwvj8BrCv7Y5sR1Ypz1K2qz9Ny0VvkVyoXBVUQ==", + "version": "4.34.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.2.tgz", + "integrity": "sha512-PSN58XG/V/tzqDb9kDGutUruycgylMlUE59f40ny6QIRNsTEIZsrNQTJKUN2keMMSmlzgunMFqyaGLmly39sug==", "cpu": [ "arm64" ], @@ -2633,9 +2633,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.34.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.0.tgz", - "integrity": "sha512-aIB5Anc8hngk15t3GUkiO4pv42ykXHfmpXGS+CzM9CTyiWyT8HIS5ygRAy7KcFb/wiw4Br+vh1byqcHRTfq2tQ==", + "version": "4.34.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.2.tgz", + "integrity": "sha512-gQhK788rQJm9pzmXyfBB84VHViDERhAhzGafw+E5mUpnGKuxZGkMVDa3wgDFKT6ukLC5V7QTifzsUKdNVxp5qQ==", "cpu": [ "x64" ], @@ -2647,9 +2647,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.34.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.0.tgz", - "integrity": "sha512-kpdsUdMlVJMRMaOf/tIvxk8TQdzHhY47imwmASOuMajg/GXpw8GKNd8LNwIHE5Yd1onehNpcUB9jHY6wgw9nHQ==", + "version": "4.34.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.2.tgz", + "integrity": "sha512-eiaHgQwGPpxLC3+zTAcdKl4VsBl3r0AiJOd1Um/ArEzAjN/dbPK1nROHrVkdnoE6p7Svvn04w3f/jEZSTVHunA==", "cpu": [ "arm64" ], @@ -2661,9 +2661,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.34.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.0.tgz", - "integrity": "sha512-D0RDyHygOBCQiqookcPevrvgEarN0CttBecG4chOeIYCNtlKHmf5oi5kAVpXV7qs0Xh/WO2RnxeicZPtT50V0g==", + "version": "4.34.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.2.tgz", + "integrity": "sha512-lhdiwQ+jf8pewYOTG4bag0Qd68Jn1v2gO1i0mTuiD+Qkt5vNfHVK/jrT7uVvycV8ZchlzXp5HDVmhpzjC6mh0g==", "cpu": [ "x64" ], @@ -2675,9 +2675,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.34.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.0.tgz", - "integrity": "sha512-mCIw8j5LPDXmCOW8mfMZwT6F/Kza03EnSr4wGYEswrEfjTfVsFOxvgYfuRMxTuUF/XmRb9WSMD5GhCWDe2iNrg==", + "version": "4.34.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.2.tgz", + "integrity": "sha512-lfqTpWjSvbgQP1vqGTXdv+/kxIznKXZlI109WkIFPbud41bjigjNmOAAKoazmRGx+k9e3rtIdbq2pQZPV1pMig==", "cpu": [ "arm" ], @@ -2689,9 +2689,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.34.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.0.tgz", - "integrity": "sha512-AwwldAu4aCJPob7zmjuDUMvvuatgs8B/QiVB0KwkUarAcPB3W+ToOT+18TQwY4z09Al7G0BvCcmLRop5zBLTag==", + "version": "4.34.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.2.tgz", + "integrity": "sha512-RGjqULqIurqqv+NJTyuPgdZhka8ImMLB32YwUle2BPTDqDoXNgwFjdjQC59FbSk08z0IqlRJjrJ0AvDQ5W5lpw==", "cpu": [ "arm" ], @@ -2703,9 +2703,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.34.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.0.tgz", - "integrity": "sha512-e7kDUGVP+xw05pV65ZKb0zulRploU3gTu6qH1qL58PrULDGxULIS0OSDQJLH7WiFnpd3ZKUU4VM3u/Z7Zw+e7Q==", + "version": "4.34.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.2.tgz", + "integrity": "sha512-ZvkPiheyXtXlFqHpsdgscx+tZ7hoR59vOettvArinEspq5fxSDSgfF+L5wqqJ9R4t+n53nyn0sKxeXlik7AY9Q==", "cpu": [ "arm64" ], @@ -2717,9 +2717,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.34.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.0.tgz", - "integrity": "sha512-SXYJw3zpwHgaBqTXeAZ31qfW/v50wq4HhNVvKFhRr5MnptRX2Af4KebLWR1wpxGJtLgfS2hEPuALRIY3LPAAcA==", + "version": "4.34.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.2.tgz", + "integrity": "sha512-UlFk+E46TZEoxD9ufLKDBzfSG7Ki03fo6hsNRRRHF+KuvNZ5vd1RRVQm8YZlGsjcJG8R252XFK0xNPay+4WV7w==", "cpu": [ "arm64" ], @@ -2731,9 +2731,9 @@ ] }, "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.34.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.0.tgz", - "integrity": "sha512-e5XiCinINCI4RdyU3sFyBH4zzz7LiQRvHqDtRe9Dt8o/8hTBaYpdPimayF00eY2qy5j4PaaWK0azRgUench6WQ==", + "version": "4.34.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.2.tgz", + "integrity": "sha512-hJhfsD9ykx59jZuuoQgYT1GEcNNi3RCoEmbo5OGfG8RlHOiVS7iVNev9rhLKh7UBYq409f4uEw0cclTXx8nh8Q==", "cpu": [ "loong64" ], @@ -2745,9 +2745,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.34.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.0.tgz", - "integrity": "sha512-3SWN3e0bAsm9ToprLFBSro8nJe6YN+5xmB11N4FfNf92wvLye/+Rh5JGQtKOpwLKt6e61R1RBc9g+luLJsc23A==", + "version": "4.34.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.2.tgz", + "integrity": "sha512-g/O5IpgtrQqPegvqopvmdCF9vneLE7eqYfdPWW8yjPS8f63DNam3U4ARL1PNNB64XHZDHKpvO2Giftf43puB8Q==", "cpu": [ "ppc64" ], @@ -2759,9 +2759,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.34.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.0.tgz", - "integrity": "sha512-B1Oqt3GLh7qmhvfnc2WQla4NuHlcxAD5LyueUi5WtMc76ZWY+6qDtQYqnxARx9r+7mDGfamD+8kTJO0pKUJeJA==", + "version": "4.34.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.2.tgz", + "integrity": "sha512-bSQijDC96M6PuooOuXHpvXUYiIwsnDmqGU8+br2U7iPoykNi9JtMUpN7K6xml29e0evK0/g0D1qbAUzWZFHY5Q==", "cpu": [ "riscv64" ], @@ -2773,9 +2773,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.34.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.0.tgz", - "integrity": "sha512-UfUCo0h/uj48Jq2lnhX0AOhZPSTAq3Eostas+XZ+GGk22pI+Op1Y6cxQ1JkUuKYu2iU+mXj1QjPrZm9nNWV9rg==", + "version": "4.34.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.2.tgz", + "integrity": "sha512-49TtdeVAsdRuiUHXPrFVucaP4SivazetGUVH8CIxVsNsaPHV4PFkpLmH9LeqU/R4Nbgky9lzX5Xe1NrzLyraVA==", "cpu": [ "s390x" ], @@ -2787,9 +2787,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.34.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.0.tgz", - "integrity": "sha512-chZLTUIPbgcpm+Z7ALmomXW8Zh+wE2icrG+K6nt/HenPLmtwCajhQC5flNSk1Xy5EDMt/QAOz2MhzfOfJOLSiA==", + "version": "4.34.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.2.tgz", + "integrity": "sha512-j+jFdfOycLIQ7FWKka9Zd3qvsIyugg5LeZuHF6kFlXo6MSOc6R1w37YUVy8VpAKd81LMWGi5g9J25P09M0SSIw==", "cpu": [ "x64" ], @@ -2801,9 +2801,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.34.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.0.tgz", - "integrity": "sha512-jo0UolK70O28BifvEsFD/8r25shFezl0aUk2t0VJzREWHkq19e+pcLu4kX5HiVXNz5qqkD+aAq04Ct8rkxgbyQ==", + "version": "4.34.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.2.tgz", + "integrity": "sha512-aDPHyM/D2SpXfSNCVWCxyHmOqN9qb7SWkY1+vaXqMNMXslZYnwh9V/UCudl6psyG0v6Ukj7pXanIpfZwCOEMUg==", "cpu": [ "x64" ], @@ -2815,9 +2815,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.34.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.0.tgz", - "integrity": "sha512-Vmg0NhAap2S54JojJchiu5An54qa6t/oKT7LmDaWggpIcaiL8WcWHEN6OQrfTdL6mQ2GFyH7j2T5/3YPEDOOGA==", + "version": "4.34.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.2.tgz", + "integrity": "sha512-LQRkCyUBnAo7r8dbEdtNU08EKLCJMgAk2oP5H3R7BnUlKLqgR3dUjrLBVirmc1RK6U6qhtDw29Dimeer8d5hzQ==", "cpu": [ "arm64" ], @@ -2829,9 +2829,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.34.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.0.tgz", - "integrity": "sha512-CV2aqhDDOsABKHKhNcs1SZFryffQf8vK2XrxP6lxC99ELZAdvsDgPklIBfd65R8R+qvOm1SmLaZ/Fdq961+m7A==", + "version": "4.34.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.2.tgz", + "integrity": "sha512-wt8OhpQUi6JuPFkm1wbVi1BByeag87LDFzeKSXzIdGcX4bMLqORTtKxLoCbV57BHYNSUSOKlSL4BYYUghainYA==", "cpu": [ "ia32" ], @@ -2843,9 +2843,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.34.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.0.tgz", - "integrity": "sha512-g2ASy1QwHP88y5KWvblUolJz9rN+i4ZOsYzkEwcNfaNooxNUXG+ON6F5xFo0NIItpHqxcdAyls05VXpBnludGw==", + "version": "4.34.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.2.tgz", + "integrity": "sha512-rUrqINax0TvrPBXrFKg0YbQx18NpPN3NNrgmaao9xRNbTwek7lOXObhx8tQy8gelmQ/gLaGy1WptpU2eKJZImg==", "cpu": [ "x64" ], @@ -3133,9 +3133,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.13.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.0.tgz", - "integrity": "sha512-ClIbNe36lawluuvq3+YYhnIN2CELi+6q8NpnM7PYp4hBn/TatfboPgVSm2rwKRfnV2M+Ty9GWDFI64KEe+kysA==", + "version": "22.13.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.1.tgz", + "integrity": "sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew==", "dev": true, "license": "MIT", "dependencies": { @@ -4448,9 +4448,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001696", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001696.tgz", - "integrity": "sha512-pDCPkvzfa39ehJtJ+OwGT/2yvT2SbjfHhiIW2LWOAcMQ7BzwxT/XuyUp4OTOd0XFWA6BKw0JalnBHgSi5DGJBQ==", + "version": "1.0.30001697", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001697.tgz", + "integrity": "sha512-GwNPlWJin8E+d7Gxq96jxM6w0w+VFeyyXRsjU58emtkYqnbwHqXm5uT2uCmO0RQE9htWknOP4xtBlLmM/gWxvQ==", "dev": true, "funding": [ { @@ -5663,9 +5663,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.90", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.90.tgz", - "integrity": "sha512-C3PN4aydfW91Natdyd449Kw+BzhLmof6tzy5W1pFC5SpQxVXT+oyiyOG9AgYYSN9OdA/ik3YkCrpwqI8ug5Tug==", + "version": "1.5.91", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.91.tgz", + "integrity": "sha512-sNSHHyq048PFmZY4S90ax61q+gLCs0X0YmcOII9wG9S2XwbVr+h4VW2wWhnbp/Eys3cCwTxVF292W3qPaxIapQ==", "dev": true, "license": "ISC" }, @@ -5720,9 +5720,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.18.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.0.tgz", - "integrity": "sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ==", + "version": "5.18.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", + "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", "dev": true, "license": "MIT", "dependencies": { @@ -9987,9 +9987,9 @@ } }, "node_modules/rollup": { - "version": "4.34.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.0.tgz", - "integrity": "sha512-+4C/cgJ9w6sudisA0nZz0+O7lTP9a3CzNLsoDwaRumM8QHwghUsu6tqHXiTmNUp/rqNiM14++7dkzHDyCRs0Jg==", + "version": "4.34.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.2.tgz", + "integrity": "sha512-sBDUoxZEaqLu9QeNalL8v3jw6WjPku4wfZGyTU7l7m1oC+rpRihXc/n/H+4148ZkGz5Xli8CHMns//fFGKvpIQ==", "dev": true, "license": "MIT", "dependencies": { @@ -10003,25 +10003,25 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.34.0", - "@rollup/rollup-android-arm64": "4.34.0", - "@rollup/rollup-darwin-arm64": "4.34.0", - "@rollup/rollup-darwin-x64": "4.34.0", - "@rollup/rollup-freebsd-arm64": "4.34.0", - "@rollup/rollup-freebsd-x64": "4.34.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.34.0", - "@rollup/rollup-linux-arm-musleabihf": "4.34.0", - "@rollup/rollup-linux-arm64-gnu": "4.34.0", - "@rollup/rollup-linux-arm64-musl": "4.34.0", - "@rollup/rollup-linux-loongarch64-gnu": "4.34.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.34.0", - "@rollup/rollup-linux-riscv64-gnu": "4.34.0", - "@rollup/rollup-linux-s390x-gnu": "4.34.0", - "@rollup/rollup-linux-x64-gnu": "4.34.0", - "@rollup/rollup-linux-x64-musl": "4.34.0", - "@rollup/rollup-win32-arm64-msvc": "4.34.0", - "@rollup/rollup-win32-ia32-msvc": "4.34.0", - "@rollup/rollup-win32-x64-msvc": "4.34.0", + "@rollup/rollup-android-arm-eabi": "4.34.2", + "@rollup/rollup-android-arm64": "4.34.2", + "@rollup/rollup-darwin-arm64": "4.34.2", + "@rollup/rollup-darwin-x64": "4.34.2", + "@rollup/rollup-freebsd-arm64": "4.34.2", + "@rollup/rollup-freebsd-x64": "4.34.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.34.2", + "@rollup/rollup-linux-arm-musleabihf": "4.34.2", + "@rollup/rollup-linux-arm64-gnu": "4.34.2", + "@rollup/rollup-linux-arm64-musl": "4.34.2", + "@rollup/rollup-linux-loongarch64-gnu": "4.34.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.34.2", + "@rollup/rollup-linux-riscv64-gnu": "4.34.2", + "@rollup/rollup-linux-s390x-gnu": "4.34.2", + "@rollup/rollup-linux-x64-gnu": "4.34.2", + "@rollup/rollup-linux-x64-musl": "4.34.2", + "@rollup/rollup-win32-arm64-msvc": "4.34.2", + "@rollup/rollup-win32-ia32-msvc": "4.34.2", + "@rollup/rollup-win32-x64-msvc": "4.34.2", "fsevents": "~2.3.2" } }, @@ -10168,9 +10168,9 @@ } }, "node_modules/semver": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.0.tgz", - "integrity": "sha512-DrfFnPzblFmNrIZzg5RzHegbiRWg7KMR7btwi2yjHwx06zsUbO5g613sVwEV7FTwmzJu+Io0lJe2GJ3LxqpvBQ==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", "dev": true, "license": "ISC", "bin": { diff --git a/resources/assets/v1/src/locales/pl.json b/resources/assets/v1/src/locales/pl.json index 5550e23310..de52232336 100644 --- a/resources/assets/v1/src/locales/pl.json +++ b/resources/assets/v1/src/locales/pl.json @@ -171,7 +171,7 @@ "list": { "title": "Tytu\u0142", "active": "Jest aktywny?", - "native_currency": "Native currency", + "native_currency": "Waluta natywna", "trigger": "Wyzwalacz", "response": "Odpowied\u017a", "delivery": "Dor\u0119czenie", diff --git a/resources/assets/v1/src/locales/sl.json b/resources/assets/v1/src/locales/sl.json index e513eaf9a5..f7debcad5b 100644 --- a/resources/assets/v1/src/locales/sl.json +++ b/resources/assets/v1/src/locales/sl.json @@ -138,7 +138,7 @@ "visit_webhook_url": "Obi\u0161\u010dite URL webhooka", "reset_webhook_secret": "Ponastavi skrivno kodo webhooka", "header_exchange_rates": "Menjalni te\u010daji", - "exchange_rates_intro": "Firefly III supports downloading and using exchange rates. Read more about this in the documentation<\/a>.", + "exchange_rates_intro": "Firefly III podpira prenos in uporabo menjalnih te\u010dajev. Preberite ve\u010d o tem v dokumentaciji<\/a>.", "exchange_rates_from_to": "Med {from} in {to} (in obratno)", "exchange_rates_intro_rates": "Firefly III uporablja naslednje menjalne te\u010daje. Obratna vrednost se samodejno izra\u010duna, \u010de ni na voljo. \u010ce na dan transakcije ni menjalnega te\u010daja, se bo Firefly III vrnil v preteklost, da bi ga na\u0161el. \u010ce jih ni, se uporabi te\u010daj \"1\".", "header_exchange_rates_rates": "Menjalni te\u010daji", From ac88007593f6086cb5b0f7e280d4d1c5a9d3fd34 Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 4 Feb 2025 21:26:40 +0100 Subject: [PATCH 09/24] Replace steam call. --- app/Http/Controllers/Chart/AccountController.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/app/Http/Controllers/Chart/AccountController.php b/app/Http/Controllers/Chart/AccountController.php index e220f91807..be3a7c491d 100644 --- a/app/Http/Controllers/Chart/AccountController.php +++ b/app/Http/Controllers/Chart/AccountController.php @@ -35,6 +35,7 @@ use FireflyIII\Models\TransactionCurrency; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface; use FireflyIII\Support\CacheProperties; +use FireflyIII\Support\Facades\Amount; use FireflyIII\Support\Facades\Steam; use FireflyIII\Support\Http\Controllers\AugumentData; use FireflyIII\Support\Http\Controllers\ChartGeneration; @@ -108,8 +109,8 @@ class AccountController extends Controller $accountNames = $this->extractNames($accounts); // grab all balances - $startBalances = app('steam')->finalAccountsBalance($accounts, $start); - $endBalances = app('steam')->finalAccountsBalance($accounts, $end); + $startBalances = Steam::finalAccountsBalance($accounts, $start); + $endBalances = Steam::finalAccountsBalance($accounts, $end); // loop the accounts, then check for balance and currency info. foreach ($accounts as $account) { @@ -432,7 +433,7 @@ class AccountController extends Controller // collect and filter balances for the entire period. $step = $this->calculateStep($start, $end); Log::debug(sprintf('Step is %s', $step)); - $locale = app('steam')->getLocale(); + $locale = Steam::getLocale(); $return = []; // fix for issue https://github.com/firefly-iii/firefly-iii/issues/8041 @@ -570,8 +571,8 @@ class AccountController extends Controller $accountNames = $this->extractNames($accounts); // grab all balances - $startBalances = app('steam')->finalAccountsBalance($accounts, $start); - $endBalances = app('steam')->finalAccountsBalance($accounts, $end); + $startBalances = Steam::finalAccountsBalance($accounts, $start); + $endBalances = Steam::finalAccountsBalance($accounts, $end); // loop the accounts, then check for balance and currency info. From 443036936d7cfed58e0eeb4efb0704fcf58e8c62 Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 4 Feb 2025 21:26:53 +0100 Subject: [PATCH 10/24] Update changelog. --- changelog.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/changelog.md b/changelog.md index db58039faa..9ab3099dbc 100644 --- a/changelog.md +++ b/changelog.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## 6.2.3 + +### Fixed + +- #9713 +- #9736 +- #9745 +- #9747 +- #9751 +- #9762 + ## 6.2.2 - 2025-02-02 > ⚠️ _This release comes with many changes, small and large. I expect you will run into issue, and I appreciate your feedback and your patience as I fix them. I've tested many things, but I'm 100% sure I've missed things. Please open [an issue here](https://github.com/firefly-iii/firefly-iii/issues/new?template=bug.yml) if you run into problems._ From 35a8fa5f02a7265244cfb301c9af91aa4205b73b Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 4 Feb 2025 21:27:24 +0100 Subject: [PATCH 11/24] Fix balance in range. --- app/Support/Steam.php | 95 +++++++++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 39 deletions(-) diff --git a/app/Support/Steam.php b/app/Support/Steam.php index cafabdc33f..9a6317d28d 100644 --- a/app/Support/Steam.php +++ b/app/Support/Steam.php @@ -70,7 +70,7 @@ class Steam $cache->addProperty($start); $cache->addProperty($end); if ($cache->has()) { - return $cache->get(); + // return $cache->get(); } $balances = []; @@ -103,29 +103,24 @@ class Steam ->where('transaction_journals.date', '<=', $end->format('Y-m-d H:i:s')) ->groupBy('transaction_journals.date') ->groupBy('transactions.transaction_currency_id') - ->groupBy('transactions.foreign_currency_id') ->orderBy('transaction_journals.date', 'ASC') ->whereNull('transaction_journals.deleted_at') ->get( [ // @phpstan-ignore-line 'transaction_journals.date', 'transactions.transaction_currency_id', - DB::raw('SUM(transactions.amount) AS modified'), - 'transactions.foreign_currency_id', - DB::raw('SUM(transactions.foreign_amount) AS modified_foreign'), - DB::raw('SUM(transactions.native_amount) AS modified_native'), + DB::raw('SUM(transactions.amount) AS sum_of_day'), ] ); $currentBalance = $startBalance; + $converter = new ExchangeRateConverter(); /** @var Transaction $entry */ foreach ($set as $entry) { // normal, native and foreign amount $carbon = new Carbon($entry->date, $entry->date_tz); - $modified = (string) (null === $entry->modified ? '0' : $entry->modified); - $foreignModified = (string) (null === $entry->modified_foreign ? '0' : $entry->modified_foreign); - $nativeModified = (string) (null === $entry->modified_native ? '0' : $entry->modified_native); + $sumOfDay = (string) (null === $entry->sum_of_day ? '0' : $entry->sum_of_day); // find currency of this entry. $currencies[$entry->transaction_currency_id] ??= TransactionCurrency::find($entry->transaction_currency_id); @@ -134,39 +129,61 @@ class Steam $entryCurrency = $currencies[$entry->transaction_currency_id]; Log::debug(sprintf('Processing transaction(s) on date %s', $carbon->format('Y-m-d H:i:s'))); + $currentBalance[$entryCurrency->code] ??= '0'; + $currentBalance[$entryCurrency->code] = bcadd($sumOfDay, $currentBalance[$entryCurrency->code]); - // if convert to native, if NOT convert to native. - if ($convertToNative) { - Log::debug(sprintf('Amount is %s %s, foreign amount is %s, native amount is %s', $entryCurrency->code, $this->bcround($modified, 2), $this->bcround($foreignModified, 2), $this->bcround($nativeModified, 2))); - // if the currency is the default currency add to native balance + currency balance - if ($entry->transaction_currency_id === $defaultCurrency->id) { - Log::debug('Add amount to native.'); - $currentBalance['native_balance'] = bcadd($currentBalance['native_balance'], $modified); + // if not convert to native, add the amount to "balance" and "native_balance" alike: + if(!$convertToNative) { + $currentBalance['balance'] = bcadd($currentBalance['balance'], $sumOfDay); + $currentBalance['native_balance'] = bcadd($currentBalance['native_balance'], $sumOfDay); + } + // if convert to native add the converted amount to native balance. + if($convertToNative) { + $nativeSumOfDay = $converter->convert($entryCurrency, $defaultCurrency, $carbon, $sumOfDay); + $currentBalance['native_balance'] = bcadd($currentBalance['native_balance'], $nativeSumOfDay); + // only add to "balance" if it has the correct currency code (the same as "native") + if($defaultCurrency->code === $entryCurrency->code) { + $currentBalance['balance'] = bcadd($currentBalance['balance'], $sumOfDay); } + } - // add to native balance. - if ($entry->foreign_currency_id !== $defaultCurrency->id) { - // this check is not necessary, because if the foreign currency is the same as the default currency, the native amount is zero. - // so adding this would mean nothing. - $currentBalance['native_balance'] = bcadd($currentBalance['native_balance'], $nativeModified); - } - if ($entry->foreign_currency_id === $defaultCurrency->id) { - $currentBalance['native_balance'] = bcadd($currentBalance['native_balance'], $foreignModified); - } - // add to balance if is the same. - if ($entry->transaction_currency_id === $accountCurrency?->id) { - $currentBalance['balance'] = bcadd($currentBalance['balance'], $modified); - } - // add currency balance - $currentBalance[$entryCurrency->code] = bcadd($currentBalance[$entryCurrency->code] ?? '0', $modified); - } - if (!$convertToNative) { - Log::debug(sprintf('Amount is %s %s, foreign amount is %s, native amount is %s', $entryCurrency->code, $modified, $foreignModified, $nativeModified)); - // add to balance, as expected. - $currentBalance['balance'] = bcadd($currentBalance['balance'] ?? '0', $modified); - // add to GBP, as expected. - $currentBalance[$entryCurrency->code] = bcadd($currentBalance[$entryCurrency->code] ?? '0', $modified); - } + +// // if convert to native, if NOT convert to native. +// if ($convertToNative) { +// // convert for this day to native +// $currentNative = '0'; // TODO +// //$currentBalance['native_balance'] +// +//// Log::debug(sprintf('Amount is %s %s, foreign amount is %s, native amount is %s', $entryCurrency->code, $this->bcround($modified, 2), $this->bcround($foreignModified, 2), $this->bcround($nativeModified, 2))); +//// // if the currency is the default currency add to native balance + currency balance +//// if ($entry->transaction_currency_id === $defaultCurrency->id) { +//// Log::debug('Add amount to native.'); +//// $currentBalance['native_balance'] = bcadd($currentBalance['native_balance'], $modified); +//// } +//// +//// // add to native balance. +//// if ($entry->foreign_currency_id !== $defaultCurrency->id) { +//// // this check is not necessary, because if the foreign currency is the same as the default currency, the native amount is zero. +//// // so adding this would mean nothing. +//// $currentBalance['native_balance'] = bcadd($currentBalance['native_balance'], $nativeModified); +//// } +//// if ($entry->foreign_currency_id === $defaultCurrency->id) { +//// $currentBalance['native_balance'] = bcadd($currentBalance['native_balance'], $foreignModified); +//// } +//// // add to balance if is the same. +//// if ($entry->transaction_currency_id === $accountCurrency?->id) { +//// $currentBalance['balance'] = bcadd($currentBalance['balance'], $modified); +//// } +//// // add currency balance +//// $currentBalance[$entryCurrency->code] = bcadd($currentBalance[$entryCurrency->code] ?? '0', $modified); +// } +// if (!$convertToNative) { +// Log::debug(sprintf('Amount is %s %s, foreign amount is %s, native amount is %s', $entryCurrency->code, $modified, $foreignModified, $nativeModified)); +// // add to balance, as expected. +// $currentBalance['balance'] = bcadd($currentBalance['balance'] ?? '0', $modified); +// // add to GBP, as expected. +// $currentBalance[$entryCurrency->code] = bcadd($currentBalance[$entryCurrency->code] ?? '0', $modified); +// } $balances[$carbon->format('Y-m-d')] = $currentBalance; Log::debug('Updated entry', $currentBalance); } From 3c8de21709cfc7a1476eeb502b800183616f0293 Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 4 Feb 2025 21:34:46 +0100 Subject: [PATCH 12/24] Fix balance and native balance lists. --- app/Support/Steam.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/Support/Steam.php b/app/Support/Steam.php index d805f8d6a7..aa19ec7b00 100644 --- a/app/Support/Steam.php +++ b/app/Support/Steam.php @@ -329,7 +329,7 @@ class Steam $hasCurrency = null !== $accountCurrency; $currency = $hasCurrency ? $accountCurrency : $native; $return = [ - 'balance' => '0', + //'balance' => '0', 'native_balance' => '0', ]; // balance(s) in other (all) currencies. @@ -343,9 +343,9 @@ class Steam Log::debug('All balances are (joined)', $others); // if there is no request to convert, take this as "balance" and "native_balance". if (!$convertToNative) { - $return['balance'] = $others[$currency->code] ?? '0'; + //$return['balance'] = $others[$currency->code] ?? '0'; $return['native_balance'] = $others[$currency->code] ?? '0'; - Log::debug(sprintf('Set balance + native_balance to %s', $return['balance'])); + Log::debug(sprintf('Set balance + native_balance to %s', $return['native_balance'])); } // if there is a request to convert, convert to "native_balance" and use "balance" for whichever amount is in the native currency. if ($convertToNative) { @@ -356,8 +356,8 @@ class Steam // either way, the balance is always combined with the virtual balance: $virtualBalance = (string) ('' === (string) $account->virtual_balance ? '0' : $account->virtual_balance); - $return['balance'] = bcadd($return['balance'], $virtualBalance); - Log::debug(sprintf('Virtual balance makes the total %s', $return['balance'])); + //$return['balance'] = bcadd($return['balance'], $virtualBalance); + //Log::debug(sprintf('Virtual balance makes the total %s', $return['balance'])); if ($convertToNative) { // the native balance is combined with a converted virtual_balance: @@ -369,7 +369,7 @@ class Steam if (!$convertToNative) { // if not, also increase the native balance for consistency. $return['native_balance'] = bcadd($return['native_balance'], $virtualBalance); - Log::debug(sprintf('Virtual balance makes the (native) total %s', $return['balance'])); + Log::debug(sprintf('Virtual balance makes the (native) total %s', $return['native_balance'])); } // if the currency is the same as the native currency, set the native_balance to the balance for consistency. From f0fa93a8113cd9a24b3e224dfb2514bb3c9c0017 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 4 Feb 2025 21:38:20 +0100 Subject: [PATCH 13/24] Auto commit for release 'develop' on 2025-02-04 --- app/Support/Steam.php | 157 +++++++++++++++++++++--------------------- changelog.md | 12 ++-- 2 files changed, 85 insertions(+), 84 deletions(-) diff --git a/app/Support/Steam.php b/app/Support/Steam.php index aa19ec7b00..22d9f7dd30 100644 --- a/app/Support/Steam.php +++ b/app/Support/Steam.php @@ -97,95 +97,96 @@ class Steam // sums up the balance changes per day, for foreign, native and normal amounts. - $set = $account->transactions() - ->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') - ->where('transaction_journals.date', '>=', $start->format('Y-m-d H:i:s')) - ->where('transaction_journals.date', '<=', $end->format('Y-m-d H:i:s')) - ->groupBy('transaction_journals.date') - ->groupBy('transactions.transaction_currency_id') - ->orderBy('transaction_journals.date', 'ASC') - ->whereNull('transaction_journals.deleted_at') - ->get( - [ // @phpstan-ignore-line - 'transaction_journals.date', - 'transactions.transaction_currency_id', - DB::raw('SUM(transactions.amount) AS sum_of_day'), - ] - ); + $set = $account->transactions() + ->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') + ->where('transaction_journals.date', '>=', $start->format('Y-m-d H:i:s')) + ->where('transaction_journals.date', '<=', $end->format('Y-m-d H:i:s')) + ->groupBy('transaction_journals.date') + ->groupBy('transactions.transaction_currency_id') + ->orderBy('transaction_journals.date', 'ASC') + ->whereNull('transaction_journals.deleted_at') + ->get( + [ // @phpstan-ignore-line + 'transaction_journals.date', + 'transactions.transaction_currency_id', + DB::raw('SUM(transactions.amount) AS sum_of_day'), + ] + ) + ; - $currentBalance = $startBalance; - $converter = new ExchangeRateConverter(); + $currentBalance = $startBalance; + $converter = new ExchangeRateConverter(); /** @var Transaction $entry */ foreach ($set as $entry) { // normal, native and foreign amount - $carbon = new Carbon($entry->date, $entry->date_tz); - $sumOfDay = (string) (null === $entry->sum_of_day ? '0' : $entry->sum_of_day); + $carbon = new Carbon($entry->date, $entry->date_tz); + $sumOfDay = (string) (null === $entry->sum_of_day ? '0' : $entry->sum_of_day); // find currency of this entry. $currencies[$entry->transaction_currency_id] ??= TransactionCurrency::find($entry->transaction_currency_id); /** @var TransactionCurrency $entryCurrency */ - $entryCurrency = $currencies[$entry->transaction_currency_id]; + $entryCurrency = $currencies[$entry->transaction_currency_id]; Log::debug(sprintf('Processing transaction(s) on date %s', $carbon->format('Y-m-d H:i:s'))); - $currentBalance[$entryCurrency->code] ??= '0'; + $currentBalance[$entryCurrency->code] ??= '0'; $currentBalance[$entryCurrency->code] = bcadd($sumOfDay, $currentBalance[$entryCurrency->code]); // if not convert to native, add the amount to "balance" and "native_balance" alike: - if(!$convertToNative) { - $currentBalance['balance'] = bcadd($currentBalance['balance'], $sumOfDay); + if (!$convertToNative) { + $currentBalance['balance'] = bcadd($currentBalance['balance'], $sumOfDay); $currentBalance['native_balance'] = bcadd($currentBalance['native_balance'], $sumOfDay); } // if convert to native add the converted amount to native balance. - if($convertToNative) { - $nativeSumOfDay = $converter->convert($entryCurrency, $defaultCurrency, $carbon, $sumOfDay); + if ($convertToNative) { + $nativeSumOfDay = $converter->convert($entryCurrency, $defaultCurrency, $carbon, $sumOfDay); $currentBalance['native_balance'] = bcadd($currentBalance['native_balance'], $nativeSumOfDay); // only add to "balance" if it has the correct currency code (the same as "native") - if($defaultCurrency->code === $entryCurrency->code) { + if ($defaultCurrency->code === $entryCurrency->code) { $currentBalance['balance'] = bcadd($currentBalance['balance'], $sumOfDay); } } -// // if convert to native, if NOT convert to native. -// if ($convertToNative) { -// // convert for this day to native -// $currentNative = '0'; // TODO -// //$currentBalance['native_balance'] -// -//// Log::debug(sprintf('Amount is %s %s, foreign amount is %s, native amount is %s', $entryCurrency->code, $this->bcround($modified, 2), $this->bcround($foreignModified, 2), $this->bcround($nativeModified, 2))); -//// // if the currency is the default currency add to native balance + currency balance -//// if ($entry->transaction_currency_id === $defaultCurrency->id) { -//// Log::debug('Add amount to native.'); -//// $currentBalance['native_balance'] = bcadd($currentBalance['native_balance'], $modified); -//// } -//// -//// // add to native balance. -//// if ($entry->foreign_currency_id !== $defaultCurrency->id) { -//// // this check is not necessary, because if the foreign currency is the same as the default currency, the native amount is zero. -//// // so adding this would mean nothing. -//// $currentBalance['native_balance'] = bcadd($currentBalance['native_balance'], $nativeModified); -//// } -//// if ($entry->foreign_currency_id === $defaultCurrency->id) { -//// $currentBalance['native_balance'] = bcadd($currentBalance['native_balance'], $foreignModified); -//// } -//// // add to balance if is the same. -//// if ($entry->transaction_currency_id === $accountCurrency?->id) { -//// $currentBalance['balance'] = bcadd($currentBalance['balance'], $modified); -//// } -//// // add currency balance -//// $currentBalance[$entryCurrency->code] = bcadd($currentBalance[$entryCurrency->code] ?? '0', $modified); -// } -// if (!$convertToNative) { -// Log::debug(sprintf('Amount is %s %s, foreign amount is %s, native amount is %s', $entryCurrency->code, $modified, $foreignModified, $nativeModified)); -// // add to balance, as expected. -// $currentBalance['balance'] = bcadd($currentBalance['balance'] ?? '0', $modified); -// // add to GBP, as expected. -// $currentBalance[$entryCurrency->code] = bcadd($currentBalance[$entryCurrency->code] ?? '0', $modified); -// } + // // if convert to native, if NOT convert to native. + // if ($convertToNative) { + // // convert for this day to native + // $currentNative = '0'; // TODO + // //$currentBalance['native_balance'] + // + // // Log::debug(sprintf('Amount is %s %s, foreign amount is %s, native amount is %s', $entryCurrency->code, $this->bcround($modified, 2), $this->bcround($foreignModified, 2), $this->bcround($nativeModified, 2))); + // // // if the currency is the default currency add to native balance + currency balance + // // if ($entry->transaction_currency_id === $defaultCurrency->id) { + // // Log::debug('Add amount to native.'); + // // $currentBalance['native_balance'] = bcadd($currentBalance['native_balance'], $modified); + // // } + // // + // // // add to native balance. + // // if ($entry->foreign_currency_id !== $defaultCurrency->id) { + // // // this check is not necessary, because if the foreign currency is the same as the default currency, the native amount is zero. + // // // so adding this would mean nothing. + // // $currentBalance['native_balance'] = bcadd($currentBalance['native_balance'], $nativeModified); + // // } + // // if ($entry->foreign_currency_id === $defaultCurrency->id) { + // // $currentBalance['native_balance'] = bcadd($currentBalance['native_balance'], $foreignModified); + // // } + // // // add to balance if is the same. + // // if ($entry->transaction_currency_id === $accountCurrency?->id) { + // // $currentBalance['balance'] = bcadd($currentBalance['balance'], $modified); + // // } + // // // add currency balance + // // $currentBalance[$entryCurrency->code] = bcadd($currentBalance[$entryCurrency->code] ?? '0', $modified); + // } + // if (!$convertToNative) { + // Log::debug(sprintf('Amount is %s %s, foreign amount is %s, native amount is %s', $entryCurrency->code, $modified, $foreignModified, $nativeModified)); + // // add to balance, as expected. + // $currentBalance['balance'] = bcadd($currentBalance['balance'] ?? '0', $modified); + // // add to GBP, as expected. + // $currentBalance[$entryCurrency->code] = bcadd($currentBalance[$entryCurrency->code] ?? '0', $modified); + // } - $balances[$carbon->format('Y-m-d')] = $currentBalance; + $balances[$carbon->format('Y-m-d')] = $currentBalance; Log::debug('Updated entry', $currentBalance); } $cache->store($balances); @@ -314,7 +315,7 @@ class Steam */ public function finalAccountBalance(Account $account, Carbon $date): array { - $cache = new CacheProperties(); + $cache = new CacheProperties(); $cache->addProperty($account->id); $cache->addProperty($date); if ($cache->has()) { @@ -323,27 +324,27 @@ class Steam Log::debug(sprintf('Now in finalAccountBalance(#%d, "%s", "%s")', $account->id, $account->name, $date->format('Y-m-d H:i:s'))); - $native = Amount::getNativeCurrencyByUserGroup($account->user->userGroup); - $convertToNative = Amount::convertToNative($account->user); - $accountCurrency = $this->getAccountCurrency($account); - $hasCurrency = null !== $accountCurrency; - $currency = $hasCurrency ? $accountCurrency : $native; - $return = [ - //'balance' => '0', + $native = Amount::getNativeCurrencyByUserGroup($account->user->userGroup); + $convertToNative = Amount::convertToNative($account->user); + $accountCurrency = $this->getAccountCurrency($account); + $hasCurrency = null !== $accountCurrency; + $currency = $hasCurrency ? $accountCurrency : $native; + $return = [ + // 'balance' => '0', 'native_balance' => '0', ]; // balance(s) in other (all) currencies. - $array = $account->transactions() + $array = $account->transactions() ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') ->leftJoin('transaction_currencies', 'transaction_currencies.id', '=', 'transactions.transaction_currency_id') ->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s')) ->get(['transaction_currencies.code', 'transactions.amount'])->toArray() ; - $others = $this->groupAndSumTransactions($array, 'code', 'amount'); + $others = $this->groupAndSumTransactions($array, 'code', 'amount'); Log::debug('All balances are (joined)', $others); // if there is no request to convert, take this as "balance" and "native_balance". if (!$convertToNative) { - //$return['balance'] = $others[$currency->code] ?? '0'; + // $return['balance'] = $others[$currency->code] ?? '0'; $return['native_balance'] = $others[$currency->code] ?? '0'; Log::debug(sprintf('Set balance + native_balance to %s', $return['native_balance'])); } @@ -355,9 +356,9 @@ class Steam } // either way, the balance is always combined with the virtual balance: - $virtualBalance = (string) ('' === (string) $account->virtual_balance ? '0' : $account->virtual_balance); - //$return['balance'] = bcadd($return['balance'], $virtualBalance); - //Log::debug(sprintf('Virtual balance makes the total %s', $return['balance'])); + $virtualBalance = (string) ('' === (string) $account->virtual_balance ? '0' : $account->virtual_balance); + // $return['balance'] = bcadd($return['balance'], $virtualBalance); + // Log::debug(sprintf('Virtual balance makes the total %s', $return['balance'])); if ($convertToNative) { // the native balance is combined with a converted virtual_balance: @@ -384,7 +385,7 @@ class Steam // $return['native_balance'] = $sum; // unset($return['balance']); // } - $final = array_merge($return, $others); + $final = array_merge($return, $others); // // Log::debug('Return is', $final); $cache->store($final); diff --git a/changelog.md b/changelog.md index 9ab3099dbc..0c16470a7d 100644 --- a/changelog.md +++ b/changelog.md @@ -7,12 +7,12 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed -- #9713 -- #9736 -- #9745 -- #9747 -- #9751 -- #9762 +- [Issue 9713](https://github.com/firefly-iii/firefly-iii/issues/9713) (Many decimal points in amounts) reported by @memo-567 +- [Issue 9736](https://github.com/firefly-iii/firefly-iii/issues/9736) (Wrong `finalAccountBalance` result) reported by @gthbusrr +- [Issue 9745](https://github.com/firefly-iii/firefly-iii/issues/9745) (Type mismatch in period overview) reported by @electrofloat +- [Issue 9747](https://github.com/firefly-iii/firefly-iii/issues/9747) (Data entry issues with exchange rates) reported by @Azmodeszer +- [Issue 9751](https://github.com/firefly-iii/firefly-iii/issues/9751) (Net worth changes since 6.2 update) reported by @ahmaddxb +- [Issue 9762](https://github.com/firefly-iii/firefly-iii/issues/9762) (Piggy bank show: start/target date not displayed) reported by @Simeam ## 6.2.2 - 2025-02-02 From 512eddf8be6534945285697a4d439baaae33ba9f Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 5 Feb 2025 05:51:22 +0100 Subject: [PATCH 14/24] Fix #9736 --- app/Http/Controllers/Account/ReconcileController.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Http/Controllers/Account/ReconcileController.php b/app/Http/Controllers/Account/ReconcileController.php index 1ad97d14e4..0b7955a42c 100644 --- a/app/Http/Controllers/Account/ReconcileController.php +++ b/app/Http/Controllers/Account/ReconcileController.php @@ -113,6 +113,7 @@ class ReconcileController extends Controller $end->endOfDay(); $startDate = clone $start; + $startDate->subDay()->endOfDay(); $startBalance = Steam::bcround(Steam::finalAccountBalance($account, $startDate)['balance'], $currency->decimal_places); $endBalance = Steam::bcround(Steam::finalAccountBalance($account, $end)['balance'], $currency->decimal_places); $subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $account->accountType->type)); From 7e4fece63de4ff2c6a809ea5d2d893efd96bc99b Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 5 Feb 2025 05:58:53 +0100 Subject: [PATCH 15/24] add some checks and balances to migrations. --- .../2024_11_30_075826_multi_piggy.php | 76 +++++++++++++------ ..._12_19_061003_add_native_amount_column.php | 8 +- 2 files changed, 57 insertions(+), 27 deletions(-) diff --git a/database/migrations/2024_11_30_075826_multi_piggy.php b/database/migrations/2024_11_30_075826_multi_piggy.php index 99718041eb..7a59159f8b 100644 --- a/database/migrations/2024_11_30_075826_multi_piggy.php +++ b/database/migrations/2024_11_30_075826_multi_piggy.php @@ -46,46 +46,76 @@ return new class () extends Migration { } Schema::table('piggy_banks', static function (Blueprint $table): void { // 2. make column nullable. - $table->unsignedInteger('account_id')->nullable()->change(); + if (!Schema::hasColumn('piggy_banks', 'account_id')) { + $table->unsignedInteger('account_id')->nullable()->change(); + } }); Schema::table('piggy_banks', static function (Blueprint $table): void { // 3. add currency - $table->integer('transaction_currency_id', false, true)->after('account_id')->nullable(); - $table->foreign('transaction_currency_id', 'unique_currency')->references('id')->on('transaction_currencies')->onDelete('cascade'); + if (!Schema::hasColumn('piggy_banks', 'transaction_currency_id')) { + $table->integer('transaction_currency_id', false, true)->after('account_id')->nullable(); + } + if (!self::hasForeign('piggy_banks', 'unique_currency')) { + $table->foreign('transaction_currency_id', 'unique_currency')->references('id')->on('transaction_currencies')->onDelete('cascade'); + } }); Schema::table('piggy_banks', static function (Blueprint $table): void { // 4. rename columns - $table->renameColumn('targetamount', 'target_amount'); - $table->renameColumn('startdate', 'start_date'); - $table->renameColumn('targetdate', 'target_date'); - $table->renameColumn('startdate_tz', 'start_date_tz'); - $table->renameColumn('targetdate_tz', 'target_date_tz'); + if (Schema::hasColumn('piggy_banks', 'targetamount') && !Schema::hasColumn('piggy_banks', 'target_amount')) { + $table->renameColumn('targetamount', 'target_amount'); + } + if (Schema::hasColumn('piggy_banks', 'startdate') && !Schema::hasColumn('piggy_banks', 'start_date')) { + $table->renameColumn('startdate', 'start_date'); + } + if (Schema::hasColumn('piggy_banks', 'targetdate') && !Schema::hasColumn('piggy_banks', 'target_date')) { + $table->renameColumn('targetdate', 'target_date'); + } + if (Schema::hasColumn('piggy_banks', 'targetdate') && !Schema::hasColumn('startdate_tz', 'start_date_tz')) { + $table->renameColumn('startdate_tz', 'start_date_tz'); + } + if (Schema::hasColumn('piggy_banks', 'targetdate_tz') && !Schema::hasColumn('target_date_tz', 'start_date_tz')) { + $table->renameColumn('targetdate_tz', 'target_date_tz'); + } }); Schema::table('piggy_banks', static function (Blueprint $table): void { // 5. add new index - $table->foreign('account_id')->references('id')->on('accounts')->onDelete('set null'); + if (!self::hasForeign('piggy_banks', 'piggy_banks_account_id_foreign')) { + $table->foreign('account_id')->references('id')->on('accounts')->onDelete('set null'); + } }); // rename some fields in piggy bank reps. Schema::table('piggy_bank_repetitions', static function (Blueprint $table): void { // 6. rename columns - $table->renameColumn('currentamount', 'current_amount'); - $table->renameColumn('startdate', 'start_date'); - $table->renameColumn('targetdate', 'target_date'); - $table->renameColumn('startdate_tz', 'start_date_tz'); - $table->renameColumn('targetdate_tz', 'target_date_tz'); + if (Schema::hasColumn('piggy_bank_repetitions', 'currentamount') && !Schema::hasColumn('piggy_bank_repetitions', 'current_amount')) { + $table->renameColumn('currentamount', 'current_amount'); + } + if (Schema::hasColumn('piggy_bank_repetitions', 'startdate') && !Schema::hasColumn('piggy_bank_repetitions', 'start_date')) { + $table->renameColumn('startdate', 'start_date'); + } + if (Schema::hasColumn('piggy_bank_repetitions', 'targetdate') && !Schema::hasColumn('piggy_bank_repetitions', 'target_date')) { + $table->renameColumn('targetdate', 'target_date'); + } + if (Schema::hasColumn('piggy_bank_repetitions', 'startdate_tz') && !Schema::hasColumn('piggy_bank_repetitions', 'start_date_tz')) { + $table->renameColumn('startdate_tz', 'start_date_tz'); + } + if (Schema::hasColumn('piggy_bank_repetitions', 'targetdate_tz') && !Schema::hasColumn('piggy_bank_repetitions', 'target_date_tz')) { + $table->renameColumn('targetdate_tz', 'target_date_tz'); + } }); // create table account_piggy_bank - Schema::create('account_piggy_bank', static function (Blueprint $table): void { - $table->id(); - $table->integer('account_id', false, true); - $table->integer('piggy_bank_id', false, true); - $table->decimal('current_amount', 32, 12)->default('0'); - $table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade'); - $table->foreign('piggy_bank_id')->references('id')->on('piggy_banks')->onDelete('cascade'); - $table->unique(['account_id', 'piggy_bank_id'], 'unique_piggy_save'); - }); + if (!Schema::hasTable('account_piggy_bank')) { + Schema::create('account_piggy_bank', static function (Blueprint $table): void { + $table->id(); + $table->integer('account_id', false, true); + $table->integer('piggy_bank_id', false, true); + $table->decimal('current_amount', 32, 12)->default('0'); + $table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade'); + $table->foreign('piggy_bank_id')->references('id')->on('piggy_banks')->onDelete('cascade'); + $table->unique(['account_id', 'piggy_bank_id'], 'unique_piggy_save'); + }); + } } diff --git a/database/migrations/2024_12_19_061003_add_native_amount_column.php b/database/migrations/2024_12_19_061003_add_native_amount_column.php index 2bbd8e4c97..87877bc503 100644 --- a/database/migrations/2024_12_19_061003_add_native_amount_column.php +++ b/database/migrations/2024_12_19_061003_add_native_amount_column.php @@ -41,8 +41,6 @@ return new class () extends Migration { 'piggy_banks' => ['native_target_amount'], // works 'transactions' => ['native_amount', 'native_foreign_amount'], // works - // TODO button to recalculate all native amounts on selected pages? - ]; /** @@ -52,9 +50,11 @@ return new class () extends Migration { { foreach ($this->tables as $table => $fields) { foreach ($fields as $field) { - Schema::table($table, static function (Blueprint $table) use ($field): void { + Schema::table($table, static function (Blueprint $tableObject) use ($table, $field): void { // add amount column - $table->decimal($field, 32, 12)->nullable(); + if(!Schema::hasColumn($table, $field)) { + $tableObject->decimal($field, 32, 12)->nullable(); + } }); } } From 6499b5eaab269a456832281f1dcd17fd4921d5e2 Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 5 Feb 2025 06:03:57 +0100 Subject: [PATCH 16/24] Rename variable for consistency. --- app/Support/Steam.php | 174 +++++++++++++++++------------------------- 1 file changed, 70 insertions(+), 104 deletions(-) diff --git a/app/Support/Steam.php b/app/Support/Steam.php index 22d9f7dd30..166b44feec 100644 --- a/app/Support/Steam.php +++ b/app/Support/Steam.php @@ -41,8 +41,8 @@ class Steam { public function getAccountCurrency(Account $account): ?TransactionCurrency { - $type = $account->accountType->type; - $list = config('firefly.valid_currency_account_types'); + $type = $account->accountType->type; + $list = config('firefly.valid_currency_account_types'); // return null if not in this list. if (!in_array($type, $list, true)) { @@ -64,74 +64,73 @@ class Steam Log::debug(sprintf('finalAccountBalanceInRange(#%d, %s, %s)', $account->id, $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s'))); // set up cache - $cache = new CacheProperties(); + $cache = new CacheProperties(); $cache->addProperty($account->id); $cache->addProperty('final-balance-in-range'); $cache->addProperty($start); $cache->addProperty($end); if ($cache->has()) { - // return $cache->get(); + return $cache->get(); } - $balances = []; - $formatted = $start->format('Y-m-d'); - $startBalance = $this->finalAccountBalance($account, $start); - $defaultCurrency = app('amount')->getNativeCurrencyByUserGroup($account->user->userGroup); - $accountCurrency = $this->getAccountCurrency($account); - $hasCurrency = null !== $accountCurrency; - $currency = $accountCurrency ?? $defaultCurrency; + $balances = []; + $formatted = $start->format('Y-m-d'); + $startBalance = $this->finalAccountBalance($account, $start); + $nativeCurrency = app('amount')->getNativeCurrencyByUserGroup($account->user->userGroup); + $accountCurrency = $this->getAccountCurrency($account); + $hasCurrency = null !== $accountCurrency; + $currency = $accountCurrency ?? $nativeCurrency; Log::debug(sprintf('Currency is %s', $currency->code)); if (!$hasCurrency) { - Log::debug(sprintf('Also set start balance in %s', $defaultCurrency->code)); - $startBalance[$defaultCurrency->code] ??= '0'; + Log::debug(sprintf('Also set start balance in %s', $nativeCurrency->code)); + $startBalance[$nativeCurrency->code] ??= '0'; } - $currencies = [ + $currencies = [ $currency->id => $currency, - $defaultCurrency->id => $defaultCurrency, + $nativeCurrency->id => $nativeCurrency, ]; $startBalance[$currency->code] ??= '0'; - $balances[$formatted] = $startBalance; + $balances[$formatted] = $startBalance; Log::debug('Final start balance: ', $startBalance); // sums up the balance changes per day, for foreign, native and normal amounts. - $set = $account->transactions() - ->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') - ->where('transaction_journals.date', '>=', $start->format('Y-m-d H:i:s')) - ->where('transaction_journals.date', '<=', $end->format('Y-m-d H:i:s')) - ->groupBy('transaction_journals.date') - ->groupBy('transactions.transaction_currency_id') - ->orderBy('transaction_journals.date', 'ASC') - ->whereNull('transaction_journals.deleted_at') - ->get( - [ // @phpstan-ignore-line - 'transaction_journals.date', - 'transactions.transaction_currency_id', - DB::raw('SUM(transactions.amount) AS sum_of_day'), - ] - ) - ; + $set = $account->transactions() + ->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') + ->where('transaction_journals.date', '>=', $start->format('Y-m-d H:i:s')) + ->where('transaction_journals.date', '<=', $end->format('Y-m-d H:i:s')) + ->groupBy('transaction_journals.date') + ->groupBy('transactions.transaction_currency_id') + ->orderBy('transaction_journals.date', 'ASC') + ->whereNull('transaction_journals.deleted_at') + ->get( + [ // @phpstan-ignore-line + 'transaction_journals.date', + 'transactions.transaction_currency_id', + DB::raw('SUM(transactions.amount) AS sum_of_day'), + ] + ); - $currentBalance = $startBalance; - $converter = new ExchangeRateConverter(); + $currentBalance = $startBalance; + $converter = new ExchangeRateConverter(); /** @var Transaction $entry */ foreach ($set as $entry) { // normal, native and foreign amount - $carbon = new Carbon($entry->date, $entry->date_tz); - $sumOfDay = (string) (null === $entry->sum_of_day ? '0' : $entry->sum_of_day); + $carbon = new Carbon($entry->date, $entry->date_tz); + $sumOfDay = (string) (null === $entry->sum_of_day ? '0' : $entry->sum_of_day); // find currency of this entry. $currencies[$entry->transaction_currency_id] ??= TransactionCurrency::find($entry->transaction_currency_id); /** @var TransactionCurrency $entryCurrency */ - $entryCurrency = $currencies[$entry->transaction_currency_id]; + $entryCurrency = $currencies[$entry->transaction_currency_id]; Log::debug(sprintf('Processing transaction(s) on date %s', $carbon->format('Y-m-d H:i:s'))); - $currentBalance[$entryCurrency->code] ??= '0'; + $currentBalance[$entryCurrency->code] ??= '0'; $currentBalance[$entryCurrency->code] = bcadd($sumOfDay, $currentBalance[$entryCurrency->code]); // if not convert to native, add the amount to "balance" and "native_balance" alike: @@ -141,10 +140,10 @@ class Steam } // if convert to native add the converted amount to native balance. if ($convertToNative) { - $nativeSumOfDay = $converter->convert($entryCurrency, $defaultCurrency, $carbon, $sumOfDay); + $nativeSumOfDay = $converter->convert($entryCurrency, $nativeCurrency, $carbon, $sumOfDay); $currentBalance['native_balance'] = bcadd($currentBalance['native_balance'], $nativeSumOfDay); // only add to "balance" if it has the correct currency code (the same as "native") - if ($defaultCurrency->code === $entryCurrency->code) { + if ($nativeCurrency->code === $entryCurrency->code) { $currentBalance['balance'] = bcadd($currentBalance['balance'], $sumOfDay); } } @@ -186,7 +185,7 @@ class Steam // $currentBalance[$entryCurrency->code] = bcadd($currentBalance[$entryCurrency->code] ?? '0', $modified); // } - $balances[$carbon->format('Y-m-d')] = $currentBalance; + $balances[$carbon->format('Y-m-d')] = $currentBalance; Log::debug('Updated entry', $currentBalance); } $cache->store($balances); @@ -224,10 +223,10 @@ class Steam // Log::debug(sprintf('Trying bcround("%s",%d)', $number, $precision)); if (str_contains($number, '.')) { if ('-' !== $number[0]) { - return bcadd($number, '0.'.str_repeat('0', $precision).'5', $precision); + return bcadd($number, '0.' . str_repeat('0', $precision) . '5', $precision); } - return bcsub($number, '0.'.str_repeat('0', $precision).'5', $precision); + return bcsub($number, '0.' . str_repeat('0', $precision) . '5', $precision); } return $number; @@ -294,28 +293,18 @@ class Steam /** * Returns the balance of an account at exact moment given. Array with at least one value. + * Always returns: + * "native_balance": balance in the user's native balance. + * "EUR": balance in EUR (or whatever currencies the account has balance in) * - * "balance" the balance in whatever currency the account has, so the sum of all transaction that happen to have - * THAT currency. - * "native_balance" the balance according to the "native_amount" + "native_foreign_amount" fields. - * "ABC" the balance in this particular currency code (may repeat for each found currency). + * If the user has $convertToNative: + * "native_balance": balance in the user's native balance, with all amounts converted to native. + * "EUR": balance in EUR (or whatever currencies the account has balance in) * - * Het maakt niet uit of de native currency wel of niet gelijk is aan de account currency. - * Optelsom zou hetzelfde moeten zijn. Als het EUR is en de rekening ook is native_amount 0. - * Zo niet is amount 0 en native_amount het bedrag. - * - * Eerst een som van alle transacties in de native currency. Alle EUR bij elkaar opgeteld. - * Om te weten wat er nog meer op de rekening gebeurt, pak alles waar currency niet EUR is, en de foreign ook niet, - * en tel native_amount erbij op. - * Daarna pak je alle transacties waar currency niet EUR is, en de foreign wel, en tel foreign_amount erbij op. - * - * Wil je niks weten van native currencies, pak je: - * - * Eerst een som van alle transacties gegroepeerd op currency. Einde. */ public function finalAccountBalance(Account $account, Carbon $date): array { - $cache = new CacheProperties(); + $cache = new CacheProperties(); $cache->addProperty($account->id); $cache->addProperty($date); if ($cache->has()) { @@ -330,17 +319,15 @@ class Steam $hasCurrency = null !== $accountCurrency; $currency = $hasCurrency ? $accountCurrency : $native; $return = [ - // 'balance' => '0', 'native_balance' => '0', ]; - // balance(s) in other (all) currencies. - $array = $account->transactions() - ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->leftJoin('transaction_currencies', 'transaction_currencies.id', '=', 'transactions.transaction_currency_id') - ->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s')) - ->get(['transaction_currencies.code', 'transactions.amount'])->toArray() - ; - $others = $this->groupAndSumTransactions($array, 'code', 'amount'); + // balance(s) in all currencies. + $array = $account->transactions() + ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') + ->leftJoin('transaction_currencies', 'transaction_currencies.id', '=', 'transactions.transaction_currency_id') + ->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s')) + ->get(['transaction_currencies.code', 'transactions.amount'])->toArray(); + $others = $this->groupAndSumTransactions($array, 'code', 'amount'); Log::debug('All balances are (joined)', $others); // if there is no request to convert, take this as "balance" and "native_balance". if (!$convertToNative) { @@ -350,15 +337,12 @@ class Steam } // if there is a request to convert, convert to "native_balance" and use "balance" for whichever amount is in the native currency. if ($convertToNative) { - $return['balance'] = $others[$native->code] ?? '0'; $return['native_balance'] = $this->convertAllBalances($others, $native, $date); // todo sum all and convert. - Log::debug(sprintf('Set balance to %s and native_balance to %s', $return['balance'], $return['native_balance'])); + Log::debug(sprintf('Set native_balance to %s', $return['native_balance'])); } // either way, the balance is always combined with the virtual balance: - $virtualBalance = (string) ('' === (string) $account->virtual_balance ? '0' : $account->virtual_balance); - // $return['balance'] = bcadd($return['balance'], $virtualBalance); - // Log::debug(sprintf('Virtual balance makes the total %s', $return['balance'])); + $virtualBalance = (string) ('' === (string) $account->virtual_balance ? '0' : $account->virtual_balance); if ($convertToNative) { // the native balance is combined with a converted virtual_balance: @@ -372,28 +356,10 @@ class Steam $return['native_balance'] = bcadd($return['native_balance'], $virtualBalance); Log::debug(sprintf('Virtual balance makes the (native) total %s', $return['native_balance'])); } - - // if the currency is the same as the native currency, set the native_balance to the balance for consistency. - // if($currency->id === $native->id) { - // $return['native_balance'] = $return['balance']; - // } - - // if (!$hasCurrency && array_key_exists('balance', $return)) { - // // Log::debug('Account has no currency preference, dropping balance in favor of native balance.'); - // $sum = bcadd($return['balance'], $return['native_balance']); - // // Log::debug(sprintf('%s + %s = %s', $return['balance'], $return['native_balance'], $sum)); - // $return['native_balance'] = $sum; - // unset($return['balance']); - // } - $final = array_merge($return, $others); - // // Log::debug('Return is', $final); - + $final = array_merge($return, $others); $cache->store($final); return $final; - - // return array_merge($return, $others); - // Log::debug('Return is', $final); } public function filterAccountBalances(array $total, Account $account, bool $convertToNative, ?TransactionCurrency $currency = null): array @@ -496,15 +462,15 @@ class Steam { $list = []; - $set = auth()->user()->transactions() - ->whereIn('transactions.account_id', $accounts) - ->groupBy(['transactions.account_id', 'transaction_journals.user_id']) - ->get(['transactions.account_id', \DB::raw('MAX(transaction_journals.date) AS max_date')]) // @phpstan-ignore-line + $set = auth()->user()->transactions() + ->whereIn('transactions.account_id', $accounts) + ->groupBy(['transactions.account_id', 'transaction_journals.user_id']) + ->get(['transactions.account_id', \DB::raw('MAX(transaction_journals.date) AS max_date')]) // @phpstan-ignore-line ; /** @var Transaction $entry */ foreach ($set as $entry) { - $date = new Carbon($entry->max_date, config('app.timezone')); + $date = new Carbon($entry->max_date, config('app.timezone')); $date->setTimezone(config('app.timezone')); $list[(int) $entry->account_id] = $date; } @@ -579,9 +545,9 @@ class Steam public function getSafeUrl(string $unknownUrl, string $safeUrl): string { // Log::debug(sprintf('getSafeUrl(%s, %s)', $unknownUrl, $safeUrl)); - $returnUrl = $safeUrl; - $unknownHost = parse_url($unknownUrl, PHP_URL_HOST); - $safeHost = parse_url($safeUrl, PHP_URL_HOST); + $returnUrl = $safeUrl; + $unknownHost = parse_url($unknownUrl, PHP_URL_HOST); + $safeHost = parse_url($safeUrl, PHP_URL_HOST); if (null !== $unknownHost && $unknownHost === $safeHost) { $returnUrl = $unknownUrl; @@ -618,7 +584,7 @@ class Steam */ public function floatalize(string $value): string { - $value = strtoupper($value); + $value = strtoupper($value); if (!str_contains($value, 'E')) { return $value; } @@ -706,9 +672,9 @@ class Steam if (null === $currency) { continue; } - $current = $converter->convert($currency, $native, $date, $amount); + $current = $converter->convert($currency, $native, $date, $amount); Log::debug(sprintf('Convert %s %s to %s %s', $currency->code, $amount, $native->code, $current)); - $total = bcadd($current, $total); + $total = bcadd($current, $total); } return $total; From f85878b843bd36d0cf03b653bc2432243243c387 Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 5 Feb 2025 06:29:07 +0100 Subject: [PATCH 17/24] Final tweaks in account balance logic. --- .../Controllers/Chart/AccountController.php | 2 +- .../Http/Controllers/ChartGeneration.php | 2 +- app/Support/Steam.php | 122 +++++++----------- 3 files changed, 46 insertions(+), 80 deletions(-) diff --git a/app/Http/Controllers/Chart/AccountController.php b/app/Http/Controllers/Chart/AccountController.php index be3a7c491d..cf086f6ec2 100644 --- a/app/Http/Controllers/Chart/AccountController.php +++ b/app/Http/Controllers/Chart/AccountController.php @@ -427,7 +427,7 @@ class AccountController extends Controller $cache->addProperty($this->convertToNative); $cache->addProperty($account->id); if ($cache->has()) { - // return response()->json($cache->get()); + return response()->json($cache->get()); } // collect and filter balances for the entire period. diff --git a/app/Support/Http/Controllers/ChartGeneration.php b/app/Support/Http/Controllers/ChartGeneration.php index 93c2a238eb..bc95cd50a7 100644 --- a/app/Support/Http/Controllers/ChartGeneration.php +++ b/app/Support/Http/Controllers/ChartGeneration.php @@ -55,7 +55,7 @@ trait ChartGeneration $cache->addProperty($accounts); $cache->addProperty($convertToNative); if ($cache->has()) { - return $cache->get(); + return $cache->get(); } app('log')->debug('Regenerate chart.account.account-balance-chart from scratch.'); $locale = app('steam')->getLocale(); diff --git a/app/Support/Steam.php b/app/Support/Steam.php index 166b44feec..0b8ec55c10 100644 --- a/app/Support/Steam.php +++ b/app/Support/Steam.php @@ -70,33 +70,36 @@ class Steam $cache->addProperty($start); $cache->addProperty($end); if ($cache->has()) { - return $cache->get(); + return $cache->get(); } $balances = []; $formatted = $start->format('Y-m-d'); $startBalance = $this->finalAccountBalance($account, $start); - $nativeCurrency = app('amount')->getNativeCurrencyByUserGroup($account->user->userGroup); + $nativeCurrency = app('amount')->getNativeCurrencyByUserGroup($account->user->userGroup); $accountCurrency = $this->getAccountCurrency($account); $hasCurrency = null !== $accountCurrency; $currency = $accountCurrency ?? $nativeCurrency; Log::debug(sprintf('Currency is %s', $currency->code)); + + // set start balances: + $startBalance[$currency->code] ??= '0'; + if ($hasCurrency) { + $startBalance[$accountCurrency->code] ??= '0'; + } if (!$hasCurrency) { Log::debug(sprintf('Also set start balance in %s', $nativeCurrency->code)); $startBalance[$nativeCurrency->code] ??= '0'; } $currencies = [ - $currency->id => $currency, + $currency->id => $currency, $nativeCurrency->id => $nativeCurrency, ]; - - $startBalance[$currency->code] ??= '0'; - $balances[$formatted] = $startBalance; + $balances[$formatted] = $startBalance; Log::debug('Final start balance: ', $startBalance); - - // sums up the balance changes per day, for foreign, native and normal amounts. + // sums up the balance changes per day. $set = $account->transactions() ->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') ->where('transaction_journals.date', '>=', $start->format('Y-m-d H:i:s')) @@ -119,13 +122,15 @@ class Steam /** @var Transaction $entry */ foreach ($set as $entry) { - // normal, native and foreign amount - $carbon = new Carbon($entry->date, $entry->date_tz); + // get date object + $carbon = new Carbon($entry->date, $entry->date_tz); + // make sure sum is a string: $sumOfDay = (string) (null === $entry->sum_of_day ? '0' : $entry->sum_of_day); - // find currency of this entry. + // find currency of this entry, does not have to exist. $currencies[$entry->transaction_currency_id] ??= TransactionCurrency::find($entry->transaction_currency_id); + // make sure this $entry has its own $entryCurrency /** @var TransactionCurrency $entryCurrency */ $entryCurrency = $currencies[$entry->transaction_currency_id]; @@ -133,58 +138,16 @@ class Steam $currentBalance[$entryCurrency->code] ??= '0'; $currentBalance[$entryCurrency->code] = bcadd($sumOfDay, $currentBalance[$entryCurrency->code]); - // if not convert to native, add the amount to "balance" and "native_balance" alike: + // if not convert to native, add the amount to "balance", do nothing else. if (!$convertToNative) { - $currentBalance['balance'] = bcadd($currentBalance['balance'], $sumOfDay); - $currentBalance['native_balance'] = bcadd($currentBalance['native_balance'], $sumOfDay); + $currentBalance['balance'] = bcadd($currentBalance['balance'], $sumOfDay); } - // if convert to native add the converted amount to native balance. + // if convert to native add the converted amount to "native_balance". if ($convertToNative) { $nativeSumOfDay = $converter->convert($entryCurrency, $nativeCurrency, $carbon, $sumOfDay); $currentBalance['native_balance'] = bcadd($currentBalance['native_balance'], $nativeSumOfDay); - // only add to "balance" if it has the correct currency code (the same as "native") - if ($nativeCurrency->code === $entryCurrency->code) { - $currentBalance['balance'] = bcadd($currentBalance['balance'], $sumOfDay); - } } - - // // if convert to native, if NOT convert to native. - // if ($convertToNative) { - // // convert for this day to native - // $currentNative = '0'; // TODO - // //$currentBalance['native_balance'] - // - // // Log::debug(sprintf('Amount is %s %s, foreign amount is %s, native amount is %s', $entryCurrency->code, $this->bcround($modified, 2), $this->bcround($foreignModified, 2), $this->bcround($nativeModified, 2))); - // // // if the currency is the default currency add to native balance + currency balance - // // if ($entry->transaction_currency_id === $defaultCurrency->id) { - // // Log::debug('Add amount to native.'); - // // $currentBalance['native_balance'] = bcadd($currentBalance['native_balance'], $modified); - // // } - // // - // // // add to native balance. - // // if ($entry->foreign_currency_id !== $defaultCurrency->id) { - // // // this check is not necessary, because if the foreign currency is the same as the default currency, the native amount is zero. - // // // so adding this would mean nothing. - // // $currentBalance['native_balance'] = bcadd($currentBalance['native_balance'], $nativeModified); - // // } - // // if ($entry->foreign_currency_id === $defaultCurrency->id) { - // // $currentBalance['native_balance'] = bcadd($currentBalance['native_balance'], $foreignModified); - // // } - // // // add to balance if is the same. - // // if ($entry->transaction_currency_id === $accountCurrency?->id) { - // // $currentBalance['balance'] = bcadd($currentBalance['balance'], $modified); - // // } - // // // add currency balance - // // $currentBalance[$entryCurrency->code] = bcadd($currentBalance[$entryCurrency->code] ?? '0', $modified); - // } - // if (!$convertToNative) { - // Log::debug(sprintf('Amount is %s %s, foreign amount is %s, native amount is %s', $entryCurrency->code, $modified, $foreignModified, $nativeModified)); - // // add to balance, as expected. - // $currentBalance['balance'] = bcadd($currentBalance['balance'] ?? '0', $modified); - // // add to GBP, as expected. - // $currentBalance[$entryCurrency->code] = bcadd($currentBalance[$entryCurrency->code] ?? '0', $modified); - // } - + // add final $currentBalance array to the big one. $balances[$carbon->format('Y-m-d')] = $currentBalance; Log::debug('Updated entry', $currentBalance); } @@ -294,11 +257,12 @@ class Steam /** * Returns the balance of an account at exact moment given. Array with at least one value. * Always returns: - * "native_balance": balance in the user's native balance. + * "balance": balance in the account's currency OR user's native currency if the account has no currency * "EUR": balance in EUR (or whatever currencies the account has balance in) * * If the user has $convertToNative: - * "native_balance": balance in the user's native balance, with all amounts converted to native. + * "balance": balance in the account's currency OR user's native currency if the account has no currency + * --> "native_balance": balance in the user's native balance, with all amounts converted to native. * "EUR": balance in EUR (or whatever currencies the account has balance in) * */ @@ -308,7 +272,7 @@ class Steam $cache->addProperty($account->id); $cache->addProperty($date); if ($cache->has()) { - // return $cache->get(); + return $cache->get(); } Log::debug(sprintf('Now in finalAccountBalance(#%d, "%s", "%s")', $account->id, $account->name, $date->format('Y-m-d H:i:s'))); @@ -320,6 +284,7 @@ class Steam $currency = $hasCurrency ? $accountCurrency : $native; $return = [ 'native_balance' => '0', + 'balance' => '0', // this key is overwritten right away, but I must remember it is always created. ]; // balance(s) in all currencies. $array = $account->transactions() @@ -328,17 +293,17 @@ class Steam ->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s')) ->get(['transaction_currencies.code', 'transactions.amount'])->toArray(); $others = $this->groupAndSumTransactions($array, 'code', 'amount'); - Log::debug('All balances are (joined)', $others); + //Log::debug('All balances are (joined)', $others); // if there is no request to convert, take this as "balance" and "native_balance". + $return['balance'] = $others[$currency->code] ?? '0'; if (!$convertToNative) { - // $return['balance'] = $others[$currency->code] ?? '0'; - $return['native_balance'] = $others[$currency->code] ?? '0'; - Log::debug(sprintf('Set balance + native_balance to %s', $return['native_balance'])); + unset($return['native_balance']); + //Log::debug(sprintf('Set balance to %s, unset native_balance', $return['balance'])); } // if there is a request to convert, convert to "native_balance" and use "balance" for whichever amount is in the native currency. if ($convertToNative) { $return['native_balance'] = $this->convertAllBalances($others, $native, $date); // todo sum all and convert. - Log::debug(sprintf('Set native_balance to %s', $return['native_balance'])); + //Log::debug(sprintf('Set native_balance to %s', $return['native_balance'])); } // either way, the balance is always combined with the virtual balance: @@ -349,14 +314,15 @@ class Steam $converter = new ExchangeRateConverter(); $nativeVirtualBalance = $converter->convert($currency, $native, $date, $virtualBalance); $return['native_balance'] = bcadd($nativeVirtualBalance, $return['native_balance']); - Log::debug(sprintf('Native virtual balance makes the native total %s', $return['native_balance'])); + //Log::debug(sprintf('Native virtual balance makes the native total %s', $return['native_balance'])); } if (!$convertToNative) { - // if not, also increase the native balance for consistency. - $return['native_balance'] = bcadd($return['native_balance'], $virtualBalance); - Log::debug(sprintf('Virtual balance makes the (native) total %s', $return['native_balance'])); + // if not, also increase the balance + native balance for consistency. + $return['balance'] = bcadd($return['balance'], $virtualBalance); + //Log::debug(sprintf('Virtual balance makes the (native) total %s', $return['balance'])); } $final = array_merge($return, $others); + Log::debug('Final balance is', $final); $cache->store($final); return $final; @@ -385,34 +351,34 @@ class Steam $defaultCurrency = app('amount')->getNativeCurrency(); if ($convertToNative) { if ($defaultCurrency->id === $currency?->id) { - // Log::debug(sprintf('Unset "native_balance" and "%s" for account #%d', $defaultCurrency->code, $account->id)); + Log::debug(sprintf('Unset "native_balance" and [%s] for account #%d', $defaultCurrency->code, $account->id)); unset($set['native_balance'], $set[$defaultCurrency->code]); } + // todo rethink this logic. if (null !== $currency && $defaultCurrency->id !== $currency->id) { - // Log::debug(sprintf('Unset balance for account #%d', $account->id)); + Log::debug(sprintf('Unset balance for account #%d', $account->id)); unset($set['balance']); } if (null === $currency) { - Log::debug(sprintf('TEMP DO NOT Drop defaultCurrency balance for account #%d', $account->id)); - // unset($set[$this->defaultCurrency->code]); + Log::debug(sprintf('Unset balance for account #%d', $account->id)); + unset($set['balance']); } } if (!$convertToNative) { if (null === $currency) { - // Log::debug(sprintf('Unset native_balance and make defaultCurrency balance the balance for account #%d', $account->id)); + Log::debug(sprintf('Unset native_balance and make defaultCurrency balance the balance for account #%d', $account->id)); $set['balance'] = $set[$defaultCurrency->code] ?? '0'; - unset($set['native_balance'], $set[$defaultCurrency->code]); + unset($set[$defaultCurrency->code]); } if (null !== $currency) { - // Log::debug(sprintf('Unset native_balance + defaultCurrency + currencyCode balance for account #%d', $account->id)); - unset($set['native_balance'], $set[$defaultCurrency->code], $set[$currency->code]); + Log::debug(sprintf('Unset [%s] + [%s] balance for account #%d', $defaultCurrency->code, $currency->code, $account->id)); + unset($set[$defaultCurrency->code], $set[$currency->code]); } } - // put specific value first in array. if (array_key_exists('native_balance', $set)) { $set = ['native_balance' => $set['native_balance']] + $set; From eca12f661f386e358b66f263ca92a0b31fea4786 Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 5 Feb 2025 06:31:15 +0100 Subject: [PATCH 18/24] Fix #9327 --- changelog.md | 2 ++ resources/lang/en_US/firefly.php | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index 0c16470a7d..015ea01b31 100644 --- a/changelog.md +++ b/changelog.md @@ -7,12 +7,14 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed +- #9327 - [Issue 9713](https://github.com/firefly-iii/firefly-iii/issues/9713) (Many decimal points in amounts) reported by @memo-567 - [Issue 9736](https://github.com/firefly-iii/firefly-iii/issues/9736) (Wrong `finalAccountBalance` result) reported by @gthbusrr - [Issue 9745](https://github.com/firefly-iii/firefly-iii/issues/9745) (Type mismatch in period overview) reported by @electrofloat - [Issue 9747](https://github.com/firefly-iii/firefly-iii/issues/9747) (Data entry issues with exchange rates) reported by @Azmodeszer - [Issue 9751](https://github.com/firefly-iii/firefly-iii/issues/9751) (Net worth changes since 6.2 update) reported by @ahmaddxb - [Issue 9762](https://github.com/firefly-iii/firefly-iii/issues/9762) (Piggy bank show: start/target date not displayed) reported by @Simeam +- Various other balance related fixes. ## 6.2.2 - 2025-02-02 diff --git a/resources/lang/en_US/firefly.php b/resources/lang/en_US/firefly.php index beb8537a8b..ced49e5599 100644 --- a/resources/lang/en_US/firefly.php +++ b/resources/lang/en_US/firefly.php @@ -733,7 +733,7 @@ return [ // END 'general_search_error' => 'An error occurred while searching. Please check the log files for more information.', 'search_box' => 'Search', - 'search_box_intro' => 'Welcome to the search function of Firefly III. Enter your search query in the box. Make sure you check out the help file because the search is pretty advanced.', + 'search_box_intro' => 'Welcome to the search function of Firefly III. Enter your search query in the box. Make sure you check out the help file because the search is pretty advanced.', 'search_error' => 'Error while searching', 'search_searching' => 'Searching ...', 'search_results' => 'Search results', From 90bfdc75732ffe132b704938ce6ff11374024647 Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 5 Feb 2025 06:36:51 +0100 Subject: [PATCH 19/24] Fix #9754 --- app/Handlers/Observer/AccountObserver.php | 6 +++++- app/Handlers/Observer/BillObserver.php | 6 +++++- app/Handlers/Observer/BudgetObserver.php | 7 ++++++- app/Handlers/Observer/CategoryObserver.php | 7 ++++++- app/Handlers/Observer/PiggyBankObserver.php | 6 +++++- app/Handlers/Observer/RecurrenceObserver.php | 7 ++++++- app/Handlers/Observer/TagObserver.php | 6 +++++- app/Handlers/Observer/TransactionJournalObserver.php | 7 ++++++- 8 files changed, 44 insertions(+), 8 deletions(-) diff --git a/app/Handlers/Observer/AccountObserver.php b/app/Handlers/Observer/AccountObserver.php index f2e4c05725..1ec19fbbbd 100644 --- a/app/Handlers/Observer/AccountObserver.php +++ b/app/Handlers/Observer/AccountObserver.php @@ -26,6 +26,7 @@ namespace FireflyIII\Handlers\Observer; use FireflyIII\Models\Account; use FireflyIII\Models\PiggyBank; +use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface; use FireflyIII\Support\Facades\Amount; use FireflyIII\Support\Http\Api\ExchangeRateConverter; @@ -73,12 +74,15 @@ class AccountObserver // app('log')->debug('Observe "deleting" of an account.'); $account->accountMeta()->delete(); + $repository = app(AttachmentRepositoryInterface::class); + $repository->setUser($account->user); + /** @var PiggyBank $piggy */ foreach ($account->piggyBanks()->get() as $piggy) { $piggy->accounts()->detach($account); } foreach ($account->attachments()->get() as $attachment) { - $attachment->delete(); + $repository->destroy($attachment); } foreach ($account->transactions()->get() as $transaction) { $transaction->delete(); diff --git a/app/Handlers/Observer/BillObserver.php b/app/Handlers/Observer/BillObserver.php index 792295156b..709d8b25ae 100644 --- a/app/Handlers/Observer/BillObserver.php +++ b/app/Handlers/Observer/BillObserver.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace FireflyIII\Handlers\Observer; use FireflyIII\Models\Bill; +use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; use FireflyIII\Support\Facades\Amount; use FireflyIII\Support\Http\Api\ExchangeRateConverter; use Illuminate\Support\Facades\Log; @@ -41,9 +42,12 @@ class BillObserver public function deleting(Bill $bill): void { + $repository = app(AttachmentRepositoryInterface::class); + $repository->setUser($bill->user); + // app('log')->debug('Observe "deleting" of a bill.'); foreach ($bill->attachments()->get() as $attachment) { - $attachment->delete(); + $repository->destroy($attachment); } $bill->notes()->delete(); } diff --git a/app/Handlers/Observer/BudgetObserver.php b/app/Handlers/Observer/BudgetObserver.php index d13abec746..a0f9e7bc69 100644 --- a/app/Handlers/Observer/BudgetObserver.php +++ b/app/Handlers/Observer/BudgetObserver.php @@ -25,6 +25,7 @@ namespace FireflyIII\Handlers\Observer; use FireflyIII\Models\Budget; use FireflyIII\Models\BudgetLimit; +use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; /** * Class BudgetObserver @@ -34,8 +35,12 @@ class BudgetObserver public function deleting(Budget $budget): void { app('log')->debug('Observe "deleting" of a budget.'); + + $repository = app(AttachmentRepositoryInterface::class); + $repository->setUser($budget->user); + foreach ($budget->attachments()->get() as $attachment) { - $attachment->delete(); + $repository->destroy($attachment); } $budgetLimits = $budget->budgetlimits()->get(); diff --git a/app/Handlers/Observer/CategoryObserver.php b/app/Handlers/Observer/CategoryObserver.php index 0cc866761a..76decd000d 100644 --- a/app/Handlers/Observer/CategoryObserver.php +++ b/app/Handlers/Observer/CategoryObserver.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace FireflyIII\Handlers\Observer; use FireflyIII\Models\Category; +use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; /** * Class CategoryObserver @@ -33,8 +34,12 @@ class CategoryObserver public function deleting(Category $category): void { app('log')->debug('Observe "deleting" of a category.'); + + $repository = app(AttachmentRepositoryInterface::class); + $repository->setUser($category->user); + foreach ($category->attachments()->get() as $attachment) { - $attachment->delete(); + $repository->destroy($attachment); } $category->notes()->delete(); } diff --git a/app/Handlers/Observer/PiggyBankObserver.php b/app/Handlers/Observer/PiggyBankObserver.php index e8e55f8f9f..e2a88158b4 100644 --- a/app/Handlers/Observer/PiggyBankObserver.php +++ b/app/Handlers/Observer/PiggyBankObserver.php @@ -25,6 +25,7 @@ declare(strict_types=1); namespace FireflyIII\Handlers\Observer; use FireflyIII\Models\PiggyBank; +use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; use FireflyIII\Support\Http\Api\ExchangeRateConverter; use Illuminate\Support\Facades\Log; @@ -46,8 +47,11 @@ class PiggyBankObserver { app('log')->debug('Observe "deleting" of a piggy bank.'); + $repository = app(AttachmentRepositoryInterface::class); + $repository->setUser($piggyBank->accounts()->first()->user); + foreach ($piggyBank->attachments()->get() as $attachment) { - $attachment->delete(); + $repository->destroy($attachment); } $piggyBank->piggyBankEvents()->delete(); diff --git a/app/Handlers/Observer/RecurrenceObserver.php b/app/Handlers/Observer/RecurrenceObserver.php index c892315f60..cf6a8f6e97 100644 --- a/app/Handlers/Observer/RecurrenceObserver.php +++ b/app/Handlers/Observer/RecurrenceObserver.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace FireflyIII\Handlers\Observer; use FireflyIII\Models\Recurrence; +use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; /** * Class RecurrenceObserver @@ -33,8 +34,12 @@ class RecurrenceObserver public function deleting(Recurrence $recurrence): void { app('log')->debug('Observe "deleting" of a recurrence.'); + + $repository = app(AttachmentRepositoryInterface::class); + $repository->setUser($recurrence->user); + foreach ($recurrence->attachments()->get() as $attachment) { - $attachment->delete(); + $repository->destroy($attachment); } $recurrence->recurrenceRepetitions()->delete(); diff --git a/app/Handlers/Observer/TagObserver.php b/app/Handlers/Observer/TagObserver.php index 1994a30aa1..4892ce2ccb 100644 --- a/app/Handlers/Observer/TagObserver.php +++ b/app/Handlers/Observer/TagObserver.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace FireflyIII\Handlers\Observer; use FireflyIII\Models\Tag; +use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; /** * Class TagObserver @@ -34,8 +35,11 @@ class TagObserver { app('log')->debug('Observe "deleting" of a tag.'); + $repository = app(AttachmentRepositoryInterface::class); + $repository->setUser($tag->user); + foreach ($tag->attachments()->get() as $attachment) { - $attachment->delete(); + $repository->destroy($attachment); } $tag->locations()->delete(); diff --git a/app/Handlers/Observer/TransactionJournalObserver.php b/app/Handlers/Observer/TransactionJournalObserver.php index 3bb106783e..4b6986b468 100644 --- a/app/Handlers/Observer/TransactionJournalObserver.php +++ b/app/Handlers/Observer/TransactionJournalObserver.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace FireflyIII\Handlers\Observer; use FireflyIII\Models\TransactionJournal; +use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; /** * Class TransactionJournalObserver @@ -34,6 +35,10 @@ class TransactionJournalObserver { app('log')->debug('Observe "deleting" of a transaction journal.'); + $repository = app(AttachmentRepositoryInterface::class); + $repository->setUser($transactionJournal->user); + + // to make sure the listener doesn't get back to use and loop TransactionJournal::withoutEvents(static function () use ($transactionJournal): void { foreach ($transactionJournal->transactions()->get() as $transaction) { @@ -41,7 +46,7 @@ class TransactionJournalObserver } }); foreach ($transactionJournal->attachments()->get() as $attachment) { - $attachment->delete(); + $repository->destroy($attachment); } $transactionJournal->locations()->delete(); $transactionJournal->sourceJournalLinks()->delete(); From 458734029345581c297a55e9856ab530e29a9b91 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 5 Feb 2025 06:41:08 +0100 Subject: [PATCH 20/24] Auto commit for release 'develop' on 2025-02-05 --- app/Handlers/Observer/BudgetObserver.php | 2 +- .../Controllers/Chart/AccountController.php | 2 +- .../Http/Controllers/ChartGeneration.php | 2 +- app/Support/Steam.php | 141 +++++++++--------- changelog.md | 2 +- config/firefly.php | 2 +- ..._12_19_061003_add_native_amount_column.php | 2 +- package-lock.json | 12 +- 8 files changed, 83 insertions(+), 82 deletions(-) diff --git a/app/Handlers/Observer/BudgetObserver.php b/app/Handlers/Observer/BudgetObserver.php index a0f9e7bc69..01fc2a937e 100644 --- a/app/Handlers/Observer/BudgetObserver.php +++ b/app/Handlers/Observer/BudgetObserver.php @@ -36,7 +36,7 @@ class BudgetObserver { app('log')->debug('Observe "deleting" of a budget.'); - $repository = app(AttachmentRepositoryInterface::class); + $repository = app(AttachmentRepositoryInterface::class); $repository->setUser($budget->user); foreach ($budget->attachments()->get() as $attachment) { diff --git a/app/Http/Controllers/Chart/AccountController.php b/app/Http/Controllers/Chart/AccountController.php index cf086f6ec2..557f3002a2 100644 --- a/app/Http/Controllers/Chart/AccountController.php +++ b/app/Http/Controllers/Chart/AccountController.php @@ -427,7 +427,7 @@ class AccountController extends Controller $cache->addProperty($this->convertToNative); $cache->addProperty($account->id); if ($cache->has()) { - return response()->json($cache->get()); + return response()->json($cache->get()); } // collect and filter balances for the entire period. diff --git a/app/Support/Http/Controllers/ChartGeneration.php b/app/Support/Http/Controllers/ChartGeneration.php index bc95cd50a7..93c2a238eb 100644 --- a/app/Support/Http/Controllers/ChartGeneration.php +++ b/app/Support/Http/Controllers/ChartGeneration.php @@ -55,7 +55,7 @@ trait ChartGeneration $cache->addProperty($accounts); $cache->addProperty($convertToNative); if ($cache->has()) { - return $cache->get(); + return $cache->get(); } app('log')->debug('Regenerate chart.account.account-balance-chart from scratch.'); $locale = app('steam')->getLocale(); diff --git a/app/Support/Steam.php b/app/Support/Steam.php index 0b8ec55c10..2d4cc21547 100644 --- a/app/Support/Steam.php +++ b/app/Support/Steam.php @@ -41,8 +41,8 @@ class Steam { public function getAccountCurrency(Account $account): ?TransactionCurrency { - $type = $account->accountType->type; - $list = config('firefly.valid_currency_account_types'); + $type = $account->accountType->type; + $list = config('firefly.valid_currency_account_types'); // return null if not in this list. if (!in_array($type, $list, true)) { @@ -64,22 +64,22 @@ class Steam Log::debug(sprintf('finalAccountBalanceInRange(#%d, %s, %s)', $account->id, $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s'))); // set up cache - $cache = new CacheProperties(); + $cache = new CacheProperties(); $cache->addProperty($account->id); $cache->addProperty('final-balance-in-range'); $cache->addProperty($start); $cache->addProperty($end); if ($cache->has()) { - return $cache->get(); + return $cache->get(); } - $balances = []; - $formatted = $start->format('Y-m-d'); - $startBalance = $this->finalAccountBalance($account, $start); - $nativeCurrency = app('amount')->getNativeCurrencyByUserGroup($account->user->userGroup); - $accountCurrency = $this->getAccountCurrency($account); - $hasCurrency = null !== $accountCurrency; - $currency = $accountCurrency ?? $nativeCurrency; + $balances = []; + $formatted = $start->format('Y-m-d'); + $startBalance = $this->finalAccountBalance($account, $start); + $nativeCurrency = app('amount')->getNativeCurrencyByUserGroup($account->user->userGroup); + $accountCurrency = $this->getAccountCurrency($account); + $hasCurrency = null !== $accountCurrency; + $currency = $accountCurrency ?? $nativeCurrency; Log::debug(sprintf('Currency is %s', $currency->code)); // set start balances: @@ -91,7 +91,7 @@ class Steam Log::debug(sprintf('Also set start balance in %s', $nativeCurrency->code)); $startBalance[$nativeCurrency->code] ??= '0'; } - $currencies = [ + $currencies = [ $currency->id => $currency, $nativeCurrency->id => $nativeCurrency, ]; @@ -100,42 +100,43 @@ class Steam Log::debug('Final start balance: ', $startBalance); // sums up the balance changes per day. - $set = $account->transactions() - ->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') - ->where('transaction_journals.date', '>=', $start->format('Y-m-d H:i:s')) - ->where('transaction_journals.date', '<=', $end->format('Y-m-d H:i:s')) - ->groupBy('transaction_journals.date') - ->groupBy('transactions.transaction_currency_id') - ->orderBy('transaction_journals.date', 'ASC') - ->whereNull('transaction_journals.deleted_at') - ->get( - [ // @phpstan-ignore-line - 'transaction_journals.date', - 'transactions.transaction_currency_id', - DB::raw('SUM(transactions.amount) AS sum_of_day'), - ] - ); + $set = $account->transactions() + ->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id') + ->where('transaction_journals.date', '>=', $start->format('Y-m-d H:i:s')) + ->where('transaction_journals.date', '<=', $end->format('Y-m-d H:i:s')) + ->groupBy('transaction_journals.date') + ->groupBy('transactions.transaction_currency_id') + ->orderBy('transaction_journals.date', 'ASC') + ->whereNull('transaction_journals.deleted_at') + ->get( + [ // @phpstan-ignore-line + 'transaction_journals.date', + 'transactions.transaction_currency_id', + DB::raw('SUM(transactions.amount) AS sum_of_day'), + ] + ) + ; - $currentBalance = $startBalance; - $converter = new ExchangeRateConverter(); + $currentBalance = $startBalance; + $converter = new ExchangeRateConverter(); /** @var Transaction $entry */ foreach ($set as $entry) { // get date object - $carbon = new Carbon($entry->date, $entry->date_tz); + $carbon = new Carbon($entry->date, $entry->date_tz); // make sure sum is a string: - $sumOfDay = (string) (null === $entry->sum_of_day ? '0' : $entry->sum_of_day); + $sumOfDay = (string) (null === $entry->sum_of_day ? '0' : $entry->sum_of_day); // find currency of this entry, does not have to exist. $currencies[$entry->transaction_currency_id] ??= TransactionCurrency::find($entry->transaction_currency_id); // make sure this $entry has its own $entryCurrency /** @var TransactionCurrency $entryCurrency */ - $entryCurrency = $currencies[$entry->transaction_currency_id]; + $entryCurrency = $currencies[$entry->transaction_currency_id]; Log::debug(sprintf('Processing transaction(s) on date %s', $carbon->format('Y-m-d H:i:s'))); - $currentBalance[$entryCurrency->code] ??= '0'; + $currentBalance[$entryCurrency->code] ??= '0'; $currentBalance[$entryCurrency->code] = bcadd($sumOfDay, $currentBalance[$entryCurrency->code]); // if not convert to native, add the amount to "balance", do nothing else. @@ -148,7 +149,7 @@ class Steam $currentBalance['native_balance'] = bcadd($currentBalance['native_balance'], $nativeSumOfDay); } // add final $currentBalance array to the big one. - $balances[$carbon->format('Y-m-d')] = $currentBalance; + $balances[$carbon->format('Y-m-d')] = $currentBalance; Log::debug('Updated entry', $currentBalance); } $cache->store($balances); @@ -186,10 +187,10 @@ class Steam // Log::debug(sprintf('Trying bcround("%s",%d)', $number, $precision)); if (str_contains($number, '.')) { if ('-' !== $number[0]) { - return bcadd($number, '0.' . str_repeat('0', $precision) . '5', $precision); + return bcadd($number, '0.'.str_repeat('0', $precision).'5', $precision); } - return bcsub($number, '0.' . str_repeat('0', $precision) . '5', $precision); + return bcsub($number, '0.'.str_repeat('0', $precision).'5', $precision); } return $number; @@ -264,64 +265,64 @@ class Steam * "balance": balance in the account's currency OR user's native currency if the account has no currency * --> "native_balance": balance in the user's native balance, with all amounts converted to native. * "EUR": balance in EUR (or whatever currencies the account has balance in) - * */ public function finalAccountBalance(Account $account, Carbon $date): array { - $cache = new CacheProperties(); + $cache = new CacheProperties(); $cache->addProperty($account->id); $cache->addProperty($date); if ($cache->has()) { - return $cache->get(); + return $cache->get(); } Log::debug(sprintf('Now in finalAccountBalance(#%d, "%s", "%s")', $account->id, $account->name, $date->format('Y-m-d H:i:s'))); - $native = Amount::getNativeCurrencyByUserGroup($account->user->userGroup); - $convertToNative = Amount::convertToNative($account->user); - $accountCurrency = $this->getAccountCurrency($account); - $hasCurrency = null !== $accountCurrency; - $currency = $hasCurrency ? $accountCurrency : $native; - $return = [ + $native = Amount::getNativeCurrencyByUserGroup($account->user->userGroup); + $convertToNative = Amount::convertToNative($account->user); + $accountCurrency = $this->getAccountCurrency($account); + $hasCurrency = null !== $accountCurrency; + $currency = $hasCurrency ? $accountCurrency : $native; + $return = [ 'native_balance' => '0', 'balance' => '0', // this key is overwritten right away, but I must remember it is always created. ]; // balance(s) in all currencies. - $array = $account->transactions() - ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->leftJoin('transaction_currencies', 'transaction_currencies.id', '=', 'transactions.transaction_currency_id') - ->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s')) - ->get(['transaction_currencies.code', 'transactions.amount'])->toArray(); - $others = $this->groupAndSumTransactions($array, 'code', 'amount'); - //Log::debug('All balances are (joined)', $others); + $array = $account->transactions() + ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') + ->leftJoin('transaction_currencies', 'transaction_currencies.id', '=', 'transactions.transaction_currency_id') + ->where('transaction_journals.date', '<=', $date->format('Y-m-d H:i:s')) + ->get(['transaction_currencies.code', 'transactions.amount'])->toArray() + ; + $others = $this->groupAndSumTransactions($array, 'code', 'amount'); + // Log::debug('All balances are (joined)', $others); // if there is no request to convert, take this as "balance" and "native_balance". $return['balance'] = $others[$currency->code] ?? '0'; if (!$convertToNative) { unset($return['native_balance']); - //Log::debug(sprintf('Set balance to %s, unset native_balance', $return['balance'])); + // Log::debug(sprintf('Set balance to %s, unset native_balance', $return['balance'])); } // if there is a request to convert, convert to "native_balance" and use "balance" for whichever amount is in the native currency. if ($convertToNative) { $return['native_balance'] = $this->convertAllBalances($others, $native, $date); // todo sum all and convert. - //Log::debug(sprintf('Set native_balance to %s', $return['native_balance'])); + // Log::debug(sprintf('Set native_balance to %s', $return['native_balance'])); } // either way, the balance is always combined with the virtual balance: - $virtualBalance = (string) ('' === (string) $account->virtual_balance ? '0' : $account->virtual_balance); + $virtualBalance = (string) ('' === (string) $account->virtual_balance ? '0' : $account->virtual_balance); if ($convertToNative) { // the native balance is combined with a converted virtual_balance: $converter = new ExchangeRateConverter(); $nativeVirtualBalance = $converter->convert($currency, $native, $date, $virtualBalance); $return['native_balance'] = bcadd($nativeVirtualBalance, $return['native_balance']); - //Log::debug(sprintf('Native virtual balance makes the native total %s', $return['native_balance'])); + // Log::debug(sprintf('Native virtual balance makes the native total %s', $return['native_balance'])); } if (!$convertToNative) { // if not, also increase the balance + native balance for consistency. $return['balance'] = bcadd($return['balance'], $virtualBalance); - //Log::debug(sprintf('Virtual balance makes the (native) total %s', $return['balance'])); + // Log::debug(sprintf('Virtual balance makes the (native) total %s', $return['balance'])); } - $final = array_merge($return, $others); + $final = array_merge($return, $others); Log::debug('Final balance is', $final); $cache->store($final); @@ -374,7 +375,7 @@ class Steam } if (null !== $currency) { - Log::debug(sprintf('Unset [%s] + [%s] balance for account #%d', $defaultCurrency->code, $currency->code, $account->id)); + Log::debug(sprintf('Unset [%s] + [%s] balance for account #%d', $defaultCurrency->code, $currency->code, $account->id)); unset($set[$defaultCurrency->code], $set[$currency->code]); } } @@ -428,15 +429,15 @@ class Steam { $list = []; - $set = auth()->user()->transactions() - ->whereIn('transactions.account_id', $accounts) - ->groupBy(['transactions.account_id', 'transaction_journals.user_id']) - ->get(['transactions.account_id', \DB::raw('MAX(transaction_journals.date) AS max_date')]) // @phpstan-ignore-line + $set = auth()->user()->transactions() + ->whereIn('transactions.account_id', $accounts) + ->groupBy(['transactions.account_id', 'transaction_journals.user_id']) + ->get(['transactions.account_id', \DB::raw('MAX(transaction_journals.date) AS max_date')]) // @phpstan-ignore-line ; /** @var Transaction $entry */ foreach ($set as $entry) { - $date = new Carbon($entry->max_date, config('app.timezone')); + $date = new Carbon($entry->max_date, config('app.timezone')); $date->setTimezone(config('app.timezone')); $list[(int) $entry->account_id] = $date; } @@ -511,9 +512,9 @@ class Steam public function getSafeUrl(string $unknownUrl, string $safeUrl): string { // Log::debug(sprintf('getSafeUrl(%s, %s)', $unknownUrl, $safeUrl)); - $returnUrl = $safeUrl; - $unknownHost = parse_url($unknownUrl, PHP_URL_HOST); - $safeHost = parse_url($safeUrl, PHP_URL_HOST); + $returnUrl = $safeUrl; + $unknownHost = parse_url($unknownUrl, PHP_URL_HOST); + $safeHost = parse_url($safeUrl, PHP_URL_HOST); if (null !== $unknownHost && $unknownHost === $safeHost) { $returnUrl = $unknownUrl; @@ -550,7 +551,7 @@ class Steam */ public function floatalize(string $value): string { - $value = strtoupper($value); + $value = strtoupper($value); if (!str_contains($value, 'E')) { return $value; } @@ -638,9 +639,9 @@ class Steam if (null === $currency) { continue; } - $current = $converter->convert($currency, $native, $date, $amount); + $current = $converter->convert($currency, $native, $date, $amount); Log::debug(sprintf('Convert %s %s to %s %s', $currency->code, $amount, $native->code, $current)); - $total = bcadd($current, $total); + $total = bcadd($current, $total); } return $total; diff --git a/changelog.md b/changelog.md index 015ea01b31..fefe263a7d 100644 --- a/changelog.md +++ b/changelog.md @@ -7,7 +7,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed -- #9327 +- [Issue 9327](https://github.com/firefly-iii/firefly-iii/issues/9327) (Add Link to Search-Page to the help file) reported by @nottheend - [Issue 9713](https://github.com/firefly-iii/firefly-iii/issues/9713) (Many decimal points in amounts) reported by @memo-567 - [Issue 9736](https://github.com/firefly-iii/firefly-iii/issues/9736) (Wrong `finalAccountBalance` result) reported by @gthbusrr - [Issue 9745](https://github.com/firefly-iii/firefly-iii/issues/9745) (Type mismatch in period overview) reported by @electrofloat diff --git a/config/firefly.php b/config/firefly.php index 499253dbbe..6ccd4bc882 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -81,7 +81,7 @@ return [ 'running_balance_column' => env('USE_RUNNING_BALANCE', false), // see cer.php for exchange rates feature flag. ], - 'version' => 'develop/2025-02-04', + 'version' => 'develop/2025-02-05', 'api_version' => '2.1.0', // field is no longer used. 'db_version' => 25, diff --git a/database/migrations/2024_12_19_061003_add_native_amount_column.php b/database/migrations/2024_12_19_061003_add_native_amount_column.php index 87877bc503..d910a46213 100644 --- a/database/migrations/2024_12_19_061003_add_native_amount_column.php +++ b/database/migrations/2024_12_19_061003_add_native_amount_column.php @@ -52,7 +52,7 @@ return new class () extends Migration { foreach ($fields as $field) { Schema::table($table, static function (Blueprint $tableObject) use ($table, $field): void { // add amount column - if(!Schema::hasColumn($table, $field)) { + if (!Schema::hasColumn($table, $field)) { $tableObject->decimal($field, 32, 12)->nullable(); } }); diff --git a/package-lock.json b/package-lock.json index 5f615fd967..188f535bde 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5663,9 +5663,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.91", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.91.tgz", - "integrity": "sha512-sNSHHyq048PFmZY4S90ax61q+gLCs0X0YmcOII9wG9S2XwbVr+h4VW2wWhnbp/Eys3cCwTxVF292W3qPaxIapQ==", + "version": "1.5.92", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.92.tgz", + "integrity": "sha512-BeHgmNobs05N1HMmMZ7YIuHfYBGlq/UmvlsTgg+fsbFs9xVMj+xJHFg19GN04+9Q+r8Xnh9LXqaYIyEWElnNgQ==", "dev": true, "license": "ISC" }, @@ -8387,9 +8387,9 @@ } }, "node_modules/object-inspect": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", - "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "dev": true, "license": "MIT", "engines": { From fd79f9df444bea443cc7d793b366b357439ab91c Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 5 Feb 2025 06:46:27 +0100 Subject: [PATCH 21/24] Expand changelog, fix migration. --- changelog.md | 2 ++ database/migrations/2024_11_30_075826_multi_piggy.php | 4 +--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/changelog.md b/changelog.md index 015ea01b31..b408ee6975 100644 --- a/changelog.md +++ b/changelog.md @@ -10,9 +10,11 @@ This project adheres to [Semantic Versioning](http://semver.org/). - #9327 - [Issue 9713](https://github.com/firefly-iii/firefly-iii/issues/9713) (Many decimal points in amounts) reported by @memo-567 - [Issue 9736](https://github.com/firefly-iii/firefly-iii/issues/9736) (Wrong `finalAccountBalance` result) reported by @gthbusrr +- #9737 - [Issue 9745](https://github.com/firefly-iii/firefly-iii/issues/9745) (Type mismatch in period overview) reported by @electrofloat - [Issue 9747](https://github.com/firefly-iii/firefly-iii/issues/9747) (Data entry issues with exchange rates) reported by @Azmodeszer - [Issue 9751](https://github.com/firefly-iii/firefly-iii/issues/9751) (Net worth changes since 6.2 update) reported by @ahmaddxb +- #9754 - [Issue 9762](https://github.com/firefly-iii/firefly-iii/issues/9762) (Piggy bank show: start/target date not displayed) reported by @Simeam - Various other balance related fixes. diff --git a/database/migrations/2024_11_30_075826_multi_piggy.php b/database/migrations/2024_11_30_075826_multi_piggy.php index 7a59159f8b..56639a463e 100644 --- a/database/migrations/2024_11_30_075826_multi_piggy.php +++ b/database/migrations/2024_11_30_075826_multi_piggy.php @@ -46,9 +46,7 @@ return new class () extends Migration { } Schema::table('piggy_banks', static function (Blueprint $table): void { // 2. make column nullable. - if (!Schema::hasColumn('piggy_banks', 'account_id')) { - $table->unsignedInteger('account_id')->nullable()->change(); - } + $table->unsignedInteger('account_id')->nullable()->change(); }); Schema::table('piggy_banks', static function (Blueprint $table): void { // 3. add currency From ffa6e6a57191732d1f65a49ca16ecf73f6548149 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 5 Feb 2025 06:50:00 +0100 Subject: [PATCH 22/24] Auto commit for release 'develop' on 2025-02-05 --- changelog.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/changelog.md b/changelog.md index 9ae07aaaa4..2c32caa4a0 100644 --- a/changelog.md +++ b/changelog.md @@ -10,11 +10,11 @@ This project adheres to [Semantic Versioning](http://semver.org/). - [Issue 9327](https://github.com/firefly-iii/firefly-iii/issues/9327) (Add Link to Search-Page to the help file) reported by @nottheend - [Issue 9713](https://github.com/firefly-iii/firefly-iii/issues/9713) (Many decimal points in amounts) reported by @memo-567 - [Issue 9736](https://github.com/firefly-iii/firefly-iii/issues/9736) (Wrong `finalAccountBalance` result) reported by @gthbusrr -- #9737 +- [Discussion 9737](https://github.com/orgs/firefly-iii/discussions/9737) (API returns 0 as current balance) started by @eps90 - [Issue 9745](https://github.com/firefly-iii/firefly-iii/issues/9745) (Type mismatch in period overview) reported by @electrofloat - [Issue 9747](https://github.com/firefly-iii/firefly-iii/issues/9747) (Data entry issues with exchange rates) reported by @Azmodeszer - [Issue 9751](https://github.com/firefly-iii/firefly-iii/issues/9751) (Net worth changes since 6.2 update) reported by @ahmaddxb -- #9754 +- [Issue 9754](https://github.com/firefly-iii/firefly-iii/issues/9754) (Deleting account - Attachments remain) reported by @memo-567 - [Issue 9762](https://github.com/firefly-iii/firefly-iii/issues/9762) (Piggy bank show: start/target date not displayed) reported by @Simeam - Various other balance related fixes. From 60d3572d375639066310607dda3241f36106c672 Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 5 Feb 2025 07:21:31 +0100 Subject: [PATCH 23/24] Expand changelog --- changelog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/changelog.md b/changelog.md index 2c32caa4a0..6360e3f07b 100644 --- a/changelog.md +++ b/changelog.md @@ -5,6 +5,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## 6.2.3 +> ⚠️ _Most pressing issues are fixed. Please open [an issue here](https://github.com/firefly-iii/firefly-iii/issues/new?template=bug.yml) if you run into problems._ + ### Fixed - [Issue 9327](https://github.com/firefly-iii/firefly-iii/issues/9327) (Add Link to Search-Page to the help file) reported by @nottheend From 5701f95e0bc8e9f87b66b93c1d9ae0903e2e0fbc Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 5 Feb 2025 07:22:00 +0100 Subject: [PATCH 24/24] Expand changelog --- changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index 6360e3f07b..669d4d717d 100644 --- a/changelog.md +++ b/changelog.md @@ -3,7 +3,7 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). -## 6.2.3 +## 6.2.3 - 2025-02-05 > ⚠️ _Most pressing issues are fixed. Please open [an issue here](https://github.com/firefly-iii/firefly-iii/issues/new?template=bug.yml) if you run into problems._