mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-31 10:47:00 +00:00 
			
		
		
		
	Auto commit for release 'develop' on 2025-02-04
This commit is contained in:
		| @@ -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
 | ||||
|   | ||||
| @@ -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; | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user