| {{ '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._
|