mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-10-12 23:45:10 +00:00
Various improvements for https://github.com/firefly-iii/firefly-iii/issues/8281
This commit is contained in:
@@ -24,7 +24,6 @@ declare(strict_types=1);
|
||||
namespace FireflyIII\Support;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Exception;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Transaction;
|
||||
@@ -47,7 +46,7 @@ class Steam
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
$repository->setUser($account->user);
|
||||
|
||||
$currencyId = (int)$repository->getMetaValue($account, 'currency_id');
|
||||
$currencyId = (int) $repository->getMetaValue($account, 'currency_id');
|
||||
$transactions = $account->transactions()
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
|
||||
@@ -76,7 +75,7 @@ class Steam
|
||||
|
||||
/** @var array $transaction */
|
||||
foreach ($transactions as $transaction) {
|
||||
$value = (string)($transaction[$key] ?? '0');
|
||||
$value = (string) ($transaction[$key] ?? '0');
|
||||
$value = '' === $value ? '0' : $value;
|
||||
$sum = bcadd($sum, $value);
|
||||
}
|
||||
@@ -146,18 +145,18 @@ class Steam
|
||||
/** @var Transaction $entry */
|
||||
foreach ($set as $entry) {
|
||||
// normal amount and foreign amount
|
||||
$modified = (string)(null === $entry->modified ? '0' : $entry->modified);
|
||||
$foreignModified = (string)(null === $entry->modified_foreign ? '0' : $entry->modified_foreign);
|
||||
$modified = (string) (null === $entry->modified ? '0' : $entry->modified);
|
||||
$foreignModified = (string) (null === $entry->modified_foreign ? '0' : $entry->modified_foreign);
|
||||
$amount = '0';
|
||||
if ($currencyId === (int)$entry->transaction_currency_id || 0 === $currencyId) {
|
||||
if ($currencyId === (int) $entry->transaction_currency_id || 0 === $currencyId) {
|
||||
// use normal amount:
|
||||
$amount = $modified;
|
||||
}
|
||||
if ($currencyId === (int)$entry->foreign_currency_id) {
|
||||
if ($currencyId === (int) $entry->foreign_currency_id) {
|
||||
// use foreign amount:
|
||||
$amount = $foreignModified;
|
||||
}
|
||||
Log::debug(sprintf('Trying to add %s and %s.', var_export($currentBalance, true), var_export($amount, true)));
|
||||
// Log::debug(sprintf('Trying to add %s and %s.', var_export($currentBalance, true), var_export($amount, true)));
|
||||
$currentBalance = bcadd($currentBalance, $amount);
|
||||
$carbon = new Carbon($entry->date, config('app.timezone'));
|
||||
$date = $carbon->format('Y-m-d');
|
||||
@@ -276,7 +275,7 @@ class Steam
|
||||
}
|
||||
$format = $day->format('Y-m-d');
|
||||
// if the transaction is in the expected currency, change nothing.
|
||||
if ((int)$transaction['transaction_currency_id'] === $native->id) {
|
||||
if ((int) $transaction['transaction_currency_id'] === $native->id) {
|
||||
// change the current balance, set it to today, continue the loop.
|
||||
$currentBalance = bcadd($currentBalance, $transaction['amount']);
|
||||
$balances[$format] = $currentBalance;
|
||||
@@ -285,7 +284,7 @@ class Steam
|
||||
continue;
|
||||
}
|
||||
// if foreign currency is in the expected currency, do nothing:
|
||||
if ((int)$transaction['foreign_currency_id'] === $native->id) {
|
||||
if ((int) $transaction['foreign_currency_id'] === $native->id) {
|
||||
$currentBalance = bcadd($currentBalance, $transaction['foreign_amount']);
|
||||
$balances[$format] = $currentBalance;
|
||||
app('log')->debug(sprintf('%s: transaction in %s (foreign), new balance is %s.', $format, $native->code, $currentBalance));
|
||||
@@ -293,7 +292,7 @@ class Steam
|
||||
continue;
|
||||
}
|
||||
// otherwise, convert 'amount' to the necessary currency:
|
||||
$currencyId = (int)$transaction['transaction_currency_id'];
|
||||
$currencyId = (int) $transaction['transaction_currency_id'];
|
||||
$currency = $currencies[$currencyId] ?? TransactionCurrency::find($currencyId);
|
||||
$currencies[$currencyId] = $currency;
|
||||
|
||||
@@ -315,6 +314,7 @@ class Steam
|
||||
}
|
||||
|
||||
$cache->store($balances);
|
||||
$converter->summarize();
|
||||
|
||||
return $balances;
|
||||
}
|
||||
@@ -327,15 +327,15 @@ class Steam
|
||||
*/
|
||||
public function balanceConverted(Account $account, Carbon $date, TransactionCurrency $native): string
|
||||
{
|
||||
app('log')->debug(sprintf('Now in balanceConverted (%s) for account #%d, converting to %s', $date->format('Y-m-d'), $account->id, $native->code));
|
||||
// abuse chart properties:
|
||||
// app('log')->debug(sprintf('Now in balanceConverted (%s) for account #%d, converting to %s', $date->format('Y-m-d'), $account->id, $native->code));
|
||||
$cache = new CacheProperties();
|
||||
$cache->addProperty($account->id);
|
||||
$cache->addProperty('balance');
|
||||
$cache->addProperty($date);
|
||||
$cache->addProperty($native->id);
|
||||
if ($cache->has()) {
|
||||
return $cache->get();
|
||||
// Log::debug('Cached!');
|
||||
// return $cache->get();
|
||||
}
|
||||
|
||||
/** @var AccountRepositoryInterface $repository */
|
||||
@@ -343,6 +343,7 @@ class Steam
|
||||
$currency = $repository->getAccountCurrency($account);
|
||||
$currency = null === $currency ? app('amount')->getDefaultCurrencyByUserGroup($account->user->userGroup) : $currency;
|
||||
if ($native->id === $currency->id) {
|
||||
// Log::debug('No conversion necessary!');
|
||||
return $this->balance($account, $date);
|
||||
}
|
||||
|
||||
@@ -424,34 +425,43 @@ class Steam
|
||||
// need to convert the others. All sets use the "amount" value as their base (that's easy)
|
||||
// but we need to convert each transaction separately because the date difference may
|
||||
// incur huge currency changes.
|
||||
$start = clone $date;
|
||||
$end = clone $date;
|
||||
$converter = new ExchangeRateConverter();
|
||||
foreach ($new as $set) {
|
||||
foreach ($set as $transaction) {
|
||||
$date = Carbon::createFromFormat('Y-m-d H:i:s', $transaction['date']);
|
||||
if (false === $date) {
|
||||
$date = today(config('app.timezone'));
|
||||
$currentDate = Carbon::createFromFormat('Y-m-d H:i:s', $transaction['date']);
|
||||
if (false === $currentDate) {
|
||||
$currentDate = today(config('app.timezone'));
|
||||
}
|
||||
$rate = $converter->getCurrencyRate($currency, $native, $date);
|
||||
if ($currentDate->lte($start)) {
|
||||
$start = clone $currentDate;
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($currentDate);
|
||||
$converter->prepare($currency, $native, $start, $end);
|
||||
|
||||
foreach ($new as $set) {
|
||||
foreach ($set as $transaction) {
|
||||
$currentDate = Carbon::createFromFormat('Y-m-d H:i:s', $transaction['date']);
|
||||
if (false === $currentDate) {
|
||||
$currentDate = today(config('app.timezone'));
|
||||
}
|
||||
$rate = $converter->getCurrencyRate($currency, $native, $currentDate);
|
||||
$convertedAmount = bcmul($transaction['amount'], $rate);
|
||||
$balance = bcadd($balance, $convertedAmount);
|
||||
// app('log')->debug(sprintf('Date: %s, rate: %s, amount: %s %s, new: %s %s',
|
||||
// $date->format('Y-m-d'),
|
||||
// $rate,
|
||||
// $currency->code,
|
||||
// $transaction['amount'],
|
||||
// $native->code,
|
||||
// $convertedAmount
|
||||
// ));
|
||||
}
|
||||
// app('log')->debug(sprintf('Balance from new set #%d is %f', $index, $balance));
|
||||
}
|
||||
|
||||
// add virtual balance (also needs conversion)
|
||||
$virtual = null === $account->virtual_balance ? '0' : $account->virtual_balance;
|
||||
$virtual = $converter->convert($currency, $native, $account->created_at, $virtual);
|
||||
$balance = bcadd($balance, $virtual);
|
||||
$converter->summarize();
|
||||
|
||||
$cache->store($balance);
|
||||
$converter->summarize();
|
||||
|
||||
return $balance;
|
||||
}
|
||||
@@ -565,11 +575,11 @@ class Steam
|
||||
->groupBy('transactions.transaction_currency_id')
|
||||
;
|
||||
$balances = $query->get(['transactions.transaction_currency_id', \DB::raw('SUM(transactions.amount) as sum_for_currency')]); // @phpstan-ignore-line
|
||||
$return = [];
|
||||
$return = [];
|
||||
|
||||
/** @var \stdClass $entry */
|
||||
foreach ($balances as $entry) {
|
||||
$return[(int)$entry->transaction_currency_id] = (string)$entry->sum_for_currency;
|
||||
$return[(int) $entry->transaction_currency_id] = (string) $entry->sum_for_currency;
|
||||
}
|
||||
$cache->store($return);
|
||||
|
||||
@@ -672,7 +682,7 @@ class Steam
|
||||
throw new FireflyException($e->getMessage(), 0, $e);
|
||||
}
|
||||
|
||||
return (string)$hostName;
|
||||
return (string) $hostName;
|
||||
}
|
||||
|
||||
public function getLastActivities(array $accounts): array
|
||||
@@ -707,7 +717,7 @@ class Steam
|
||||
if ('equal' === $locale) {
|
||||
$locale = $this->getLanguage();
|
||||
}
|
||||
$locale = (string)$locale;
|
||||
$locale = (string) $locale;
|
||||
|
||||
// Check for Windows to replace the locale correctly.
|
||||
if ('WIN' === strtoupper(substr(PHP_OS, 0, 3))) {
|
||||
@@ -808,20 +818,20 @@ class Steam
|
||||
return $value;
|
||||
}
|
||||
|
||||
$number = substr($value, 0, (int)strpos($value, 'E'));
|
||||
$number = substr($value, 0, (int) strpos($value, 'E'));
|
||||
if (str_contains($number, '.')) {
|
||||
$post = strlen(substr($number, (int)strpos($number, '.') + 1));
|
||||
$mantis = substr($value, (int)strpos($value, 'E') + 1);
|
||||
$post = strlen(substr($number, (int) strpos($number, '.') + 1));
|
||||
$mantis = substr($value, (int) strpos($value, 'E') + 1);
|
||||
if ($mantis < 0) {
|
||||
$post += abs((int)$mantis);
|
||||
$post += abs((int) $mantis);
|
||||
}
|
||||
|
||||
// TODO careless float could break financial math.
|
||||
return number_format((float)$value, $post, '.', '');
|
||||
return number_format((float) $value, $post, '.', '');
|
||||
}
|
||||
|
||||
// TODO careless float could break financial math.
|
||||
return number_format((float)$value, 0, '.', '');
|
||||
return number_format((float) $value, 0, '.', '');
|
||||
}
|
||||
|
||||
public function opposite(string $amount = null): ?string
|
||||
@@ -841,24 +851,24 @@ class Steam
|
||||
// has a K in it, remove the K and multiply by 1024.
|
||||
$bytes = bcmul(rtrim($string, 'k'), '1024');
|
||||
|
||||
return (int)$bytes;
|
||||
return (int) $bytes;
|
||||
}
|
||||
|
||||
if (false !== stripos($string, 'm')) {
|
||||
// has a M in it, remove the M and multiply by 1048576.
|
||||
$bytes = bcmul(rtrim($string, 'm'), '1048576');
|
||||
|
||||
return (int)$bytes;
|
||||
return (int) $bytes;
|
||||
}
|
||||
|
||||
if (false !== stripos($string, 'g')) {
|
||||
// has a G in it, remove the G and multiply by (1024)^3.
|
||||
$bytes = bcmul(rtrim($string, 'g'), '1073741824');
|
||||
|
||||
return (int)$bytes;
|
||||
return (int) $bytes;
|
||||
}
|
||||
|
||||
return (int)$string;
|
||||
return (int) $string;
|
||||
}
|
||||
|
||||
public function positive(string $amount): string
|
||||
|
Reference in New Issue
Block a user